2 * Copyright (c) 2021 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 "client_socket.hh"
21 #include <sys/socket.h>
22 #include <sys/types.h>
26 #include "utils/logging.hh"
28 #include "pkgmgrinfo_debug.h"
32 bool IsDBWriteRequest(pkgmgr_common::ReqType req_type) {
33 if (req_type != pkgmgr_common::ReqType::SET_PKG_INFO &&
34 req_type != pkgmgr_common::ReqType::SET_CERT_INFO &&
35 req_type != pkgmgr_common::ReqType::WRITE_QUERY)
43 namespace pkgmgr_common {
46 ClientSocket::ClientSocket(std::string path)
47 : AbstractSocket(std::move(path)) {}
49 void ClientSocket::SetTimeout(int timeout_msec) {
50 if (timeout_msec == -1)
53 if (timeout_msec < 0) {
54 LOG(ERROR) << "Invalid timeout_msec parameter";
58 struct timeval timeout = {
59 .tv_sec = static_cast<time_t>(timeout_msec / 1000),
60 .tv_usec = static_cast<suseconds_t>((timeout_msec % 1000) * 1000)};
62 if (setsockopt(fd_, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0)
63 LOG(ERROR) << "setsockopt() is failed. fd: " << fd_
64 << ", errno: " << errno;
67 bool ClientSocket::Connect(ReqType req_type) {
71 SetTimeout(IsDBWriteRequest(req_type) ? 60 * 1000 : 30 * 1000);
75 int ret = TryConnection();
78 } else if (ret < -1) {
79 LOG(ERROR) << "Maybe peer not launched or peer dead. path: " << GetPath()
80 << ", fd: " << GetFd();
82 // If requester is root, don't wait
89 LOG(ERROR) << "Failed to connect to socket: " << GetPath()
90 << ", fd: " << GetFd();
93 } while (retry_cnt > 0);
95 return (retry_cnt > 0);
98 int ClientSocket::TryConnection() {
99 int flags = fcntl(fd_, F_GETFL, 0);
101 if (fcntl(fd_, F_SETFL, flags | O_NONBLOCK) != 0) {
102 LOG(ERROR) << "Failed to set flags: " << (flags | O_NONBLOCK) << " on fd: "
103 << fd_ << ", errno: " << errno;
108 connect(fd_, reinterpret_cast<struct sockaddr*>(&addr_), sizeof(addr_));
109 if (fcntl(fd_, F_SETFL, flags) != 0) {
110 LOG(ERROR) << "Failed to set flags: " << flags << " on fd: " << fd_
111 << ", errno: " << errno;
115 if (errno != EAGAIN && errno != EINPROGRESS)
117 } else if (ret == 0) {
124 FD_SET(fd_, &readfds);
125 fd_set writefds = readfds;
126 struct timeval timeout = {0, 100 * 1000};
127 ret = select(fd_ + 1, &readfds, &writefds, NULL, &timeout);
133 if (FD_ISSET(fd_, &readfds) || FD_ISSET(fd_, &writefds)) {
135 socklen_t len = sizeof(error);
136 if (getsockopt(fd_, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
143 } // namespace socket
144 } // namespace pkgmgr_common