Mercurial > hg > octave-nkf > gnulib-hg
changeset 14599:2a40136b85ae
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 <sys/uio.h>; <sys/sockets.h> 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 <eblake@redhat.com>
author | Eric Blake <eblake@redhat.com> |
---|---|
date | Thu, 21 Apr 2011 07:16:20 -0600 |
parents | 052f47e91db5 |
children | f57a9fcc777a |
files | ChangeLog doc/posix-headers/sys_socket.texi lib/passfd.c lib/sys_socket.in.h m4/afunix.m4 modules/passfd-tests modules/sys_socket tests/test-passfd.c tests/test-sys_socket.c |
diffstat | 9 files changed, 95 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2011-04-21 Eric Blake <eblake@redhat.com> + 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 <sys/uio.h>; <sys/sockets.h> 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.
--- a/doc/posix-headers/sys_socket.texi +++ b/doc/posix-headers/sys_socket.texi @@ -29,4 +29,10 @@ 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
--- a/lib/passfd.c +++ b/lib/passfd.c @@ -24,7 +24,6 @@ #include <stdlib.h> #include <string.h> #include <sys/types.h> -#include <sys/uio.h> #include <unistd.h> #include <sys/socket.h> @@ -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 @@ 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 @@ 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 @@ 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 <fcntl.h>). @@ -97,11 +107,11 @@ 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 @@ 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 @@ } } -#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 @@ 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
--- a/lib/sys_socket.in.h +++ b/lib/sys_socket.in.h @@ -146,7 +146,6 @@ suggests that getaddrinfo should be available on all Windows releases. */ - # if @HAVE_WINSOCK2_H@ # include <winsock2.h> # endif @@ -177,6 +176,19 @@ # endif +/* For struct iovec */ +# include <sys/uio.h> + +/* 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@
--- 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_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],
--- a/modules/passfd-tests +++ b/modules/passfd-tests @@ -3,9 +3,10 @@ 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
--- a/modules/sys_socket +++ b/modules/sys_socket @@ -13,6 +13,7 @@ errno include_next socklen +sys_uio warn-on-use configure.ac:
--- a/tests/test-passfd.c +++ b/tests/test-passfd.c @@ -18,6 +18,7 @@ #include "passfd.h" +#include <errno.h> #include <fcntl.h> #include <signal.h> #include <stdlib.h> @@ -33,6 +34,7 @@ int main () { +#if HAVE_SOCKETPAIR int pair[2]; int ret; pid_t pid; @@ -41,11 +43,11 @@ 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 @@ } 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 }
--- a/tests/test-sys_socket.c +++ b/tests/test-sys_socket.c @@ -30,6 +30,12 @@ /* 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 @@ 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); }