[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