2 * Copyright (c) 2018-present 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
19 #include <vist/logger.hpp>
25 #include <sys/socket.h>
35 void set_cloexec(int fd)
37 if (::fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
38 THROW(ErrCode::RuntimeError) << "Failed to set CLOSEXEC.";
41 } // anonymous namespace
43 Socket::Socket(int fd) noexcept : fd(fd)
47 Socket::Socket(const std::string& path)
49 if (path.size() >= sizeof(::sockaddr_un::sun_path))
50 THROW(ErrCode::LogicError) << "Socket path size is wrong.";
52 int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
54 THROW(ErrCode::RuntimeError) << "Failed to create socket.";
59 addr.sun_family = AF_UNIX;
60 ::strncpy(addr.sun_path, path.c_str(), sizeof(sockaddr_un::sun_path) - 1);
61 addr.sun_path[sizeof(sockaddr_un::sun_path) - 1] = '\0';
63 if (addr.sun_path[0] == '@') {
64 addr.sun_path[0] = '\0';
67 if (::unlink(path.c_str()) == -1)
68 WARN(VIST) << "Failed to remove exist socket: " << errno;
71 if (::bind(fd, reinterpret_cast<::sockaddr*>(&addr), sizeof(::sockaddr_un)) == -1) {
73 THROW(ErrCode::RuntimeError) << "Failed to bind.";
76 if (::listen(fd, MAX_BACKLOG_SIZE) == -1) {
78 THROW(ErrCode::RuntimeError) << "Failed to liten.";
83 DEBUG(VIST) << "Socket is created: " << path << ", and is listening.. fd[" << fd << "]";
86 Socket::Socket(Socket&& that) : fd(that.fd)
91 Socket& Socket::operator=(Socket&& that)
102 Socket::~Socket(void)
108 Socket Socket::accept(void) const
111 int fd = ::accept(this->fd, nullptr, nullptr);
113 THROW(ErrCode::RuntimeError) << "Failed to accept: " << errno;
120 Socket Socket::connect(const std::string& path)
122 if (path.size() >= sizeof(::sockaddr_un::sun_path))
123 THROW(ErrCode::LogicError) << "Socket path size is wrong.";
125 int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
127 THROW(ErrCode::RuntimeError) << "Failed to create socket.";
132 addr.sun_family = AF_UNIX;
133 ::strncpy(addr.sun_path, path.c_str(), sizeof(sockaddr_un::sun_path) - 1);
134 addr.sun_path[sizeof(sockaddr_un::sun_path) - 1] = '\0';
136 if (addr.sun_path[0] == '@')
137 addr.sun_path[0] = '\0';
139 DEBUG(VIST) << "Start to connect: " << path;
141 if (::connect(fd, reinterpret_cast<::sockaddr*>(&addr), sizeof(sockaddr_un)) == -1) {
143 ERROR(VIST) << "Failed to connect to: " << path;
144 THROW(ErrCode::RuntimeError) << "Failed to connect to: " << path
145 << ", with: " << errno;
151 int Socket::getFd(void) const noexcept