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:
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user