Cosmetic: use `appname' in more places, so that Unix PuTTYtel announces itself
[sgt/putty] / unix / uxnet.c
index e1dfce3..c082567 100644 (file)
@@ -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)