2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "launchpad-common/client_socket.hh"
22 #include <sys/socket.h>
23 #include <sys/types.h>
27 #include "launchpad-common/log_private.hh"
32 constexpr const int MAX_RETRY_CNT = 2;
36 ClientSocket::ClientSocket() {
37 fd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
40 _E("socket() is failed. errno(%d)", errno);
45 ClientSocket::ClientSocket(int fd) : fd_(fd) {}
47 ClientSocket::~ClientSocket() {
51 void ClientSocket::Close() {
58 void ClientSocket::Connect(const std::string& endpoint) {
59 int flag = fcntl(fd_, F_GETFL, 0);
62 _E("Failed to fcntl(%d, F_GETFL, 0). errno(%d)", fd_, errno);
66 fcntl(fd_, F_SETFL, flag | O_NONBLOCK);
67 struct sockaddr_un sockaddr = { 0, };
68 sockaddr.sun_family = AF_UNIX;
69 snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s",
71 struct sockaddr* sockaddr_ptr = reinterpret_cast<struct sockaddr*>(&sockaddr);
72 socklen_t len = static_cast<socklen_t>(sizeof(sockaddr));
77 ret = connect(fd_, sockaddr_ptr, len);
86 fcntl(fd_, F_SETFL, flag);
88 _E("connect() is failed. errno(%d)", -ret);
93 int ClientSocket::Send(const void* buf, size_t size) {
94 const unsigned char* buffer = static_cast<const unsigned char*>(buf);
96 int retry_cnt = MAX_RETRY_CNT;
98 ssize_t bytes = send(fd_, buffer, len, MSG_NOSIGNAL | MSG_DONTWAIT);
100 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
103 _E("send(): fd(%d), errno(%d). sleep and retry ...", fd_, errno);
109 _E("send() is failed. fd(%d), errno(%d)", fd_, errno);
120 int ClientSocket::Receive(void* buf, size_t size) {
122 if (fcntl(fd_, F_GETFL, 0) & O_NONBLOCK)
127 int retry_count = 20;
128 unsigned char* buffer = static_cast<unsigned char*>(buf);
131 ssize_t bytes = recv(fd_, buffer, len, 0);
133 _W("EOF. fd(%d)", fd_);
138 if (errno == EINTR || errno == EAGAIN) {
139 if (is_blocking && errno == EAGAIN) {
140 _E("Timed out. fd(%d)", fd_);
144 if (retry_count > 0) {
151 _E("recv() is failed. fd(%d), errno(%d)", fd_, errno);
163 int ClientSocket::GetReceiveBufferSize() {
165 socklen_t len = sizeof(int);
166 int ret = getsockopt(fd_, SOL_SOCKET, SO_RCVBUF,
167 reinterpret_cast<void*>(&value), &len);
170 _E("getsockopt() is failed. errno(%d)", errno);
177 int ClientSocket::GetSendBufferSize() {
179 socklen_t len = sizeof(int);
180 int ret = getsockopt(fd_, SOL_SOCKET, SO_SNDBUF,
181 reinterpret_cast<void*>(&value), &len);
184 _E("getsockopt() is failed. errno(%d)", errno);
191 int ClientSocket::GetReceiveTimeout() {
192 struct timeval timeout = { 0, };
193 socklen_t len = static_cast<socklen_t>(sizeof(struct timeval));
194 int ret = getsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO,
195 reinterpret_cast<void*>(&timeout), &len);
198 _E("getsockopt() is failed. errno(%d)", errno);
202 int value = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
206 void ClientSocket::SetReceiveBufferSize(int size) {
207 socklen_t len = sizeof(size);
208 int ret = setsockopt(fd_, SOL_SOCKET, SO_RCVBUF, &size, len);
211 _E("setsockopt() is failed. errno(%d)", errno);
216 void ClientSocket::SetSendBufferSize(int size) {
217 socklen_t len = sizeof(size);
218 int ret = setsockopt(fd_, SOL_SOCKET, SO_SNDBUF, &size, len);
221 _E("setsockopt() is failed. errno(%d)", errno);
226 void ClientSocket::SetReceiveTimeout(int timeout) {
227 if (timeout == INT_MAX)
234 _E("Invalid parameter");
238 struct timeval tv = {
239 .tv_sec = static_cast<time_t>(timeout / 1000),
240 .tv_usec = static_cast<suseconds_t>((timeout % 1000) * 1000)
242 socklen_t len = static_cast<socklen_t>(sizeof(struct timeval));
243 int ret = setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, &tv, len);
246 _E("setsockopt() is failed. errno(%d)", errno);
251 bool ClientSocket::IsClosed() const {
255 int ClientSocket::GetFd() const {
259 int ClientSocket::RemoveFd() {
265 } // namespace launchpad