Skip to content

Commit 06121a0

Browse files
jrngitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8ec6c8d commit 06121a0

File tree

1 file changed

+22
-17
lines changed

1 file changed

+22
-17
lines changed

unix-socket.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,25 +73,29 @@ static int unix_sockaddr_init(struct sockaddr_un *sa, const char *path,
7373

7474
int unix_stream_connect(const char *path)
7575
{
76-
int fd;
76+
int fd, saved_errno;
7777
struct sockaddr_un sa;
7878
struct unix_sockaddr_context ctx;
7979

8080
if (unix_sockaddr_init(&sa, path, &ctx) < 0)
8181
return -1;
8282
fd = unix_stream_socket();
83-
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
84-
unix_sockaddr_cleanup(&ctx);
85-
close(fd);
86-
return -1;
87-
}
83+
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
84+
goto fail;
8885
unix_sockaddr_cleanup(&ctx);
8986
return fd;
87+
88+
fail:
89+
saved_errno = errno;
90+
unix_sockaddr_cleanup(&ctx);
91+
close(fd);
92+
errno = saved_errno;
93+
return -1;
9094
}
9195

9296
int unix_stream_listen(const char *path)
9397
{
94-
int fd;
98+
int fd, saved_errno;
9599
struct sockaddr_un sa;
96100
struct unix_sockaddr_context ctx;
97101

@@ -100,18 +104,19 @@ int unix_stream_listen(const char *path)
100104
fd = unix_stream_socket();
101105

102106
unlink(path);
103-
if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
104-
unix_sockaddr_cleanup(&ctx);
105-
close(fd);
106-
return -1;
107-
}
107+
if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
108+
goto fail;
108109

109-
if (listen(fd, 5) < 0) {
110-
unix_sockaddr_cleanup(&ctx);
111-
close(fd);
112-
return -1;
113-
}
110+
if (listen(fd, 5) < 0)
111+
goto fail;
114112

115113
unix_sockaddr_cleanup(&ctx);
116114
return fd;
115+
116+
fail:
117+
saved_errno = errno;
118+
unix_sockaddr_cleanup(&ctx);
119+
close(fd);
120+
errno = saved_errno;
121+
return -1;
117122
}

0 commit comments

Comments
 (0)