The liblaunchpad-common library is added for launchpad daemons.
Change-Id: I4cc7d88a3709184a6cfd3908160d23c044341648
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
## Targets
SET(TARGET_APP_DEFINED_LOADER "app-defined-loader")
SET(TARGET_LAUNCHPAD "launchpad")
+SET(TARGET_LAUNCHPAD_COMMON "launchpad-common")
SET(TARGET_LAUNCHPAD_HYDRA "launchpad-hydra")
SET(TARGET_LAUNCHPAD_LOADER "launchpad-loader")
SET(TARGET_LAUNCHPAD_PARSER "launchpad-parser")
%{_prefix}/share/aul/launchpad.conf
%{_sysconfdir}/package-manager/parserlib/liblaunchpad-parser.so
%{_datadir}/parser-plugins/*
+%attr(0644,root,root) %{_libdir}/liblaunchpad-common.so.*
%files devel
%{_includedir}/launchpad/*.h
+%{_includedir}/launchpad-common/*.hh
%{_libdir}/*.so
%{_libdir}/pkgconfig/launchpad.pc
+%attr(0644,root,root) %{_libdir}/liblaunchpad-common.so
+%{_libdir}/pkgconfig/liblaunchpad-common.pc
%files -n launchpad-loader
%manifest launchpad-loader.manifest
VCONF_DEPS
)
-TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_PROCESS_POOL} PUBLIC "-lm -ldl")
+TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_PROCESS_POOL} PUBLIC
+ ${TARGET_LAUNCHPAD_COMMON} "-lm -ldl")
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/packaging/default.debugger.in
${CMAKE_SOURCE_DIR}/packaging/default.debugger @ONLY)
ADD_SUBDIRECTORY(launchpad)
+ADD_SUBDIRECTORY(launchpad-common)
ADD_SUBDIRECTORY(launchpad-hydra)
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ LAUNCHPAD_COMMON_SRCS)
+
+ADD_LIBRARY(${TARGET_LAUNCHPAD_COMMON} SHARED ${LAUNCHPAD_COMMON_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_LAUNCHPAD_COMMON} PROPERTIES
+ SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_LAUNCHPAD_COMMON} PROPERTIES
+ VERSION ${VERSION})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_LAUNCHPAD_COMMON} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../
+)
+
+APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_COMMON} PUBLIC
+ BUNDLE_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_COMMON} PUBLIC "-ldl")
+
+INSTALL(TARGETS ${TARGET_LAUNCHPAD_COMMON} DESTINATION ${LIB_INSTALL_DIR}
+ COMPONENT RuntimeLibraries)
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
+ DESTINATION include/launchpad-common
+ FILES_MATCHING
+ PATTERN "*_private.hh" EXCLUDE
+ PATTERN "*.hh"
+)
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-common.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-common.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-common.pc
+ DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "launchpad-common/client_socket.hh"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "launchpad-common/log_private.hh"
+
+namespace launchpad {
+namespace {
+
+constexpr const int MAX_RETRY_CNT = 2;
+
+} // namespace
+
+ClientSocket::ClientSocket() {
+ fd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (fd_ < 0) {
+ int error = -errno;
+ _E("socket() is failed. errno(%d)", errno);
+ THROW(error);
+ }
+}
+
+ClientSocket::ClientSocket(int fd) : fd_(fd) {}
+
+ClientSocket::~ClientSocket() {
+ Close();
+}
+
+void ClientSocket::Close() {
+ if (fd_ > -1) {
+ close(fd_);
+ fd_ = -1;
+ }
+}
+
+void ClientSocket::Connect(const std::string& endpoint) {
+ int flag = fcntl(fd_, F_GETFL, 0);
+ if (flag == -1) {
+ int ret = -errno;
+ _E("Failed to fcntl(%d, F_GETFL, 0). errno(%d)", fd_, errno);
+ THROW(ret);
+ }
+
+ fcntl(fd_, F_SETFL, flag | O_NONBLOCK);
+ struct sockaddr_un sockaddr = { 0, };
+ sockaddr.sun_family = AF_UNIX;
+ snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s",
+ endpoint.c_str());
+ struct sockaddr* sockaddr_ptr = reinterpret_cast<struct sockaddr*>(&sockaddr);
+ socklen_t len = static_cast<socklen_t>(sizeof(sockaddr));
+
+ int ret;
+ int retry = 2;
+ do {
+ ret = connect(fd_, sockaddr_ptr, len);
+ if (ret == 0)
+ break;
+
+ retry--;
+ ret = -errno;
+ usleep(100 * 1000);
+ } while (retry > 0);
+
+ fcntl(fd_, F_SETFL, flag);
+ if (ret < 0) {
+ _E("connect() is failed. errno(%d)", -ret);
+ THROW(ret);
+ }
+}
+
+int ClientSocket::Send(const void* buf, unsigned int size) {
+ const unsigned char* buffer = static_cast<const unsigned char*>(buf);
+ size_t len = size;
+ int retry_cnt = MAX_RETRY_CNT;
+ while (len) {
+ ssize_t bytes = send(fd_, buffer, len, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (bytes < 0) {
+ if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+ if (retry_cnt > 0) {
+ retry_cnt--;
+ _E("send(): fd(%d), errno(%d). sleep and retry ...", fd_, errno);
+ usleep(10 * 1000);
+ continue;
+ }
+ }
+
+ _E("send() is failed. fd(%d), errno(%d)", fd_, errno);
+ return -ECOMM;
+ }
+
+ len -= bytes;
+ buffer += bytes;
+ }
+
+ return 0;
+}
+
+int ClientSocket::Receive(void* buf, unsigned int size) {
+ bool is_blocking;
+ if (fcntl(fd_, F_GETFL, 0) & O_NONBLOCK)
+ is_blocking = false;
+ else
+ is_blocking = true;
+
+ int retry_count = 20;
+ unsigned char* buffer = static_cast<unsigned char*>(buf);
+ size_t len = size;
+ while (len) {
+ ssize_t bytes = recv(fd_, buffer, len, 0);
+ if (bytes == 0) {
+ _W("EOF. fd(%d)", fd_);
+ return -ECOMM;
+ }
+
+ if (bytes < 0) {
+ if (errno == EINTR || errno == EAGAIN) {
+ if (is_blocking && errno == EAGAIN) {
+ _E("Timed out. fd(%d)", fd_);
+ return -EAGAIN;
+ }
+
+ if (retry_count > 0) {
+ usleep(100 * 1000);
+ retry_count--;
+ continue;
+ }
+ }
+
+ _E("recv() is failed. fd(%d), errno(%d)", fd_, errno);
+ return -ECOMM;
+ }
+
+ len -= bytes;
+ buffer += bytes;
+ }
+
+ return 0;
+}
+
+
+int ClientSocket::GetReceiveBufferSize() {
+ int value;
+ socklen_t len = sizeof(int);
+ int ret = getsockopt(fd_, SOL_SOCKET, SO_RCVBUF,
+ reinterpret_cast<void*>(&value), &len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("getsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+
+ return value;
+}
+
+int ClientSocket::GetSendBufferSize() {
+ int value;
+ socklen_t len = sizeof(int);
+ int ret = getsockopt(fd_, SOL_SOCKET, SO_SNDBUF,
+ reinterpret_cast<void*>(&value), &len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("getsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+
+ return value;
+}
+
+int ClientSocket::GetReceiveTimeout() {
+ struct timeval timeout = { 0, };
+ socklen_t len = static_cast<socklen_t>(sizeof(struct timeval));
+ int ret = getsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO,
+ reinterpret_cast<void*>(&timeout), &len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("getsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+
+ int value = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
+ return value;
+}
+
+void ClientSocket::SetReceiveBufferSize(int size) {
+ socklen_t len = sizeof(size);
+ int ret = setsockopt(fd_, SOL_SOCKET, SO_RCVBUF, &size, len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("setsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+}
+
+void ClientSocket::SetSendBufferSize(int size) {
+ socklen_t len = sizeof(size);
+ int ret = setsockopt(fd_, SOL_SOCKET, SO_SNDBUF, &size, len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("setsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+}
+
+void ClientSocket::SetReceiveTimeout(int timeout) {
+ if (timeout == INT_MAX)
+ return;
+
+ if (timeout == -1)
+ timeout = 5000;
+
+ if (timeout < 0) {
+ _E("Invalid parameter");
+ THROW(-EINVAL);
+ }
+
+ struct timeval tv = {
+ .tv_sec = static_cast<time_t>(timeout / 1000),
+ .tv_usec = static_cast<suseconds_t>((timeout % 1000) * 1000)
+ };
+ socklen_t len = static_cast<socklen_t>(sizeof(struct timeval));
+ int ret = setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, &tv, len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("setsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+}
+
+bool ClientSocket::IsClosed() const {
+ return fd_ < 0;
+}
+
+int ClientSocket::GetFd() const {
+ return fd_;
+}
+
+int ClientSocket::RemoveFd() {
+ int fd = fd_;
+ fd_ = -1;
+ return fd;
+}
+
+} // namespace launchpad
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_LAUNCHPAD_COMMON_CLIENT_SOCKET_HH_
+#define LIB_LAUNCHPAD_COMMON_CLIENT_SOCKET_HH_
+
+#include <string>
+
+#include <exception.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API ClientSocket {
+ public:
+ ClientSocket();
+ explicit ClientSocket(int fd);
+ virtual ~ClientSocket();
+ ClientSocket(const ClientSocket&) = delete;
+ ClientSocket& operator = (const ClientSocket&) = delete;
+
+ void Close();
+ void Connect(const std::string& endpoint);
+ int Send(const void* buf, size_t size);
+ int Receive(void* buf, size_t size);
+ int GetReceiveBufferSize();
+ int GetSendBufferSize();
+ int GetReceiveTimeout();
+ void SetReceiveBufferSize(int size);
+ void SetSendBufferSize(int size);
+ void SetReceiveTimeout(int timeout);
+ bool IsClosed() const;
+ int GetFd() const;
+ int RemoveFd();
+
+ private:
+ int fd_;
+};
+
+} // namespace launchpad
+
+#endif // LIB_LAUNCHPAD_COMMON_CLIENT_SOCKET_HH_
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "launchpad-common/exception.hh"
+
+namespace launchpad {
+
+Exception::Exception(int error_code, std::string file, int line)
+ : error_code_(error_code) {
+ message_ = file.substr(file.find_last_of("/") + 1) + ":" +
+ std::to_string(line) + " code:" + std::to_string(error_code_);
+}
+
+Exception::~Exception() {}
+
+const char* Exception::what(void) const noexcept {
+ return message_.c_str();
+}
+
+int Exception::GetErrorCode() const {
+ return error_code_;
+}
+
+} // namespace launchpad
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_LAUNCHPAD_COMMON_EXCEPTION_HH_
+#define LIB_LAUNCHPAD_COMMON_EXCEPTION_HH_
+
+#include <exception>
+#include <string>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+#define THROW(error) throw launchpad::Exception(error, __FUNCTION__, __LINE__)
+
+namespace launchpad {
+
+class EXPORT_API Exception : public std::exception {
+ public:
+ explicit Exception(int error_code, std::string file, int line);
+ virtual ~Exception();
+
+ virtual const char* what(void) const noexcept;
+ int GetErrorCode() const;
+
+ private:
+ int error_code_;
+ std::string message_;
+};
+
+} // namespace launchpad
+
+#endif // LIB_LAUNCHPAD_COMMON_EXCEPTION_HH_
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "launchpad-common/io_channel.hh"
+
+#include <errno.h>
+
+#include <memory>
+
+#include "launchpad-common/log_private.hh"
+
+namespace launchpad {
+
+IOChannel::IOChannel(int fd, int condition, IOChannel::IEvent* listener)
+ : fd_(fd), listener_(listener) {
+ auto channel = g_io_channel_unix_new(fd_);
+ if (channel == nullptr) {
+ _E("g_io_channel_unix_new() is failed");
+ THROW(-ENOMEM);
+ }
+ auto channel_auto =
+ std::unique_ptr<GIOChannel, decltype(g_io_channel_unref)*>(
+ channel, g_io_channel_unref);
+
+ source_id_ = g_io_add_watch(channel, static_cast<GIOCondition>(condition),
+ IOEventCb, this);
+ if (source_id_ == 0) {
+ _E("g_io_add_watch() is failed");
+ THROW(-ENOMEM);
+ }
+
+ channel_ = channel_auto.release();
+}
+
+IOChannel::~IOChannel() {
+ if (source_id_ != 0)
+ g_source_remove(source_id_);
+
+ if (channel_ != nullptr)
+ g_io_channel_unref(channel_);
+}
+
+void IOChannel::SetCloseOnDestroy(bool do_close) {
+ g_io_channel_set_close_on_unref(channel_, do_close);
+}
+
+gboolean IOChannel::IOEventCb(GIOChannel* channel, GIOCondition condition,
+ gpointer user_data) {
+ auto* io_channel = static_cast<IOChannel*>(user_data);
+ auto* listener = io_channel->listener_;
+ if (listener != nullptr)
+ listener->OnIOEventReceived(io_channel->fd_, static_cast<int>(condition));
+
+ return G_SOURCE_CONTINUE;
+}
+
+
+} // namespace launchpad
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_LAUNCHPAD_COMMON_IO_CHANNEL_HH_
+#define LIB_LAUNCHPAD_COMMON_IO_CHANNEL_HH_
+
+#include <gio/gio.h>
+
+#include <exception.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API IOChannel {
+ public:
+ enum IOCondition {
+ IO_IN = G_IO_IN,
+ IO_OUT = G_IO_OUT,
+ IO_PRI = G_IO_PRI,
+ IO_ERR = G_IO_ERR,
+ IO_HUP = G_IO_HUP,
+ IO_NVAL = G_IO_NVAL,
+ };
+
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void OnIOEventReceived(int fd, int condition);
+ };
+
+ IOChannel(int fd, int condtion, IEvent* listener);
+ virtual ~IOChannel();
+
+ IOChannel(const IOChannel&) = delete;
+ IOChannel& operator = (const IOChannel&) = delete;
+
+ void SetCloseOnDestroy(bool do_close);
+
+ private:
+ static gboolean IOEventCb(GIOChannel* channel, GIOCondition condition,
+ gpointer user_data);
+
+ private:
+ int fd_;
+ IEvent* listener_ = nullptr;
+ GIOChannel* channel_ = nullptr;
+ guint source_id_ = 0;
+};
+
+} // namespace launchpad
+
+#endif // LIB_LAUNCHPAD_COMMON_IO_CHANNEL_HH_
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_LAUNCHPAD_COMMON_LOG_PRIVATE_HH_
+#define LIB_LAUNCHPAD_COMMON_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "LAUNCHPAD_COMMON"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif // LIB_LAUNCHPAD_COMMON_LOG_PRIVATE_HH_
--- /dev/null
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: liblaunchpad-common
+Description: launchpad common library
+Version: @VERSION@
+Requires: bundle dlog
+Libs: -L${libdir} -llaunchpad-common
+Cflags: -I${includedir} -I${includedir}/launchpad-common
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "launchpad-common/server_socket.hh"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "launchpad-common/exception.hh"
+#include "launchpad-common/log_private.hh"
+
+namespace launchpad {
+
+ServerSocket::ServerSocket() {
+ fd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (fd_ < 0) {
+ fd_ = -errno;
+ _E("socket() is failed. errno(%d)", errno);
+ THROW(fd_);
+ }
+}
+
+ServerSocket::ServerSocket(int fd) : fd_(fd) {}
+
+ServerSocket::~ServerSocket() {
+ Close();
+}
+
+std::unique_ptr<ClientSocket> ServerSocket::Accept() {
+ struct sockaddr_un addr = { 0, };
+ socklen_t len = static_cast<socklen_t>(sizeof(struct sockaddr_un));
+ auto* addr_ptr = reinterpret_cast<struct sockaddr*>(&addr);
+ int client_fd = accept(GetFd(), addr_ptr, &len);
+ if (client_fd == -1) {
+ _E("accept() is failed. errno(%d)", errno);
+ return nullptr;
+ }
+
+ return std::unique_ptr<ClientSocket>(new ClientSocket(client_fd));
+}
+
+void ServerSocket::Bind(const std::string& bindpoint) {
+ struct sockaddr_un sockaddr = { 0, };
+ sockaddr.sun_family = AF_UNIX;
+ snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s",
+ bindpoint.c_str());
+ struct sockaddr* sockaddr_ptr = reinterpret_cast<struct sockaddr*>(&sockaddr);
+ socklen_t len = static_cast<socklen_t>(sizeof(sockaddr));
+
+ unlink(bindpoint.c_str());
+ int ret = bind(GetFd(), sockaddr_ptr, len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("bind() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+}
+
+void ServerSocket::Close() {
+ if (fd_ > -1) {
+ close(fd_);
+ fd_ = -1;
+ }
+}
+
+void ServerSocket::Listen(int backlog) {
+ int ret = listen(fd_, backlog);
+ if (ret < 0) {
+ ret = -errno;
+ _E("listen() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+}
+
+int ServerSocket::GetReceiveBufferSize() {
+ int value;
+ socklen_t len = sizeof(int);
+ int ret = getsockopt(fd_, SOL_SOCKET, SO_RCVBUF,
+ reinterpret_cast<void*>(&value), &len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("getsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+
+ return value;
+}
+
+int ServerSocket::GetSendBufferSize() {
+ int value;
+ socklen_t len = sizeof(int);
+ int ret = getsockopt(fd_, SOL_SOCKET, SO_SNDBUF,
+ reinterpret_cast<void*>(&value), &len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("getsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+
+ return value;
+}
+
+void ServerSocket::SetReceiveBufferSize(int size) {
+ socklen_t len = sizeof(size);
+ int ret = setsockopt(fd_, SOL_SOCKET, SO_RCVBUF, &size, len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("setsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+}
+
+void ServerSocket::SetSendBufferSize(int size) {
+ socklen_t len = sizeof(size);
+ int ret = setsockopt(fd_, SOL_SOCKET, SO_SNDBUF, &size, len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("setsockopt() is failed. errno(%d)", errno);
+ THROW(ret);
+ }
+}
+
+bool ServerSocket::IsClosed() const {
+ return fd_ < 0;
+}
+
+int ServerSocket::GetFd() const {
+ return fd_;
+}
+
+int ServerSocket::RemoveFd() {
+ int fd = fd_;
+ fd_ = -1;
+ return fd;
+}
+
+} // namespace launchpad
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_LAUNCHPAD_COMMON_SERVER_SOCKET_HH_
+#define LIB_LAUNCHPAD_COMMON_SERVER_SOCKET_HH_
+
+#include <memory>
+#include <string>
+
+#include <client_socket.hh>
+#include <exception.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API ServerSocket {
+ public:
+ ServerSocket();
+ explicit ServerSocket(int fd);
+ virtual ~ServerSocket();
+ ServerSocket(const ServerSocket&) = delete;
+ ServerSocket& operator = (const ServerSocket&) = delete;
+
+ std::unique_ptr<ClientSocket> Accept();
+ void Bind(const std::string& bindpoint);
+ void Close();
+ void Listen(int backlog);
+ int GetReceiveBufferSize();
+ int GetSendBufferSize();
+ void SetReceiveBufferSize(int size);
+ void SetSendBufferSize(int size);
+ bool IsClosed() const;
+ int GetFd() const;
+ int RemoveFd();
+
+ private:
+ int fd_;
+};
+
+} // namespace launchpad
+
+#endif // LIB_LAUNCHPAD_COMMON_SERVER_SOCKET_HH_