24 #include <sys/types.h>
25 #include <sys/socket.h>
28 #include <netinet/in.h>
31 #include <sys/socket.h>
33 #include <system_error>
39 signal(SIGPIPE, SIG_IGN);
42 static void initUnixSocketAddr(
const std::string &unixAddr,
struct sockaddr_un &serv_addr_un, socklen_t &addrlen,
bool bind)
44 memset(&serv_addr_un, 0,
sizeof(serv_addr_un));
45 serv_addr_un.sun_family = AF_UNIX;
51 strncpy(serv_addr_un.sun_path + 1, unixAddr.c_str(),
sizeof(serv_addr_un.sun_path) - 1);
53 int len = offsetof(
struct sockaddr_un, sun_path) + unixAddr.size() + 1;
58 strncpy(serv_addr_un.sun_path, unixAddr.c_str(),
sizeof(serv_addr_un.sun_path) - 1);
60 int len = offsetof(
struct sockaddr_un, sun_path) + unixAddr.size();
64 unlink(unixAddr.c_str());
73 struct sockaddr_un serv_addr_un;
77 if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
79 throw std::system_error(
errno, std::generic_category(),
"Socket");
83 fcntl(sockfd, F_SETFD, FD_CLOEXEC);
87 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse)) < 0)
89 throw std::system_error(
errno, std::generic_category(),
"setsockopt");
92 initUnixSocketAddr(unixAddr, serv_addr_un, addrlen,
true);
94 if (bind(sockfd, (
struct sockaddr *)&serv_addr_un, addrlen) < 0)
96 throw std::system_error(
errno, std::generic_category(),
"Bind to " + unixAddr);
100 if (::listen(sockfd, 5) < 0)
102 throw std::system_error(
errno, std::generic_category(),
"Listen to " + unixAddr);
110 struct sockaddr_in serv_socket;
115 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
117 throw std::system_error(
errno, std::generic_category(),
"Socket");
121 memset(&serv_socket, 0,
sizeof(serv_socket));
122 serv_socket.sin_family = AF_INET;
123 serv_socket.sin_addr.s_addr = htonl(INADDR_ANY);
124 serv_socket.sin_port = htons((
unsigned short)port);
125 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse)) < 0)
127 throw std::system_error(
errno, std::generic_category(),
"SO_REUSEADDR");
129 if (bind(sockfd, (
struct sockaddr *)&serv_socket,
sizeof(serv_socket)) < 0)
131 throw std::system_error(
errno, std::generic_category(),
"Bind to " +
std::to_string(port));
135 if (::listen(sockfd, 5) < 0)
137 throw std::system_error(
errno, std::generic_category(),
"Listen to " +
std::to_string(port));
147 int cli_fd = ::accept(
fd, 0, 0);
150 throw std::system_error(
errno, std::generic_category(),
"Accept failed");
157 struct sockaddr_un serv_addr_un;
161 if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
163 throw std::system_error(
errno, std::generic_category(),
"Socket");
166 initUnixSocketAddr(unixAddr, serv_addr_un, addrlen,
false);
168 int ret = ::connect(sockfd, (
struct sockaddr *)&serv_addr_un, addrlen);
178 throw std::system_error(e, std::generic_category(),
"Connect to " + unixAddr);
189 struct cmsghdr * cmsgh;
192 cmsghdrlength = CMSG_SPACE((count *
sizeof(
int)));
194 cmsgh = (
struct cmsghdr*)malloc(cmsghdrlength);
197 cmsgh->cmsg_len = CMSG_LEN(count *
sizeof(
int));
198 cmsgh->cmsg_level = SOL_SOCKET;
199 cmsgh->cmsg_type = SCM_RIGHTS;
200 msgh.msg_control = cmsgh;
201 msgh.msg_controllen = cmsghdrlength;
202 for(
int i = 0; i < count; ++i)
204 ((
int *) CMSG_DATA(CMSG_FIRSTHDR(&msgh)))[i] = fds[i];
207 iov[0].iov_base = buff;
211 msgh.msg_name = NULL;
212 msgh.msg_namelen = 0;
216 int ret = sendmsg(
fd, &msgh, MSG_NOSIGNAL);
220 throw std::system_error(
errno, std::generic_category(),
"Failed to send fds");
224 throw std::runtime_error(
"Channel closed when sending fds");
236 struct cmsghdr cmsgh;
238 char control[CMSG_SPACE(16 *
sizeof(
int))];
243 throw std::runtime_error(
"Cannot pass that amount of fds");
251 msgh.msg_name = NULL;
252 msgh.msg_namelen = 0;
256 msgh.msg_control = control_un.control;
257 msgh.msg_controllen =
sizeof(control_un.control);
261 recvflag = MSG_CMSG_CLOEXEC;
266 int size = recvmsg(
fd, &msgh, recvflag);
269 throw std::system_error(
errno, std::generic_category(),
"Could not receive fds");
272 for (
struct cmsghdr * cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg))
274 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
277 while(cmsg->cmsg_len >= CMSG_LEN((fdCount + 1) *
sizeof(
int)))
281 fprintf(stderr,
"Received fd : %d\n", fdCount);
282 if (fdCount != count)
284 throw std::runtime_error(
"Wrong number of fds received");
286 int * fds = (
int*)CMSG_DATA(cmsg);
287 for(
int i = 0; i < fdCount; ++i)
290 fcntl(fds[i], F_SETFD, FD_CLOEXEC);
298 throw std::runtime_error(
"Did not receive fds");
303 struct sockaddr_in serv_addr;
307 auto hp = gethostbyname(host.c_str());
310 throw std::system_error(h_errno, std::generic_category(),
"Could not resolve " + host);
314 (void)memset((
char *)&serv_addr, 0,
sizeof(serv_addr));
315 serv_addr.sin_family = AF_INET;
316 serv_addr.sin_addr.s_addr = ((
struct in_addr *)(hp->h_addr_list[0]))->s_addr;
317 serv_addr.sin_port = htons(port);
318 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
320 throw std::system_error(
errno, std::generic_category(),
"socket");
324 if (connect(sockfd, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
328 throw std::system_error(
errno, std::generic_category(),
"Connect to " + host);
345 buffer = (
char*)malloc(size);
349 if (getcwd(
buffer, size) !=
nullptr)
353 if ((
errno == ERANGE) && (size < 0x100000))
364 std::string ret = std::string(
buffer) +
"/" + str;
365 fprintf(stderr,
"starting : %s\n", ret.c_str());
std::vector< uint8_t > buffer
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
std::string getTestExePath(const std::string &str)
int unixSocketListen(const std::string &unixAddr)
int tcpSocketListen(int port)
void unixSocketRecvFds(int fd, int count, int *fdsDest)
int unixSocketConnect(const std::string &unixAddr, bool failAllowed)
void unixSocketSendFds(int fd, int count, int *fds)
int tcpSocketConnect(const std::string &host, int port, bool failAllowed)