X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/89e97516fedf1d0a7fe9c569bb569fa7ea872afa..068ba98ca54170b084721df9f7f8ec8d897714f5:/unix/uxnet.c diff --git a/unix/uxnet.c b/unix/uxnet.c index 2b3d8cbc..bd40937a 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -97,6 +97,10 @@ static int cmpfortree(void *av, void *bv) return -1; if (as > bs) return +1; + if (a < b) + return -1; + if (a > b) + return +1; return 0; } @@ -453,6 +457,14 @@ static int try_connect(Actual_Socket sock) short localport; int fl, salen; + /* + * Remove the socket from the tree before we overwrite its + * internal socket id, because that forms part of the tree's + * sorting criterion. We'll add it back before exiting this + * function, whether we changed anything or not. + */ + del234(sktree, sock); + if (sock->s >= 0) close(sock->s); @@ -470,7 +482,7 @@ static int try_connect(Actual_Socket sock) goto ret; } - fcntl(s, F_SETFD, FD_CLOEXEC); + cloexec(s); if (sock->oobinline) { int b = TRUE; @@ -605,9 +617,14 @@ static int try_connect(Actual_Socket sock) } uxsel_tell(sock); - add234(sktree, sock); ret: + + /* + * No matter what happened, put the socket back in the tree. + */ + add234(sktree, sock); + if (err) plug_log(sock->plug, 1, sock->addr, sock->port, strerror(err), err); return err; @@ -725,7 +742,7 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, i return (Socket) ret; } - fcntl(s, F_SETFD, FD_CLOEXEC); + cloexec(s); ret->oobinline = 0; @@ -1060,6 +1077,7 @@ static int net_select_result(int fd, int event) #endif socklen_t addrlen = sizeof(ss); int t; /* socket of connection */ + int fl; memset(&ss, 0, addrlen); t = accept(s->s, (struct sockaddr *)&ss, &addrlen); @@ -1067,6 +1085,10 @@ static int net_select_result(int fd, int event) break; } + fl = fcntl(t, F_GETFL); + if (fl != -1) + fcntl(t, F_SETFL, fl | O_NONBLOCK); + if (s->localhost_only && !sockaddr_is_loopback((struct sockaddr *)&ss)) { close(t); /* someone let nonlocal through?! */