1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:17:44 +00:00

LibCore: Close accepted sockets on exec() and make them non-blocking

Previously accept() would copy the listener socket's cloexec and
non-blocking flag. With that fixed however TCPServer and LocalServer
now leak file descriptors into child processes and are blocking.
This commit is contained in:
Gunnar Beutner 2021-05-16 12:13:19 +02:00 committed by Andreas Kling
parent 89956cb0d6
commit 07341c3594
3 changed files with 22 additions and 1 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

View file

@ -141,12 +141,22 @@ RefPtr<LocalSocket> LocalServer::accept()
VERIFY(m_listening); VERIFY(m_listening);
sockaddr_un un; sockaddr_un un;
socklen_t un_size = sizeof(un); socklen_t un_size = sizeof(un);
#ifndef AK_OS_MACOS
int accepted_fd = ::accept4(m_fd, (sockaddr*)&un, &un_size, SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
int accepted_fd = ::accept(m_fd, (sockaddr*)&un, &un_size); int accepted_fd = ::accept(m_fd, (sockaddr*)&un, &un_size);
#endif
if (accepted_fd < 0) { if (accepted_fd < 0) {
perror("accept"); perror("accept");
return nullptr; return nullptr;
} }
#ifdef AK_OS_MACOS
int option = 1;
ioctl(m_fd, FIONBIO, &option);
(void)fcntl(accepted_fd, F_SETFD, FD_CLOEXEC);
#endif
return LocalSocket::construct(accepted_fd); return LocalSocket::construct(accepted_fd);
} }

View file

@ -9,12 +9,12 @@
#include <LibCore/Notifier.h> #include <LibCore/Notifier.h>
#include <LibCore/TCPServer.h> #include <LibCore/TCPServer.h>
#include <LibCore/TCPSocket.h> #include <LibCore/TCPSocket.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#ifndef SOCK_NONBLOCK #ifndef SOCK_NONBLOCK
# include <fcntl.h>
# include <sys/ioctl.h> # include <sys/ioctl.h>
#endif #endif
namespace Core { namespace Core {
@ -69,12 +69,23 @@ RefPtr<TCPSocket> TCPServer::accept()
VERIFY(m_listening); VERIFY(m_listening);
sockaddr_in in; sockaddr_in in;
socklen_t in_size = sizeof(in); socklen_t in_size = sizeof(in);
#ifndef AK_OS_MACOS
int accepted_fd = ::accept4(m_fd, (sockaddr*)&in, &in_size, SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
int accepted_fd = ::accept(m_fd, (sockaddr*)&in, &in_size); int accepted_fd = ::accept(m_fd, (sockaddr*)&in, &in_size);
#endif
if (accepted_fd < 0) { if (accepted_fd < 0) {
perror("accept"); perror("accept");
return nullptr; return nullptr;
} }
#ifdef AK_OS_MACOS
int option = 1;
(void)ioctl(m_fd, FIONBIO, &option);
(void)fcntl(accepted_fd, F_SETFD, FD_CLOEXEC);
#endif
return TCPSocket::construct(accepted_fd); return TCPSocket::construct(accepted_fd);
} }