/* ================================================== */
+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
set_socket_options(int sock_fd, int flags)
{
/* ================================================== */
+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
get_recv_flags(int flags)
{
/* ================================================== */
+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
SCK_SetIntOption(int sock_fd, int level, int name, int value)
{
int flags);
extern int SCK_OpenUnixStreamSocket(const char *remote_addr, const char *local_addr,
int flags);
+extern int SCK_OpenUnixSocketPair(int flags, int *other_fd);
/* Set and get a socket option of int size */
extern int SCK_SetIntOption(int sock_fd, int level, int name, int value);