diff --git a/src/base/socket.cc b/src/base/socket.cc index fa61ea4cfc..f0aeb01992 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -81,6 +81,28 @@ ListenSocket::loopbackOnly() bindToLoopback = true; } +// Wrappers to stub out SOCK_CLOEXEC/accept4 availability + +int +ListenSocket::socketCloexec(int domain, int type, int protocol) +{ +#ifdef SOCK_CLOEXEC + type |= SOCK_CLOEXEC; +#endif + return ::socket(domain, type, protocol); +} + +int +ListenSocket::acceptCloexec(int sockfd, struct sockaddr *addr, + socklen_t *addrlen) +{ +#if defined(_GNU_SOURCE) && defined(SOCK_CLOEXEC) + return ::accept4(sockfd, addr, addrlen, SOCK_CLOEXEC); +#else + return ::accept(sockfd, addr, addrlen); +#endif +} + //////////////////////////////////////////////////////////////////////// // // @@ -104,7 +126,7 @@ ListenSocket::listen(int port, bool reuse) // only create socket if not already created by a previous call if (fd == -1) { - fd = ::socket(PF_INET, SOCK_STREAM, 0); + fd = socketCloexec(PF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (fd < 0) panic("Can't create socket:%s !", strerror(errno)); } @@ -150,7 +172,7 @@ ListenSocket::accept(bool nodelay) { struct sockaddr_in sockaddr; socklen_t slen = sizeof (sockaddr); - int sfd = ::accept(fd, (struct sockaddr *)&sockaddr, &slen); + int sfd = acceptCloexec(fd, (struct sockaddr *)&sockaddr, &slen); if (sfd != -1 && nodelay) { int i = 1; if (::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (char *)&i, diff --git a/src/base/socket.hh b/src/base/socket.hh index b9b257c10b..4ed6185152 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -29,6 +29,9 @@ #ifndef __SOCKET_HH__ #define __SOCKET_HH__ +#include +#include + namespace gem5 { @@ -59,6 +62,13 @@ class ListenSocket */ static void cleanup(); + private: + /* Create a socket, adding SOCK_CLOEXEC if available. */ + static int socketCloexec(int domain, int type, int protocol); + /* Accept a connection, adding SOCK_CLOEXEC if available. */ + static int acceptCloexec(int sockfd, struct sockaddr *addr, + socklen_t *addrlen); + public: /**