Dear diary, on Wed, Jun 28, 2006 at 06:56:12PM CEST, I got a letter where Morten Welinder <mwelinder@xxxxxxxxx> said that... > It looks like connect.c waits too long before it uses errno in both copies > of git_tcp_connect_sock. Both close and freeaddrinfo can poke any > non-zero value in there. Nice catch. ->8- errno was used after it could've been modified by a subsequent library call. Spotted by Morten Welinder. Signed-off-by: Petr Baudis <pasky@xxxxxxx> --- connect.c | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-) diff --git a/connect.c b/connect.c index cb4656d..9a87bd9 100644 --- a/connect.c +++ b/connect.c @@ -328,7 +328,7 @@ #ifndef NO_IPV6 */ static int git_tcp_connect_sock(char *host) { - int sockfd = -1; + int sockfd = -1, saved_errno = 0; char *colon, *end; const char *port = STR(DEFAULT_GIT_PORT); struct addrinfo hints, *ai0, *ai; @@ -362,9 +362,12 @@ static int git_tcp_connect_sock(char *ho for (ai0 = ai; ai; ai = ai->ai_next) { sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (sockfd < 0) + if (sockfd < 0) { + saved_errno = errno; continue; + } if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { + saved_errno = errno; close(sockfd); sockfd = -1; continue; @@ -375,7 +378,7 @@ static int git_tcp_connect_sock(char *ho freeaddrinfo(ai0); if (sockfd < 0) - die("unable to connect a socket (%s)", strerror(errno)); + die("unable to connect a socket (%s)", strerror(saved_errno)); return sockfd; } @@ -387,7 +390,7 @@ #else /* NO_IPV6 */ */ static int git_tcp_connect_sock(char *host) { - int sockfd = -1; + int sockfd = -1, saved_errno = 0; char *colon, *end; char *port = STR(DEFAULT_GIT_PORT), *ep; struct hostent *he; @@ -426,8 +429,10 @@ static int git_tcp_connect_sock(char *ho for (ap = he->h_addr_list; *ap; ap++) { sockfd = socket(he->h_addrtype, SOCK_STREAM, 0); - if (sockfd < 0) + if (sockfd < 0) { + saved_errno = errno; continue; + } memset(&sa, 0, sizeof sa); sa.sin_family = he->h_addrtype; @@ -435,6 +440,7 @@ static int git_tcp_connect_sock(char *ho memcpy(&sa.sin_addr, *ap, he->h_length); if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) { + saved_errno = errno; close(sockfd); sockfd = -1; continue; @@ -443,7 +449,7 @@ static int git_tcp_connect_sock(char *ho } if (sockfd < 0) - die("unable to connect a socket (%s)", strerror(errno)); + die("unable to connect a socket (%s)", strerror(saved_errno)); return sockfd; } -- Petr "Pasky" Baudis Stuff: http://pasky.or.cz/ Snow falling on Perl. White noise covering line noise. Hides all the bugs too. -- J. Putnam - : send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html