bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] passfd: give nicer error for recvfd at eof


From: Eric Blake
Subject: [PATCH] passfd: give nicer error for recvfd at eof
Date: Tue, 24 Dec 2013 11:27:20 -0700

I noticed that recvfd() fails with errno set to EACCES if the
other end of the socket has closed (such as if it calls _exit());
but "Permission denied" as the strerror() message doesn't read
very well.  This improves things to give the nicer message:
"Transport endpoint is not connected".

* lib/passfd.c (recvfd): Fake ENOTCONN if other end closes early.
* tests/test-passfd.c (main): Enhance test to cover this.

Signed-off-by: Eric Blake <address@hidden>
---

Jim suggested enhancing the testsuite, and it turned out to not be
too difficult; so I'm pushing this now.

 ChangeLog           | 6 ++++++
 lib/passfd.c        | 8 +++++---
 tests/test-passfd.c | 8 ++++++++
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1753c8e..36ede18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-12-24  Eric Blake  <address@hidden>
+
+       passfd: give nicer error for recvfd at eof
+       * lib/passfd.c (recvfd): Fake ENOTCONN if other end closes early.
+       * tests/test-passfd.c (main): Enhance test to cover this.
+
 2013-12-17  Paul Eggert  <address@hidden>

        gettimeofday: port recent C++ fix to Emacs
diff --git a/lib/passfd.c b/lib/passfd.c
index 44a9de7..5388ca5 100644
--- a/lib/passfd.c
+++ b/lib/passfd.c
@@ -110,6 +110,7 @@ recvfd (int sock, int flags)
   struct iovec iov;
   struct msghdr msg;
   int fd = -1;
+  ssize_t len;
 # ifdef CMSG_FIRSTHDR
   struct cmsghdr *cmsg;
   char buf[CMSG_SPACE (sizeof fd)];
@@ -142,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;
     }

diff --git a/tests/test-passfd.c b/tests/test-passfd.c
index 6389e15..3351233 100644
--- a/tests/test-passfd.c
+++ b/tests/test-passfd.c
@@ -83,6 +83,7 @@ main ()
   /* father */
   else
     {
+      ASSERT (close (pair[1]) == 0);
       fd = recvfd (pair[0], 0);
       if (fd == -1)
         {
@@ -116,6 +117,13 @@ main ()
           perror ("fstat");
           return 80;
         }
+
+      /* Check behavior when sender no longer around */
+      errno = 0;
+      fd = recvfd (pair[0], 0);
+      ASSERT (fd == -1);
+      ASSERT (errno == ENOTCONN);
+
       return 0;
     }
 #else
-- 
1.8.4.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]