CARLA
Loading...
Searching...
No Matches
Sockets.h
Go to the documentation of this file.
1// Copyright (c) 2026 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8
9#include <cstdint>
10
11#ifdef _WIN32
12 #include <winsock2.h> ///< socket
13 #include <Ws2tcpip.h>
14#else
15 #include <sys/socket.h> ///< socket
16 #include <netinet/in.h> ///< sockaddr_in
17 #include <arpa/inet.h> ///< getsockname
18 #include <unistd.h> ///< close
19 #include <fcntl.h> ///< fcntl, FD_CLOEXEC
20 #include <dirent.h> ///< opendir, readdir
21 #include <cstdlib> ///< strtol
22#endif
23
24#define SOCK_INVALID_INDEX -1
25
26namespace carla {
27
28 /// Marks a socket file descriptor close-on-exec, so it is not inherited
29 /// by child processes started via fork+exec (e.g. RecastBuilder, launched
30 /// by UCarlaEpisode::LoadNewOpendriveEpisode through
31 /// FPlatformProcess::CreateProc). Without this, a forked child that
32 /// outlives the CARLA process keeps the listen socket bound and the next
33 /// server boot fails in asio's bind(). No-op on Windows, where
34 /// CreateProcess only inherits handles explicitly marked inheritable
35 /// (bInheritHandles), which UE's process-spawning calls already leave off.
36 template <typename NativeHandle>
37 inline void SetSocketCloseOnExec(NativeHandle fd)
38 {
39#ifndef _WIN32
41 {
42 const int flags = fcntl(fd, F_GETFD, 0);
43 if (flags != -1)
44 {
45 fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
46 }
47 }
48#else
49 (void) fd;
50#endif // ifndef _WIN32
51 }
52
53#ifndef _WIN32
54 /// Fallback for listening sockets we have no direct handle to (e.g. the
55 /// vendored rpclib server's acceptor, hidden behind a PIMPL with no
56 /// accessor). Walks this process's open file descriptors and marks
57 /// close-on-exec any socket bound to @a Port, on any address family.
58 /// Linux-only (relies on /proc/self/fd); intentionally not declared on
59 /// Windows.
60 inline void SetCloseOnExecForListeningPort(uint16_t Port)
61 {
62 DIR *FdDir = opendir("/proc/self/fd");
63 if (FdDir == nullptr)
64 {
65 return;
66 }
67 struct dirent *Entry;
68 while ((Entry = readdir(FdDir)) != nullptr)
69 {
70 char *EndPtr = nullptr;
71 const long Fd = std::strtol(Entry->d_name, &EndPtr, 10);
72 if (EndPtr == Entry->d_name || *EndPtr != '\0' || Fd < 0)
73 {
74 continue; // not a plain numeric fd entry (".", "..")
75 }
76 struct sockaddr_storage Addr;
77 socklen_t AddrLen = sizeof(Addr);
78 if (getsockname(static_cast<int>(Fd), reinterpret_cast<struct sockaddr *>(&Addr), &AddrLen) != 0)
79 {
80 continue; // not a socket, or we can't query it -- skip.
81 }
82 uint16_t BoundPort = 0;
83 if (Addr.ss_family == AF_INET)
84 {
85 BoundPort = ntohs(reinterpret_cast<struct sockaddr_in *>(&Addr)->sin_port);
86 }
87 else if (Addr.ss_family == AF_INET6)
88 {
89 BoundPort = ntohs(reinterpret_cast<struct sockaddr_in6 *>(&Addr)->sin6_port);
90 }
91 if (BoundPort == Port)
92 {
93 SetSocketCloseOnExec(static_cast<int>(Fd));
94 }
95 }
96 closedir(FdDir);
97 }
98#endif // ifndef _WIN32
99
100} // namespace carla
#define SOCK_INVALID_INDEX
< socket sockaddr_in
Definition Sockets.h:24
This file contains definitions of common data structures used in traffic manager.
void SetSocketCloseOnExec(NativeHandle fd)
Marks a socket file descriptor close-on-exec, so it is not inherited by child processes started via f...
Definition Sockets.h:37
void SetCloseOnExecForListeningPort(uint16_t Port)
Fallback for listening sockets we have no direct handle to (e.g.
Definition Sockets.h:60
static double fd[10]
Definition odrSpiral.cpp:94