X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/db9b7dcedb001b942ad945a56b2d7bf9b77d7a6a..1705f46890cf636d5d2a717e9ca12e281f0aea79:/unix/uxnet.c diff --git a/unix/uxnet.c b/unix/uxnet.c index e1dfce32..c082567d 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); @@ -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; @@ -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?! */ @@ -1270,15 +1292,29 @@ int net_service_lookup(char *service) return 0; } -SockAddr platform_get_x11_unix_address(int displaynum, char **canonicalname) +SockAddr platform_get_x11_unix_address(const char *display, int displaynum, + char **canonicalname) { SockAddr ret = snew(struct SockAddr_tag); int n; memset(ret, 0, sizeof *ret); ret->family = AF_UNIX; - n = snprintf(ret->hostname, sizeof ret->hostname, - "%s%d", X11_UNIX_PATH, displaynum); + /* + * Mac OS X Leopard uses an innovative X display naming + * convention in which the entire display name is the path to + * the Unix socket, including the trailing :0 which only + * _looks_ like a display number. Heuristically, I think + * detecting this by means of a leading slash ought to be + * adequate. + */ + if (display[0] == '/') { + n = snprintf(ret->hostname, sizeof ret->hostname, + "%s", display); + } else { + n = snprintf(ret->hostname, sizeof ret->hostname, + "%s%d", X11_UNIX_PATH, displaynum); + } if(n < 0) ret->error = "snprintf failed"; else if(n >= sizeof ret->hostname)