socket: add support for opening socket pairs

This commit is contained in:
Miroslav Lichvar 2019-11-18 18:08:47 +01:00
parent 0dba2b9689
commit dfc2f70876
2 changed files with 60 additions and 0 deletions

View file

@ -243,6 +243,30 @@ open_socket(int domain, int type, int flags)
/* ================================================== */ /* ================================================== */
static int
open_socket_pair(int domain, int type, int flags, int *other_fd)
{
int sock_fds[2];
if (socketpair(domain, type | get_open_flags(flags), 0, sock_fds) < 0) {
DEBUG_LOG("Could not open %s socket : %s",
domain_to_string(domain), strerror(errno));
return INVALID_SOCK_FD;
}
if (!set_socket_flags(sock_fds[0], flags) || !set_socket_flags(sock_fds[1], flags)) {
close(sock_fds[0]);
close(sock_fds[1]);
return INVALID_SOCK_FD;
}
*other_fd = sock_fds[1];
return sock_fds[0];
}
/* ================================================== */
static int static int
set_socket_options(int sock_fd, int flags) set_socket_options(int sock_fd, int flags)
{ {
@ -520,6 +544,22 @@ error:
/* ================================================== */ /* ================================================== */
static int
open_unix_socket_pair(int type, int flags, int *other_fd)
{
int sock_fd;
sock_fd = open_socket_pair(AF_UNIX, type, flags, other_fd);
if (sock_fd < 0)
return INVALID_SOCK_FD;
DEBUG_LOG("Opened Unix socket pair fd1=%d fd2=%d", sock_fd, *other_fd);
return sock_fd;
}
/* ================================================== */
static int static int
get_recv_flags(int flags) get_recv_flags(int flags)
{ {
@ -1159,6 +1199,25 @@ SCK_OpenUnixStreamSocket(const char *remote_addr, const char *local_addr, int fl
/* ================================================== */ /* ================================================== */
int
SCK_OpenUnixSocketPair(int flags, int *other_fd)
{
int sock_fd;
/* Prefer SEQPACKET sockets over DGRAM in order to receive a zero-length
message (end of file) when the other end is unexpectedly closed */
if (
#ifdef SOCK_SEQPACKET
(sock_fd = open_unix_socket_pair(SOCK_SEQPACKET, flags, other_fd)) < 0 &&
#endif
(sock_fd = open_unix_socket_pair(SOCK_DGRAM, flags, other_fd)) < 0)
return INVALID_SOCK_FD;
return sock_fd;
}
/* ================================================== */
int int
SCK_SetIntOption(int sock_fd, int level, int name, int value) SCK_SetIntOption(int sock_fd, int level, int name, int value)
{ {

View file

@ -98,6 +98,7 @@ extern int SCK_OpenUnixDatagramSocket(const char *remote_addr, const char *local
int flags); int flags);
extern int SCK_OpenUnixStreamSocket(const char *remote_addr, const char *local_addr, extern int SCK_OpenUnixStreamSocket(const char *remote_addr, const char *local_addr,
int flags); int flags);
extern int SCK_OpenUnixSocketPair(int flags, int *other_fd);
/* Set and get a socket option of int size */ /* Set and get a socket option of int size */
extern int SCK_SetIntOption(int sock_fd, int level, int name, int value); extern int SCK_SetIntOption(int sock_fd, int level, int name, int value);