Skip to content

Commit

Permalink
net/SocketPair: convenience wrapper for UniqueSocketDescriptor::Creat…
Browse files Browse the repository at this point in the history
…eSocketPair()
  • Loading branch information
MaxKellermann committed Nov 7, 2023
1 parent e95d8e7 commit 763e7d3
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 17 deletions.
39 changes: 39 additions & 0 deletions src/net/SocketPair.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <[email protected]>

#include "SocketPair.hxx"
#include "SocketError.hxx"

static inline std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
_CreateSocketPair(int domain, int type, int protocol)
{
int sv[2];
if (socketpair(domain, type, protocol, sv))
throw MakeSocketError("socketpair() failed");

return {
UniqueSocketDescriptor{sv[0]},
UniqueSocketDescriptor{sv[1]},
};
}

std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateSocketPair(int domain, int type, int protocol)
{
#ifdef SOCK_CLOEXEC
/* implemented since Linux 2.6.27 */
type |= SOCK_CLOEXEC;
#endif

return _CreateSocketPair(domain, type, protocol);
}

std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateSocketPairNonBlock(int domain, int type, int protocol)
{
#ifdef SOCK_NONBLOCK
type |= SOCK_NONBLOCK;
#endif

return CreateSocketPair(domain, type, protocol);
}
62 changes: 62 additions & 0 deletions src/net/SocketPair.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <[email protected]>

#pragma once

#include "UniqueSocketDescriptor.hxx"

#include <utility>

#include <sys/socket.h>

class UniqueSocketDescriptor;

/**
* Wrapper for socketpair().
*
* Throws on error.
*/
std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateSocketPair(int domain, int type, int protocol=0);

/**
* Shortcut for CreateSocketPair(AF_LOCAL, type).
*/
static std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateSocketPair(int type)
{
return CreateSocketPair(AF_LOCAL, type);
}

/**
* Like CreateSocketPair(), but with SOCK_NONBLOCK (if available).
*/
std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateSocketPairNonBlock(int domain, int type, int protocol=0);

/**
* Shortcut for CreateSocketPairNonBlock(AF_LOCAL, type).
*/
static std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateSocketPairNonBlock(int type)
{
return CreateSocketPairNonBlock(AF_LOCAL, type);
}

/**
* Shortcut for CreateSocketPair(SOCK_STREAM).
*/
static inline std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateStreamSocketPair()
{
return CreateSocketPair(SOCK_STREAM);
}

/**
* Shortcut for CreateSocketPairNonBlock(SOCK_STREAM).
*/
static inline std::pair<UniqueSocketDescriptor, UniqueSocketDescriptor>
CreateStreamSocketPairNonBlock()
{
return CreateSocketPairNonBlock(SOCK_STREAM);
}
1 change: 1 addition & 0 deletions src/net/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ net_sources = [
'Interface.cxx',
'SocketDescriptor.cxx',
'UniqueSocketDescriptor.cxx',
'SocketPair.cxx',
'SocketConfig.cxx',
'RBindSocket.cxx',
'RConnectSocket.cxx',
Expand Down
9 changes: 3 additions & 6 deletions src/spawn/Client.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Mount.hxx"
#include "ExitListener.hxx"
#include "system/Error.hxx"
#include "net/SocketPair.hxx"
#include "util/PrintException.hxx"

#include <stdexcept>
Expand Down Expand Up @@ -126,11 +127,7 @@ SpawnServerClient::Connect()
{
CheckOrAbort();

UniqueSocketDescriptor local_socket, remote_socket;
if (!UniqueSocketDescriptor::CreateSocketPairNonBlock(AF_LOCAL, SOCK_SEQPACKET, 0,
local_socket,
remote_socket))
throw MakeErrno("socketpair() failed");
auto [local_socket, remote_socket] = CreateSocketPairNonBlock(AF_LOCAL, SOCK_SEQPACKET);

static constexpr SpawnRequestCommand cmd = SpawnRequestCommand::CONNECT;

Expand All @@ -143,7 +140,7 @@ SpawnServerClient::Connect()
std::throw_with_nested(std::runtime_error("Spawn server failed"));
}

return local_socket;
return std::move(local_socket);
}

static void
Expand Down
12 changes: 5 additions & 7 deletions src/spawn/Launch.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "system/Mount.hxx"
#include "system/ProcessName.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "net/SocketPair.hxx"
#include "io/Open.hxx"
#include "io/SmallTextFile.hxx"
#include "io/UniqueFileDescriptor.hxx"
Expand Down Expand Up @@ -307,13 +308,10 @@ LaunchSpawnServer(const SpawnConfig &config, SpawnHook *hook,
UniqueSocketDescriptor
LaunchSpawnServer(const SpawnConfig &config, SpawnHook *hook)
{
UniqueSocketDescriptor s1, s2;
if (!UniqueSocketDescriptor::CreateSocketPairNonBlock(AF_LOCAL, SOCK_SEQPACKET, 0,
s1, s2))
throw MakeErrno("socketpair() failed");
auto [for_client, for_server] = CreateSocketPairNonBlock(SOCK_SEQPACKET);

LaunchSpawnServer(config, hook, std::move(s1),
[&s2](){ s2.Close(); });
LaunchSpawnServer(config, hook, std::move(for_server),
[&]{ for_client.Close(); });

return s2;
return std::move(for_client);
}
6 changes: 2 additions & 4 deletions test/net/TestLog.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "net/log/Parser.hxx"
#include "net/log/Datagram.hxx"
#include "net/SocketError.hxx"
#include "net/SocketPair.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "http/Method.hxx"
#include "http/Status.hxx"
Expand Down Expand Up @@ -107,10 +108,7 @@ TEST(Log, Serializer)
static auto
SendReceive(const Net::Log::Datagram &src)
{
UniqueSocketDescriptor a, b;
if (!UniqueSocketDescriptor::CreateSocketPair(AF_LOCAL, SOCK_SEQPACKET,
0, a, b))
throw MakeSocketError("Failed to create socket pair");
auto [a, b] = CreateSocketPair(SOCK_SEQPACKET);

Net::Log::Send(a, src);

Expand Down

0 comments on commit 763e7d3

Please sign in to comment.