base: Add SOCK_CLOEXEC when creating/accepting sockets

Prevents any forked process (e.g. diod) from holding on the sockets
if gem5 crashes.

This flag is only supported on Linux, so we stub it out on other
platforms.

Test: ls -l /proc/$DIOD_PID/fd shows a lot less fds.
Change-Id: I6bc195ed3bd638ab28ff7690f43afce030fa28c7
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/48623
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Nicolas Boichat
2021-07-26 18:57:17 +08:00
parent 8b3565d507
commit 63c53e21fe
2 changed files with 34 additions and 2 deletions

View File

@@ -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,

View File

@@ -29,6 +29,9 @@
#ifndef __SOCKET_HH__
#define __SOCKET_HH__
#include <sys/socket.h>
#include <sys/types.h>
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:
/**