From: Eric Blake Date: Thu, 21 Apr 2011 13:16:20 +0000 (-0600) Subject: passfd: allow compilation on mingw X-Git-Tag: v0.1~2926 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=06d76f63c628cb1653f3c27a1f60a46cf44665ba;p=gnulib.git passfd: allow compilation on mingw The passfd module now skips on mingw, rather than failing to compile. It may be nice to add a sendmsg and recvmsg module in the future, but for now passfd is the only client that cares. * modules/sys_socket (Depends-on): Add sys_uio. * lib/sys_socket.in.h [!@HAVE_SYS_SOCKET_H@]: Use it for struct iovec and a minimal struct msghdr. * tests/test-sys_socket.c (main): Enhance test. * m4/afunix.m4 (gl_SOCKET_AFUNIX): Detect recvmsg/sendmsg. * lib/passfd.c (include): Drop ; is guaranteed to provide what we need. (sendmsg, recvmsg): Declare fallbacks if we lack sendmsg. * modules/passfd-tests (Depends-on): Add sys_wait. * tests/test-passfd.c (main): Skip test on mingw, for now. * doc/posix-headers/sys_socket.texi (sys/socket.h): Document the partial 'struct msghdr' implementation. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index 4f8321a1e..95fee4897 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2011-04-21 Eric Blake + passfd: allow compilation on mingw + * modules/sys_socket (Depends-on): Add sys_uio. + * lib/sys_socket.in.h [!@HAVE_SYS_SOCKET_H@]: Use it for struct + iovec and a minimal struct msghdr. + * m4/afunix.m4 (gl_SOCKET_AFUNIX): Detect recvmsg/sendmsg. + * tests/test-sys_socket.c (main): Enhance test. + * lib/passfd.c (include): Drop ; is + guaranteed to provide what we need. + (sendmsg, recvmsg): Declare fallbacks if we lack sendmsg. + * modules/passfd-tests (Depends-on): Add sys_wait. + * tests/test-passfd.c (main): Skip test on mingw, for now. + * doc/posix-headers/sys_socket.texi (sys/socket.h): Document the + partial 'struct msghdr' implementation. + sys_uio: new module * modules/sys_uio: New module. * modules/sys_uio-tests: Likewise. diff --git a/doc/posix-headers/sys_socket.texi b/doc/posix-headers/sys_socket.texi index c8e42280f..f80e54254 100644 --- a/doc/posix-headers/sys_socket.texi +++ b/doc/posix-headers/sys_socket.texi @@ -29,4 +29,10 @@ AIX 7.1. Portability problems not fixed by Gnulib: @itemize +@item +This header file does not declare the @code{msg_control} and +@code{msg_controllen} members of @code{struct msghdr} on some +platforms. This can be detected by the absence of the +@code{CMSG_FIRSTHDR} macro: +gnulib replacement header, old BSD @end itemize diff --git a/lib/passfd.c b/lib/passfd.c index 1ab94b48b..5d4c6a762 100644 --- a/lib/passfd.c +++ b/lib/passfd.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -38,6 +37,7 @@ # 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. @@ -49,10 +49,10 @@ sendfd (int sock, int fd) char send = 0; struct iovec iov; struct msghdr msg; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY +# if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY struct cmsghdr *cmsg; char buf[CMSG_SPACE (sizeof fd)]; -#endif +# endif /* send at least one char */ memset (&msg, 0, sizeof msg); @@ -63,7 +63,7 @@ sendfd (int sock, int fd) msg.msg_name = NULL; msg.msg_namelen = 0; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY +# if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY msg.msg_control = buf; msg.msg_controllen = sizeof buf; cmsg = CMSG_FIRSTHDR (&msg); @@ -72,19 +72,29 @@ 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_UNIXSOCKET_SCM_RIGHTS_BSD43_WAY 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 ). @@ -97,11 +107,11 @@ recvfd (int sock, int flags) struct iovec iov; struct msghdr msg; int fd = -1; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY +# if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY 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) { @@ -118,7 +128,7 @@ recvfd (int sock, int flags) msg.msg_name = NULL; msg.msg_namelen = 0; -#if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY +# if HAVE_UNIXSOCKET_SCM_RIGHTS_BSD44_WAY msg.msg_control = buf; msg.msg_controllen = sizeof buf; cmsg = CMSG_FIRSTHDR (&msg); @@ -156,7 +166,7 @@ recvfd (int sock, int flags) } } -#elif HAVE_UNIXSOCKET_SCM_RIGHTS_BSD43_WAY +# elif HAVE_UNIXSOCKET_SCM_RIGHTS_BSD43_WAY msg.msg_accrights = &fd; msg.msg_accrightslen = sizeof fd; if (recvmsg (sock, &msg, 0) < 0) @@ -173,9 +183,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 diff --git a/lib/sys_socket.in.h b/lib/sys_socket.in.h index b60789f2a..f9e368b6c 100644 --- a/lib/sys_socket.in.h +++ b/lib/sys_socket.in.h @@ -146,7 +146,6 @@ struct sockaddr_storage suggests that getaddrinfo should be available on all Windows releases. */ - # if @HAVE_WINSOCK2_H@ # include # endif @@ -177,6 +176,19 @@ typedef int socklen_t; # endif +/* For struct iovec */ +# include + +/* Rudimentary 'struct msghdr'; this works as long as you don't try to + access msg_control or msg_controllen. */ +struct msghdr { + void *msg_name; + socklen_t msg_namelen; + struct iovec *msg_iov; + int msg_iovlen; + int msg_flags; +}; + #endif #if @HAVE_WINSOCK2_H@ diff --git a/m4/afunix.m4 b/m4/afunix.m4 index 13f758316..3f5eb447d 100644 --- a/m4/afunix.m4 +++ b/m4/afunix.m4 @@ -1,4 +1,4 @@ -# afunix.m4 serial 6 +# afunix.m4 serial 7 dnl Copyright (C) 2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_SOCKET_AFUNIX], [ AC_REQUIRE([gl_HEADER_SYS_SOCKET]) AC_REQUIRE([gl_SOCKET_FAMILY_UNIX]) + AC_CHECK_FUNCS_ONCE([recvmsg sendmsg]) AC_MSG_CHECKING([for UNIX domain sockets SCM_RIGHTS]) AC_CACHE_VAL([gl_cv_socket_unix_scm_rights], diff --git a/modules/passfd-tests b/modules/passfd-tests index 477754b2b..29e3ad932 100644 --- a/modules/passfd-tests +++ b/modules/passfd-tests @@ -3,9 +3,10 @@ tests/test-passfd.c tests/macros.h Depends-on: +sys_wait configure.ac: -AC_CHECK_DECLS_ONCE([alarm]) +AC_CHECK_DECLS_ONCE([alarm socketpair]) Makefile.am: TESTS += test-passfd diff --git a/modules/sys_socket b/modules/sys_socket index 0e9fb4e3f..f5cd1f7d0 100644 --- a/modules/sys_socket +++ b/modules/sys_socket @@ -13,6 +13,7 @@ c++defs errno include_next socklen +sys_uio warn-on-use configure.ac: diff --git a/tests/test-passfd.c b/tests/test-passfd.c index d657ad9d6..315e6c21b 100644 --- a/tests/test-passfd.c +++ b/tests/test-passfd.c @@ -18,6 +18,7 @@ #include "passfd.h" +#include #include #include #include @@ -33,6 +34,7 @@ int main () { +#if HAVE_SOCKETPAIR int pair[2]; int ret; pid_t pid; @@ -41,11 +43,11 @@ main () int fd; struct stat st; -#if HAVE_DECL_ALARM +# if HAVE_DECL_ALARM /* Avoid hanging on failure. */ signal (SIGALRM, SIG_DFL); alarm (5); -#endif +# endif fdnull = open ("/dev/null", O_RDWR); if (fdnull < 0) @@ -115,4 +117,17 @@ main () } return 0; } +#else + errno = 0; + ASSERT(sendfd (0, 0) == -1); + ASSERT(errno == ENOSYS); + + errno = 0; + ASSERT(recvfd (0, 0) == -1); + ASSERT(errno == ENOSYS); + + fputs ("skipping test: socketpair not supported on this system\n", + stderr); + return 77; +#endif } diff --git a/tests/test-sys_socket.c b/tests/test-sys_socket.c index 8f323ca1d..a6e99d600 100644 --- a/tests/test-sys_socket.c +++ b/tests/test-sys_socket.c @@ -30,6 +30,12 @@ int a[] = { SHUT_RD, SHUT_WR, SHUT_RDWR }; /* Check that the 'socklen_t' type is defined. */ socklen_t t1; +/* Check that 'struct iovec' is defined. */ +struct iovec io; + +/* Check that a minimal set of 'struct msghdr' is defined. */ +struct msghdr msg; + int main (void) { @@ -51,10 +57,8 @@ main (void) x.ss_family = 42; i = 42; + msg.msg_iov = &io; - /* Tell the compiler that these variables are used. */ - (void) x; - (void) i; - - return 0; + return (x.ss_family - i + msg.msg_namelen + msg.msg_iov->iov_len + + msg.msg_iovlen); }