From: Hwankyu Jhun Date: Thu, 9 Mar 2023 05:03:33 +0000 (+0000) Subject: Add liblaunchpad-common library for launchpad daemons X-Git-Tag: accepted/tizen/unified/20230325.044622~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F44%2F289444%2F9;p=platform%2Fcore%2Fappfw%2Flaunchpad.git Add liblaunchpad-common library for launchpad daemons The liblaunchpad-common library is added for launchpad daemons. Change-Id: I4cc7d88a3709184a6cfd3908160d23c044341648 Signed-off-by: Hwankyu Jhun --- diff --git a/CMakeLists.txt b/CMakeLists.txt index fb3253d..cccc039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") ## 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") diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 13dcb12..116fdc0 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -179,11 +179,15 @@ ln -sf ../launchpad-process-pool.service %{buildroot}%{_unitdir_user}/basic.targ %{_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 diff --git a/src/launchpad-process-pool/CMakeLists.txt b/src/launchpad-process-pool/CMakeLists.txt index e619fe3..7440026 100644 --- a/src/launchpad-process-pool/CMakeLists.txt +++ b/src/launchpad-process-pool/CMakeLists.txt @@ -42,7 +42,8 @@ APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_PROCESS_POOL} PUBLIC 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) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 3daf3df..25baf15 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,2 +1,3 @@ ADD_SUBDIRECTORY(launchpad) +ADD_SUBDIRECTORY(launchpad-common) ADD_SUBDIRECTORY(launchpad-hydra) diff --git a/src/lib/launchpad-common/CMakeLists.txt b/src/lib/launchpad-common/CMakeLists.txt new file mode 100644 index 0000000..35449e3 --- /dev/null +++ b/src/lib/launchpad-common/CMakeLists.txt @@ -0,0 +1,35 @@ +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) diff --git a/src/lib/launchpad-common/client_socket.cc b/src/lib/launchpad-common/client_socket.cc new file mode 100644 index 0000000..849f4cf --- /dev/null +++ b/src/lib/launchpad-common/client_socket.cc @@ -0,0 +1,265 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#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(&sockaddr); + socklen_t len = static_cast(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(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(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(&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(&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(sizeof(struct timeval)); + int ret = getsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&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(timeout / 1000), + .tv_usec = static_cast((timeout % 1000) * 1000) + }; + socklen_t len = static_cast(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 diff --git a/src/lib/launchpad-common/client_socket.hh b/src/lib/launchpad-common/client_socket.hh new file mode 100644 index 0000000..ebb73a2 --- /dev/null +++ b/src/lib/launchpad-common/client_socket.hh @@ -0,0 +1,57 @@ +/* + * 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 + +#include + +#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_ diff --git a/src/lib/launchpad-common/exception.cc b/src/lib/launchpad-common/exception.cc new file mode 100644 index 0000000..c909499 --- /dev/null +++ b/src/lib/launchpad-common/exception.cc @@ -0,0 +1,37 @@ +/* + * 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 diff --git a/src/lib/launchpad-common/exception.hh b/src/lib/launchpad-common/exception.hh new file mode 100644 index 0000000..9c2a0a6 --- /dev/null +++ b/src/lib/launchpad-common/exception.hh @@ -0,0 +1,45 @@ +/* + * 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 +#include + +#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_ diff --git a/src/lib/launchpad-common/io_channel.cc b/src/lib/launchpad-common/io_channel.cc new file mode 100644 index 0000000..10ddbb9 --- /dev/null +++ b/src/lib/launchpad-common/io_channel.cc @@ -0,0 +1,71 @@ +/* + * 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 + +#include + +#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( + channel, g_io_channel_unref); + + source_id_ = g_io_add_watch(channel, static_cast(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(user_data); + auto* listener = io_channel->listener_; + if (listener != nullptr) + listener->OnIOEventReceived(io_channel->fd_, static_cast(condition)); + + return G_SOURCE_CONTINUE; +} + + +} // namespace launchpad diff --git a/src/lib/launchpad-common/io_channel.hh b/src/lib/launchpad-common/io_channel.hh new file mode 100644 index 0000000..12056a7 --- /dev/null +++ b/src/lib/launchpad-common/io_channel.hh @@ -0,0 +1,67 @@ +/* + * 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 + +#include + +#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_ diff --git a/src/lib/launchpad-common/log_private.hh b/src/lib/launchpad-common/log_private.hh new file mode 100644 index 0000000..47d5a15 --- /dev/null +++ b/src/lib/launchpad-common/log_private.hh @@ -0,0 +1,37 @@ +/* + * 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 + +#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_ diff --git a/src/lib/launchpad-common/pkgconfig/liblaunchpad-common.pc.in b/src/lib/launchpad-common/pkgconfig/liblaunchpad-common.pc.in new file mode 100644 index 0000000..6b5cff3 --- /dev/null +++ b/src/lib/launchpad-common/pkgconfig/liblaunchpad-common.pc.in @@ -0,0 +1,13 @@ +# 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 diff --git a/src/lib/launchpad-common/server_socket.cc b/src/lib/launchpad-common/server_socket.cc new file mode 100644 index 0000000..772c196 --- /dev/null +++ b/src/lib/launchpad-common/server_socket.cc @@ -0,0 +1,155 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#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 ServerSocket::Accept() { + struct sockaddr_un addr = { 0, }; + socklen_t len = static_cast(sizeof(struct sockaddr_un)); + auto* addr_ptr = reinterpret_cast(&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(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(&sockaddr); + socklen_t len = static_cast(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(&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(&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 diff --git a/src/lib/launchpad-common/server_socket.hh b/src/lib/launchpad-common/server_socket.hh new file mode 100644 index 0000000..603d6e7 --- /dev/null +++ b/src/lib/launchpad-common/server_socket.hh @@ -0,0 +1,57 @@ +/* + * 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 +#include + +#include +#include + +#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 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_