X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fpassfd.c;h=5388ca567c2e4fc982d0b0d1f5bc0be0ab847ca6;hb=beae0bdcf7fe30f2415c16f6b8c1368d469e519c;hp=1ab94b48b35b1915b70f9305a15ce41c1b20cb36;hpb=f711a2d501b4cdf6f096a76d5e050bb14d67e513;p=gnulib.git diff --git a/lib/passfd.c b/lib/passfd.c index 1ab94b48b..5388ca567 100644 --- a/lib/passfd.c +++ b/lib/passfd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Free Software Foundation, Inc. +/* Copyright (C) 2011-2013 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 @@ -24,20 +24,23 @@ #include #include #include -#include #include #include -#if HAVE_SYS_UN_H -# include -#endif #include "cloexec.h" +/* The code that uses CMSG_FIRSTHDR is enabled on + Linux, Mac OS X, FreeBSD, OpenBSD, NetBSD, AIX, OSF/1, Cygwin. + The code that uses HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS is enabled on + HP-UX, IRIX, Solaris. */ + +/* MSG_CMSG_CLOEXEC is defined only on Linux, as of 2011. */ #ifndef MSG_CMSG_CLOEXEC # define MSG_CMSG_CLOEXEC 0 #endif +#if HAVE_SENDMSG /* sendfd sends the file descriptor fd along the socket to a process calling recvfd on the other end. @@ -46,24 +49,24 @@ int sendfd (int sock, int fd) { - char send = 0; + char byte = 0; struct iovec iov; struct msghdr msg; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY +# ifdef CMSG_FIRSTHDR struct cmsghdr *cmsg; char buf[CMSG_SPACE (sizeof fd)]; -#endif +# endif /* send at least one char */ memset (&msg, 0, sizeof msg); - iov.iov_base = &send; + iov.iov_base = &byte; iov.iov_len = 1; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY +# ifdef CMSG_FIRSTHDR msg.msg_control = buf; msg.msg_controllen = sizeof buf; cmsg = CMSG_FIRSTHDR (&msg); @@ -72,36 +75,47 @@ sendfd (int sock, int fd) cmsg->cmsg_len = CMSG_LEN (sizeof fd); /* Initialize the payload: */ memcpy (CMSG_DATA (cmsg), &fd, sizeof fd); -#elif HAVE_UNIXSOCKET_SCM_RIGHTS_BSD43_WAY +# elif HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS msg.msg_accrights = &fd; msg.msg_accrightslen = sizeof fd; -#else +# else errno = ENOSYS; return -1; -#endif +# endif if (sendmsg (sock, &msg, 0) != iov.iov_len) return -1; return 0; } +#else +int +sendfd (int sock _GL_UNUSED, int fd _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} +#endif + +#if HAVE_RECVMSG /* recvfd receives a file descriptor through the socket. The flags are a bitmask, possibly including O_CLOEXEC (defined in ). - Return 0 on success, or -1 with errno set in case of error. + Return the fd on success, or -1 with errno set in case of error. */ int recvfd (int sock, int flags) { - char recv = 0; + char byte = 0; struct iovec iov; struct msghdr msg; int fd = -1; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY + ssize_t len; +# ifdef CMSG_FIRSTHDR struct cmsghdr *cmsg; char buf[CMSG_SPACE (sizeof fd)]; int flags_recvmsg = flags & O_CLOEXEC ? MSG_CMSG_CLOEXEC : 0; -#endif +# endif if ((flags & ~O_CLOEXEC) != 0) { @@ -111,14 +125,14 @@ recvfd (int sock, int flags) /* send at least one char */ memset (&msg, 0, sizeof msg); - iov.iov_base = &recv; + iov.iov_base = &byte; iov.iov_len = 1; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY +# ifdef CMSG_FIRSTHDR msg.msg_control = buf; msg.msg_controllen = sizeof buf; cmsg = CMSG_FIRSTHDR (&msg); @@ -129,16 +143,17 @@ recvfd (int sock, int flags) memcpy (CMSG_DATA (cmsg), &fd, sizeof fd); msg.msg_controllen = cmsg->cmsg_len; - if (recvmsg (sock, &msg, flags_recvmsg) < 0) + len = recvmsg (sock, &msg, flags_recvmsg); + if (len < 0) return -1; cmsg = CMSG_FIRSTHDR (&msg); /* be paranoiac */ - if (cmsg == NULL || cmsg->cmsg_len != CMSG_LEN (sizeof fd) + if (len == 0 || cmsg == NULL || cmsg->cmsg_len != CMSG_LEN (sizeof fd) || cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { /* fake errno: at end the file is not available */ - errno = EACCES; + errno = len ? EACCES : ENOTCONN; return -1; } @@ -156,7 +171,7 @@ recvfd (int sock, int flags) } } -#elif HAVE_UNIXSOCKET_SCM_RIGHTS_BSD43_WAY +# elif HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS msg.msg_accrights = &fd; msg.msg_accrightslen = sizeof fd; if (recvmsg (sock, &msg, 0) < 0) @@ -173,9 +188,17 @@ recvfd (int sock, int flags) return -1; } } -#else +# else errno = ENOSYS; -#endif +# endif return fd; } +#else +int +recvfd (int sock _GL_UNUSED, int flags _GL_UNUSED) +{ + errno = ENOSYS; + return -1; +} +#endif