passfd: allow compilation on mingw
authorEric Blake <eblake@redhat.com>
Thu, 21 Apr 2011 13:16:20 +0000 (07:16 -0600)
committerEric Blake <eblake@redhat.com>
Thu, 21 Apr 2011 20:35:06 +0000 (14:35 -0600)
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>
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

index 4f8321a..95fee48 100644 (file)
--- 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.
index c8e4228..f80e542 100644 (file)
@@ -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
index 1ab94b4..5d4c6a7 100644 (file)
@@ -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 @@ 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 <fcntl.h>).
 
@@ -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
index b60789f..f9e368b 100644 (file)
@@ -146,7 +146,6 @@ struct sockaddr_storage
    suggests that getaddrinfo should be available on all Windows
    releases. */
 
-
 # if @HAVE_WINSOCK2_H@
 #  include <winsock2.h>
 # endif
@@ -177,6 +176,19 @@ typedef int socklen_t;
 
 # 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@
index 13f7583..3f5eb44 100644 (file)
@@ -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],
index 477754b..29e3ad9 100644 (file)
@@ -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
index 0e9fb4e..f5cd1f7 100644 (file)
@@ -13,6 +13,7 @@ c++defs
 errno
 include_next
 socklen
+sys_uio
 warn-on-use
 
 configure.ac:
index d657ad9..315e6c2 100644 (file)
@@ -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 @@ 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
 }
index 8f323ca..a6e99d6 100644 (file)
@@ -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);
 }