mirror of
https://github.com/zeromq/libzmq.git
synced 2025-11-06 21:56:25 +01:00
Avoid race condition with accept4 where available
Linux provides accept4(2) which will return a socket with FD_CLOEXEC set when called with the SOCK_CLOEXEC flag. So call this when available and fall back to fcntl(..., FD_CLOEXEC) if not.
This commit is contained in:
@@ -390,7 +390,11 @@ zmq::fd_t zmq::ipc_listener_t::accept ()
|
|||||||
// The situation where connection cannot be accepted due to insufficient
|
// The situation where connection cannot be accepted due to insufficient
|
||||||
// resources is considered valid and treated by ignoring the connection.
|
// resources is considered valid and treated by ignoring the connection.
|
||||||
zmq_assert (s != retired_fd);
|
zmq_assert (s != retired_fd);
|
||||||
|
#if defined ZMQ_HAVE_SOCK_CLOEXEC
|
||||||
|
fd_t sock = ::accept4 (s, (struct sockaddr *) &ss, &ss_len, SOCK_CLOEXEC);
|
||||||
|
#else
|
||||||
fd_t sock = ::accept (s, NULL, NULL);
|
fd_t sock = ::accept (s, NULL, NULL);
|
||||||
|
#endif
|
||||||
if (sock == -1) {
|
if (sock == -1) {
|
||||||
errno_assert (errno == EAGAIN || errno == EWOULDBLOCK ||
|
errno_assert (errno == EAGAIN || errno == EWOULDBLOCK ||
|
||||||
errno == EINTR || errno == ECONNABORTED || errno == EPROTO ||
|
errno == EINTR || errno == ECONNABORTED || errno == EPROTO ||
|
||||||
@@ -398,9 +402,9 @@ zmq::fd_t zmq::ipc_listener_t::accept ()
|
|||||||
return retired_fd;
|
return retired_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined ZMQ_HAVE_SOCK_CLOEXEC && defined FD_CLOEXEC
|
||||||
// Race condition can cause socket not to be closed (if fork happens
|
// Race condition can cause socket not to be closed (if fork happens
|
||||||
// between accept and this point).
|
// between accept and this point).
|
||||||
#ifdef FD_CLOEXEC
|
|
||||||
int rc = fcntl (sock, F_SETFD, FD_CLOEXEC);
|
int rc = fcntl (sock, F_SETFD, FD_CLOEXEC);
|
||||||
errno_assert (rc != -1);
|
errno_assert (rc != -1);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -273,7 +273,11 @@ zmq::fd_t zmq::tcp_listener_t::accept ()
|
|||||||
#else
|
#else
|
||||||
socklen_t ss_len = sizeof (ss);
|
socklen_t ss_len = sizeof (ss);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined ZMQ_HAVE_SOCK_CLOEXEC
|
||||||
|
fd_t sock = ::accept4 (s, (struct sockaddr *) &ss, &ss_len, SOCK_CLOEXEC);
|
||||||
|
#else
|
||||||
fd_t sock = ::accept (s, (struct sockaddr *) &ss, &ss_len);
|
fd_t sock = ::accept (s, (struct sockaddr *) &ss, &ss_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ZMQ_HAVE_WINDOWS
|
#ifdef ZMQ_HAVE_WINDOWS
|
||||||
if (sock == INVALID_SOCKET) {
|
if (sock == INVALID_SOCKET) {
|
||||||
@@ -299,9 +303,9 @@ zmq::fd_t zmq::tcp_listener_t::accept ()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined ZMQ_HAVE_SOCK_CLOEXEC && defined FD_CLOEXEC
|
||||||
// Race condition can cause socket not to be closed (if fork happens
|
// Race condition can cause socket not to be closed (if fork happens
|
||||||
// between accept and this point).
|
// between accept and this point).
|
||||||
#ifdef FD_CLOEXEC
|
|
||||||
int rc = fcntl (sock, F_SETFD, FD_CLOEXEC);
|
int rc = fcntl (sock, F_SETFD, FD_CLOEXEC);
|
||||||
errno_assert (rc != -1);
|
errno_assert (rc != -1);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user