mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
LibCore: Add API for taking over an accepted socket from SystemServer
Core::LocalSocket::take_over_accepted_socket_from_system_server() now allows you to construct a Core::LocalSocket for a pre-accepted socket when using SystemServer's new AcceptSocketConnections mode.
This commit is contained in:
parent
457a687050
commit
6bc40b20b8
2 changed files with 38 additions and 0 deletions
|
@ -26,7 +26,9 @@
|
||||||
|
|
||||||
#include <LibCore/LocalSocket.h>
|
#include <LibCore/LocalSocket.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifndef SOCK_NONBLOCK
|
#ifndef SOCK_NONBLOCK
|
||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
|
@ -70,4 +72,38 @@ LocalSocket::~LocalSocket()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<LocalSocket> LocalSocket::take_over_accepted_socket_from_system_server()
|
||||||
|
{
|
||||||
|
constexpr auto socket_takeover = "SOCKET_TAKEOVER";
|
||||||
|
if (!getenv(socket_takeover))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
dbg() << "Taking the accepted socket over from SystemServer";
|
||||||
|
|
||||||
|
// The SystemServer has passed us the socket as fd 3,
|
||||||
|
// so use that instead of creating our own.
|
||||||
|
constexpr int fd = 3;
|
||||||
|
|
||||||
|
// Sanity check: it has to be a socket.
|
||||||
|
struct stat stat;
|
||||||
|
int rc = fstat(fd, &stat);
|
||||||
|
if (rc < 0 || !S_ISSOCK(stat.st_mode)) {
|
||||||
|
if (rc != 0)
|
||||||
|
perror("fstat");
|
||||||
|
dbg() << "ERROR: The fd we got from SystemServer is not a socket";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto socket = LocalSocket::construct(fd);
|
||||||
|
|
||||||
|
// It had to be !CLOEXEC for obvious reasons, but we
|
||||||
|
// don't need it to be !CLOEXEC anymore, so set the
|
||||||
|
// CLOEXEC flag now.
|
||||||
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
|
// We wouldn't want our children to think we're passing
|
||||||
|
// them a socket either, so unset the env variable.
|
||||||
|
unsetenv(socket_takeover);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ class LocalSocket final : public Socket {
|
||||||
public:
|
public:
|
||||||
virtual ~LocalSocket() override;
|
virtual ~LocalSocket() override;
|
||||||
|
|
||||||
|
static RefPtr<LocalSocket> take_over_accepted_socket_from_system_server();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit LocalSocket(Object* parent = nullptr);
|
explicit LocalSocket(Object* parent = nullptr);
|
||||||
LocalSocket(int fd, Object* parent = nullptr);
|
LocalSocket(int fd, Object* parent = nullptr);
|
||||||
|
|
Loading…
Add table
Reference in a new issue