Skip to content

Commit 58a9f98

Browse files
authored
Support FD_CLOEXEC for server and client sockets created by SocketServer (#604)
This adds a method setCloseOnExec() to enable setting FD_CLOEXEC on the server and client file descriptors before starting to listen or initiating the WebSocket handshake. This is useful if a process spawns child processes via system() or otherwise, but does not want have WebSocket specific sockets to be inherited to child processes.
1 parent 038e0bf commit 58a9f98

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

ixwebsocket/IXSocket.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,16 @@ namespace ix
318318
#endif
319319
}
320320

321+
bool Socket::setCloseOnExec(socket_t fd)
322+
{
323+
#ifdef _WIN32
324+
// Not implemented on Windows.
325+
return false;
326+
#else
327+
return ::fcntl(fd, F_SETFD, FD_CLOEXEC) == 0;
328+
#endif
329+
}
330+
321331
bool Socket::init(std::string& errorMsg)
322332
{
323333
return _selectInterrupt->init(errorMsg);

ixwebsocket/IXSocket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ namespace ix
7474
static void setErrno(int err);
7575
static bool isWaitNeeded();
7676
static void closeSocket(socket_t fd);
77+
static bool setCloseOnExec(socket_t fd);
7778

7879
static PollResultType poll(bool readyToRead,
7980
int timeoutMs,

ixwebsocket/IXSocketServer.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,20 @@ namespace ix
102102
return std::make_pair(false, ss.str());
103103
}
104104

105+
if (_closeOnExec)
106+
{
107+
if (!Socket::setCloseOnExec(_serverFd))
108+
{
109+
std::stringstream ss;
110+
ss << "SocketServer::listen() error setting close on exec: "
111+
<< strerror(Socket::getErrno());
112+
113+
Socket::closeSocket(_serverFd);
114+
_serverFd = -1;
115+
return std::make_pair(false, ss.str());
116+
}
117+
}
118+
105119
// Make that socket reusable. (allow restarting this server at will)
106120
int enable = 1;
107121
if (setsockopt(_serverFd, SOL_SOCKET, SO_REUSEADDR, (char*) &enable, sizeof(enable)) < 0)
@@ -373,6 +387,22 @@ namespace ix
373387
continue;
374388
}
375389

390+
if (_closeOnExec)
391+
{
392+
if (!Socket::setCloseOnExec(clientFd))
393+
{
394+
int err = Socket::getErrno();
395+
std::stringstream ss;
396+
ss << "SocketServer::run() error setting close on exec: " << err << ", "
397+
<< strerror(err);
398+
logError(ss.str());
399+
400+
Socket::closeSocket(clientFd);
401+
402+
continue;
403+
}
404+
}
405+
376406
// Retrieve connection info, the ip address of the remote peer/client)
377407
std::string remoteIp;
378408
int remotePort;

ixwebsocket/IXSocketServer.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@ namespace ix
7474

7575
void setTLSOptions(const SocketTLSOptions& socketTLSOptions);
7676

77-
int getPort();
77+
// Set FD_CLOEXEC on server and client file descriptors.
78+
void setCloseOnExec()
79+
{
80+
_closeOnExec = true;
81+
}
82+
83+
int getPort();
7884
std::string getHost();
7985
int getBacklog();
8086
std::size_t getMaxConnections();
@@ -93,6 +99,7 @@ namespace ix
9399
int _backlog;
94100
size_t _maxConnections;
95101
int _addressFamily;
102+
bool _closeOnExec = false;
96103

97104
// socket for accepting connections
98105
socket_t _serverFd;

0 commit comments

Comments
 (0)