From beae0bdcf7fe30f2415c16f6b8c1368d469e519c Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 24 Dec 2013 11:16:07 -0700 Subject: [PATCH] passfd: give nicer error for recvfd at eof 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 --- 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 1753c8e24..36ede1819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-24 Eric Blake + + 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 gettimeofday: port recent C++ fix to Emacs diff --git a/lib/passfd.c b/lib/passfd.c index 44a9de77d..5388ca567 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 6389e154e..335123323 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 -- 2.11.0