summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Roucariès <roucaries.bastien@gmail.com>2011-03-13 15:06:52 +0100
committerBruno Haible <bruno@clisp.org>2011-03-13 15:35:46 +0100
commitee195dafe32fed7ec44fb0cbf775e1638e668b9b (patch)
tree83e35052752eb7e324e58c83a4c0ce600bab3cad
parent68d757e2cb228590d46961cbf3e9ec7d4460e335 (diff)
downloadgnulib-ee195dafe32fed7ec44fb0cbf775e1638e668b9b.tar.gz
passfd module, part 2.
* modules/passfd: New file. * lib/passfd.h: New file. * lib/passfd.c: New file.
-rw-r--r--ChangeLog7
-rw-r--r--lib/passfd.c147
-rw-r--r--lib/passfd.h21
-rw-r--r--modules/passfd30
4 files changed, 205 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index a3ddcef231..c95ab68426 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-03-07 Bastien Roucariès <roucaries.bastien@gmail.com>
+
+ passfd module, part 2.
+ * modules/passfd: New file.
+ * lib/passfd.h: New file.
+ * lib/passfd.c: New file.
+
2011-03-12 Bruno Haible <bruno@clisp.org>
wcswidth, mbswidth: Avoid integer overflow.
diff --git a/lib/passfd.c b/lib/passfd.c
new file mode 100644
index 0000000000..2f84a13637
--- /dev/null
+++ b/lib/passfd.c
@@ -0,0 +1,147 @@
+/* Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+/* Sendfd sends the file descriptor fd along the socket
+ to a process calling recvfd on the other end.
+
+ return -1 in case of error, 0 on success
+*/
+int
+sendfd (int sock, int fd)
+{
+ char send = 0;
+ struct iovec iov[1];
+ struct msghdr msg;
+
+ /* send at least one char */
+ iov[0].iov_base = &send;
+ iov[0].iov_len = 1;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+
+ {
+#ifdef HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY
+ struct cmsghdr *cmsg;
+ char buf[CMSG_SPACE (sizeof (fd))];
+
+ msg.msg_control = buf;
+ msg.msg_controllen = sizeof (buf);
+ cmsg = CMSG_FIRSTHDR (&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN (sizeof (int));
+ /* Initialize the payload: */
+ memcpy (CMSG_DATA (cmsg), &fd, sizeof (fd));
+ msg.msg_controllen = cmsg->cmsg_len;
+#elif HAVE_UNIXSOCKET_SCM_RIGHTS_BSD43_WAY
+ msg.msg_accrights = &fd;
+ msg.msg_accrightslen = sizeof (fd);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+ }
+
+ if (sendmsg (sock, &msg, 0) != iov[0].iov_len)
+ return -1;
+ return 0;
+}
+
+/* Sendfd sends the file descriptor fd along the socket
+ to a process calling recvfd on the other end.
+
+ return -1 in case of error, fd on success
+*/
+int
+recvfd (int sock)
+{
+ char recv = 0;
+ const int mone = -1;
+ int fd;
+ struct iovec iov[1];
+ struct msghdr msg;
+
+ /* send at least one char */
+ iov[0].iov_base = &recv;
+ iov[0].iov_len = 1;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+
+ {
+#ifdef HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY
+ struct cmsghdr *cmsg;
+ char buf[CMSG_SPACE (sizeof (fd))];
+
+ msg.msg_control = buf;
+ msg.msg_controllen = sizeof (buf);
+ cmsg = CMSG_FIRSTHDR (&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN (sizeof (int));
+ /* Initialize the payload: */
+ memcpy (CMSG_DATA (cmsg), &mone, sizeof (mone));
+ msg.msg_controllen = cmsg->cmsg_len;
+
+ if (recvmsg (sock, &msg, 0) < 0)
+ return -1;
+
+ cmsg = CMSG_FIRSTHDR (&msg);
+ /* be paranoiac */
+ if (cmsg == NULL || cmsg->cmsg_len != CMSG_LEN (sizeof (int))
+ || cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS)
+ {
+ /* fake errno: at end the file is not available */
+ errno = EACCES;
+ return -1;
+ }
+
+ memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd));
+ return fd;
+#elif HAVE_UNIXSOCKET_SCM_RIGHTS_BSD43_WAY
+ msg.msg_accrights = &fd;
+ msg.msg_accrightslen = sizeof (fd);
+ if (recvmsg (sock, &msg, 0) < 0)
+ return -1;
+ return fd;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+ }
+}
diff --git a/lib/passfd.h b/lib/passfd.h
new file mode 100644
index 0000000000..13eb3b1dfb
--- /dev/null
+++ b/lib/passfd.h
@@ -0,0 +1,21 @@
+/* passfd.h -- definitions and prototypes for passfd.c
+
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#ifndef PASSFD_H_
+#define PASSFD_H_ 1
+int sendfd (int sock, int fd);
+int recvfd (int sock);
+#endif
diff --git a/modules/passfd b/modules/passfd
new file mode 100644
index 0000000000..43922e17d0
--- /dev/null
+++ b/modules/passfd
@@ -0,0 +1,30 @@
+Description:
+Passfile descriptors along Unix (socket/stream) file descriptors
+
+Files:
+m4/sockpfaf.m4
+m4/afunix.m4
+lib/passfd.c
+lib/passfd.h
+
+Depends-on:
+errno
+sys_socket
+extensions
+
+configure.ac:
+gl_SOCKET_AFUNIX
+
+Makefile.am:
+lib_SOURCES += passfd.c
+
+Include:
+<sys/socket.h>
+<sys/un.h>
+"passfd.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+Bastien ROUCARIÈS