Revamp of the local X11 connection code. We now parse X display
[u/mdw/putty] / unix / uxnet.c
index 98453db..c0f2471 100644 (file)
@@ -88,6 +88,7 @@ struct Socket_tag {
 };
 
 struct SockAddr_tag {
+    int refcount;
     const char *error;
     enum { UNRESOLVED, UNIX, IP } superfamily;
 #ifndef NO_IPV6
@@ -193,6 +194,7 @@ SockAddr sk_namelookup(const char *host, char **canonicalname, int address_famil
     ret->superfamily = UNRESOLVED;
     *realhost = '\0';
     ret->error = NULL;
+    ret->refcount = 1;
 
 #ifndef NO_IPV6
     hints.ai_flags = AI_CANONNAME;
@@ -275,6 +277,7 @@ SockAddr sk_nonamelookup(const char *host)
 #else
     ret->addresses = NULL;
 #endif
+    ret->refcount = 1;
     return ret;
 }
 
@@ -412,7 +415,8 @@ void sk_addrcopy(SockAddr addr, char *buf)
 
 void sk_addr_free(SockAddr addr)
 {
-
+    if (--addr->refcount > 0)
+       return;
 #ifndef NO_IPV6
     if (addr->ais != NULL)
        freeaddrinfo(addr->ais);
@@ -422,6 +426,12 @@ void sk_addr_free(SockAddr addr)
     sfree(addr);
 }
 
+SockAddr sk_addr_dup(SockAddr addr)
+{
+    addr->refcount++;
+    return addr;
+}
+
 static Plug sk_tcp_plug(Socket sock, Plug p)
 {
     Actual_Socket s = (Actual_Socket) sock;
@@ -1380,8 +1390,7 @@ int net_service_lookup(char *service)
        return 0;
 }
 
-SockAddr platform_get_x11_unix_address(const char *display, int displaynum,
-                                      char **canonicalname)
+SockAddr platform_get_x11_unix_address(const char *sockpath, int displaynum)
 {
     SockAddr ret = snew(struct SockAddr_tag);
     int n;
@@ -1389,31 +1398,28 @@ SockAddr platform_get_x11_unix_address(const char *display, int displaynum,
     memset(ret, 0, sizeof *ret);
     ret->superfamily = UNIX;
     /*
-     * 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.
+     * In special circumstances (notably Mac OS X Leopard), we'll
+     * have been passed an explicit Unix socket path.
      */
-    if (display[0] == '/') {
+    if (sockpath) {
        n = snprintf(ret->hostname, sizeof ret->hostname,
-                    "%s", display);
+                    "%s", sockpath);
     } else {
        n = snprintf(ret->hostname, sizeof ret->hostname,
                     "%s%d", X11_UNIX_PATH, displaynum);
     }
-    if(n < 0)
+
+    if (n < 0)
        ret->error = "snprintf failed";
-    else if(n >= sizeof ret->hostname)
+    else if (n >= sizeof ret->hostname)
        ret->error = "X11 UNIX name too long";
-    else
-       *canonicalname = dupstr(ret->hostname);
+
 #ifndef NO_IPV6
     ret->ais = NULL;
 #else
     ret->addresses = NULL;
     ret->naddresses = 0;
 #endif
+    ret->refcount = 1;
     return ret;
 }