Thread (49 messages) 49 messages, 6 authors, 2016-06-15

Re: [PATCHv3 10/13] credentials: add "cache" helper

From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:52:46
Subsystem: the rest · Maintainer: Linus Torvalds

Jeff King wrote:
Still, it would be slightly more robust. I wonder how portable fchdir
is in practice (I guess we could always fall back to the getcwd code
path). Do you want to prepare a patch on top?
I've been wanting to get around to doing something similar for setup.c
for a while.  I'm happy enough to forget about it for now. ;-)

Thanks again for the fix.  Here's another quick nit.

-- >8 --
Subject: unix-socket: do not let close() or chdir() clobber errno during cleanup

unix_stream_connect and unix_stream_listen return -1 on error, with
errno set by the failing underlying call to allow the caller to write
a useful diagnosis.

Unfortunately the error path involves a few system calls itself, such
as close(), that can themselves touch errno.

This is not as worrisome as it might sound.  If close() fails, this
just means substituting one meaningful error message for another,
which is perfectly fine.  However, when the call _succeeds_, it is
allowed to (and sometimes might) clobber errno along the way with some
undefined value, so it is good higiene to save errno and restore it
immediately before returning to the caller.  Do so.

Signed-off-by: Jonathan Nieder <redacted>
---
 unix-socket.c |   39 ++++++++++++++++++++++-----------------
 1 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/unix-socket.c b/unix-socket.c
index 7d8bec61..01f119f9 100644
--- a/unix-socket.c
+++ b/unix-socket.c
@@ -73,25 +73,29 @@ static int unix_sockaddr_init(struct sockaddr_un *sa, const char *path,
 
 int unix_stream_connect(const char *path)
 {
-	int fd;
+	int fd, saved_errno;
 	struct sockaddr_un sa;
 	struct unix_sockaddr_context ctx;
 
 	if (unix_sockaddr_init(&sa, path, &ctx) < 0)
 		return -1;
 	fd = unix_stream_socket();
-	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
-		unix_sockaddr_cleanup(&ctx);
-		close(fd);
-		return -1;
-	}
+	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
+		goto fail;
 	unix_sockaddr_cleanup(&ctx);
 	return fd;
+
+fail:
+	saved_errno = errno;
+	unix_sockaddr_cleanup(&ctx);
+	close(fd);
+	errno = saved_errno;
+	return -1;
 }
 
 int unix_stream_listen(const char *path)
 {
-	int fd;
+	int fd, saved_errno;
 	struct sockaddr_un sa;
 	struct unix_sockaddr_context ctx;
 
@@ -100,18 +104,19 @@ int unix_stream_listen(const char *path)
 	fd = unix_stream_socket();
 
 	unlink(path);
-	if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
-		unix_sockaddr_cleanup(&ctx);
-		close(fd);
-		return -1;
-	}
+	if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
+		goto fail;
 
-	if (listen(fd, 5) < 0) {
-		unix_sockaddr_cleanup(&ctx);
-		close(fd);
-		return -1;
-	}
+	if (listen(fd, 5) < 0)
+		goto fail;
 
 	unix_sockaddr_cleanup(&ctx);
 	return fd;
+
+fail:
+	saved_errno = errno;
+	unix_sockaddr_cleanup(&ctx);
+	close(fd);
+	errno = saved_errno;
+	return -1;
 }
-- 
1.7.8.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help