Index: lib/xtrans/Xtrans.c =================================================================== RCS file: /cvs/xorg/lib/xtrans/Xtrans.c,v retrieving revision 1.6 diff -u -r1.6 Xtrans.c --- lib/xtrans/Xtrans.c 8 Nov 2005 06:33:26 -0000 1.6 +++ lib/xtrans/Xtrans.c 17 Mar 2006 04:08:40 -0000 @@ -1400,3 +1400,6 @@ #endif /* NEED_UTSNAME */ return len; } + +/* vim:set ts=8 sw=4: */ + Index: lib/xtrans/Xtrans.h =================================================================== RCS file: /cvs/xorg/lib/xtrans/Xtrans.h,v retrieving revision 1.2 diff -u -r1.2 Xtrans.h --- lib/xtrans/Xtrans.h 23 Apr 2004 18:44:27 -0000 1.2 +++ lib/xtrans/Xtrans.h 17 Mar 2006 04:08:40 -0000 @@ -488,3 +488,6 @@ #endif #endif /* _XTRANS_H_ */ + +/* vim:set ts=8 sw=4: */ + Index: lib/xtrans/Xtransint.h =================================================================== RCS file: /cvs/xorg/lib/xtrans/Xtransint.h,v retrieving revision 1.4 diff -u -r1.4 Xtransint.h --- lib/xtrans/Xtransint.h 8 Nov 2005 06:33:26 -0000 1.4 +++ lib/xtrans/Xtransint.h 17 Mar 2006 04:08:40 -0000 @@ -374,9 +374,15 @@ #define TRANS_DISABLED (1<<2) /* Don't open this one */ #define TRANS_NOLISTEN (1<<3) /* Don't listen on this one */ #define TRANS_NOUNLINK (1<<4) /* Dont unlink transport endpoints */ +#ifdef HAVE_ABSTRACT_SOCKETS +/* XXX: should be safe enough to define this unconditionally */ +#define TRANS_ABSTRACT (1<<5) /* Use abstract sockets if available */ /* Flags to preserve when setting others */ +#define TRANS_KEEPFLAGS (TRANS_NOUNLINK|TRANS_ABSTRACT) +#else #define TRANS_KEEPFLAGS (TRANS_NOUNLINK) +#endif /* * readv() and writev() don't exist or don't work correctly on some @@ -483,3 +489,6 @@ #endif /* XTRANSDEBUG */ #endif /* _XTRANSINT_H_ */ + +/* vim:set ts=8 sw=4: */ + Index: lib/xtrans/Xtranssock.c =================================================================== RCS file: /cvs/xorg/lib/xtrans/Xtranssock.c,v retrieving revision 1.11 diff -u -r1.11 Xtranssock.c --- lib/xtrans/Xtranssock.c 8 Nov 2005 06:33:26 -0000 1.11 +++ lib/xtrans/Xtranssock.c 17 Mar 2006 04:08:43 -0000 @@ -831,23 +831,41 @@ #ifdef UNIXCONN static int -set_sun_path(const char *port, const char *upath, char *path) +set_sun_path(const char *port, const char *upath, char *path +#ifdef HAVE_ABSTRACT_SOCKETS + , int abstract +#endif + ) { struct sockaddr_un s; int maxlen = sizeof(s.sun_path) - 1; +#ifdef HAVE_ABSTRACT_SOCKETS + const char *at = abstract ? "@" : ""; +#define ABSTRACTPREFIX "%s" +#define ABSTRACTARG , at +#else +#define ABSTRACTPREFIX +#define ABSTRACTARG +#endif if (!port || !*port || !path) return -1; - if (*port == '/') { /* a full pathname */ - if (strlen(port) > maxlen) - return -1; - sprintf(path, "%s", port); - } else { - if (strlen(port) + strlen(upath) > maxlen) - return -1; - sprintf(path, "%s%s", upath, port); - } +#ifdef HAVE_ABSTRACT_SOCKETS + at = ""; + if (port[0] == '@') + upath = ""; + else if (abstract) + at = "@"; +#endif + if (*port == '/') /* a full pathname */ + upath = ""; + + if (strlen(port) + strlen(upath) > maxlen) + return -1; + sprintf(path, ABSTRACTPREFIX "%s%s" ABSTRACTARG , upath, port); +#undef ABSTRACTPREFIX +#undef ABSTRACTARG return 0; } #endif @@ -1070,6 +1088,14 @@ int oldUmask; int status; unsigned int mode; + char tmpport[64]; + +#ifdef HAVE_ABSTRACT_SOCKETS + int abstract = ciptr->transptr->flags & TRANS_ABSTRACT; +#define ABSTRACTARG , abstract +#else +#define ABSTRACTARG +#endif PRMSG (2, "SocketUNIXCreateListener(%s)\n", port ? port : "NULL", 0, 0); @@ -1094,13 +1120,13 @@ sockname.sun_family = AF_UNIX; - if (port && *port) { - if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) { - PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); - return TRANS_CREATE_LISTENER_FAILED; - } - } else { - sprintf (sockname.sun_path, "%s%ld", UNIX_PATH, (long)getpid()); + if (! (port && *port)) { + sprintf (tmpport, "%ld", (long)getpid()); + port = tmpport; + } + if (set_sun_path(port, UNIX_PATH, sockname.sun_path ABSTRACTARG) != 0) { + PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); + return TRANS_CREATE_LISTENER_FAILED; } #if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) && !defined(Lynx) @@ -1110,7 +1136,12 @@ namelen = strlen(sockname.sun_path) + sizeof(sockname.sun_family); #endif - unlink (sockname.sun_path); +#ifdef HAVE_ABSTRACT_SOCKETS + if (abstract) + sockname.sun_path[0] = '\0'; + else +#endif + unlink (sockname.sun_path); if ((status = TRANS(SocketCreateListener) (ciptr, (struct sockaddr *) &sockname, namelen, flags)) < 0) @@ -1140,6 +1171,10 @@ return TRANS_CREATE_LISTENER_FAILED; } +#ifdef HAVE_ABSTRACT_SOCKETS + if (ciptr->transptr->flags & TRANS_ABSTRACT) + sockname.sun_path[0] = '@'; +#endif ciptr->family = sockname.sun_family; ciptr->addrlen = namelen; memcpy (ciptr->addr, &sockname, ciptr->addrlen); @@ -1148,6 +1183,7 @@ return 0; } +#undef ABSTRACTARG static int @@ -1165,12 +1201,20 @@ PRMSG (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd, 0); - if (stat (unsock->sun_path, &statb) == -1 || + if ( +#ifdef HAVE_ABSTRACT_SOCKETS + ! (ciptr->transptr->flags & TRANS_ABSTRACT) && ( +#endif + stat (unsock->sun_path, &statb) == -1 || ((statb.st_mode & S_IFMT) != #if (defined (sun) && defined(SVR4)) || defined(NCR) || defined(SCO325) || !defined(S_IFSOCK) - S_IFIFO)) + S_IFIFO #else - S_IFSOCK)) + S_IFSOCK +#endif + )) +#ifdef HAVE_ABSTRACT_SOCKETS + ) #endif { int oldUmask = umask (0); @@ -1353,6 +1397,10 @@ return NULL; } + /* + * if the socket is abstract, we already modified the address to have a + * @ instead of the initial NUL, so no need to do that again here. + */ newciptr->addrlen = ciptr->addrlen; memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen); @@ -1951,6 +1999,12 @@ int old_namelen; #endif +#ifdef HAVE_ABSTRACT_SOCKETS + int abstract = ciptr->transptr->flags & TRANS_ABSTRACT; +#define ABSTRACTARG , abstract +#else +#define ABSTRACTARG +#endif PRMSG (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port); @@ -1988,7 +2042,7 @@ sockname.sun_family = AF_UNIX; - if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) { + if (set_sun_path(port, UNIX_PATH, sockname.sun_path ABSTRACTARG) != 0) { PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); return TRANS_CONNECT_FAILED; } @@ -2006,7 +2060,7 @@ * This is gross, but it was in Xlib */ old_sockname.sun_family = AF_UNIX; - if (set_sun_path(port, OLD_UNIX_PATH, old_sockname.sun_path) != 0) { + if (set_sun_path(port, OLD_UNIX_PATH, old_sockname.sun_path ABSTRACTARG) != 0) { PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); return TRANS_CONNECT_FAILED; } @@ -2014,6 +2068,19 @@ sizeof (old_sockname.sun_family); #endif +#ifdef HAVE_ABSTRACT_SOCKETS + /* + * Adjust the socket path if using abstract sockets. + * Done here because otherwise all the strlen() calls above would fail. + */ + + if (abstract) { + sockname.sun_path[0] = '\0'; +#if defined(hpux) && defined(X11_t) + old_sockname.sun_path[0] = '\0'; +#endif + } +#endif /* * Do the connect() @@ -2051,12 +2118,21 @@ * should try again. */ - if (olderrno == ENOENT || olderrno == EINTR) - return TRANS_TRY_CONNECT_AGAIN; - else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) + if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) return TRANS_IN_PROGRESS; - else - { + else if (olderrno == EINTR) + return TRANS_TRY_CONNECT_AGAIN; + else if (olderrno == ENOENT) { +#ifdef HAVE_ABSTRACT_SOCKETS + /* + * If opening as abstract socket failed, try again "normally" + */ + if (abstract) + ciptr->transptr->flags &= ~(TRANS_ABSTRACT); +#endif + return TRANS_TRY_CONNECT_AGAIN; + } + else { PRMSG (2,"SocketUNIXConnect: Can't connect: errno = %d\n", EGET(),0, 0); @@ -2079,14 +2155,20 @@ return TRANS_CONNECT_FAILED; } +#ifdef HAVE_ABSTRACT_SOCKETS + if (abstract) + sockname.sun_path[0] = '@'; +#endif + ciptr->family = AF_UNIX; ciptr->addrlen = namelen; ciptr->peeraddrlen = namelen; memcpy (ciptr->addr, &sockname, ciptr->addrlen); memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen); - + return 0; } +#undef ABSTRACTARG #endif /* UNIXCONN */ @@ -2095,7 +2177,6 @@ static int TRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) - { PRMSG (2,"SocketBytesReadable(%p,%d,%p)\n", ciptr, ciptr->fd, pend); @@ -2124,7 +2205,6 @@ static int TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) - { PRMSG (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size); @@ -2144,7 +2224,6 @@ static int TRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size) - { PRMSG (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size); @@ -2164,7 +2243,6 @@ static int TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) - { PRMSG (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size); @@ -2174,7 +2252,6 @@ static int TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) - { PRMSG (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size); @@ -2184,7 +2261,6 @@ static int TRANS(SocketDisconnect) (XtransConnInfo ciptr) - { PRMSG (2,"SocketDisconnect(%p,%d)\n", ciptr, ciptr->fd, 0); @@ -2203,7 +2279,6 @@ #ifdef TCPCONN static int TRANS(SocketINETClose) (XtransConnInfo ciptr) - { PRMSG (2,"SocketINETClose(%p,%d)\n", ciptr, ciptr->fd, 0); @@ -2224,7 +2299,6 @@ #ifdef UNIXCONN static int TRANS(SocketUNIXClose) (XtransConnInfo ciptr) - { /* * If this is the server side, then once the socket is closed, @@ -2243,7 +2317,11 @@ && sockname->sun_family == AF_UNIX && sockname->sun_path[0]) { - if (!(ciptr->flags & TRANS_NOUNLINK)) + if (!(ciptr->flags & TRANS_NOUNLINK +#ifdef HAVE_ABSTRACT_SOCKETS + || ciptr->transptr->flags & TRANS_ABSTRACT +#endif + )) unlink (sockname->sun_path); } @@ -2252,7 +2330,6 @@ static int TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr) - { /* * Don't unlink path. @@ -2410,7 +2487,11 @@ Xtransport TRANS(SocketLocalFuncs) = { /* Socket Interface */ "local", +#ifdef HAVE_ABSTRACT_SOCKETS + TRANS_ABSTRACT, +#else 0, +#endif #ifdef TRANS_CLIENT TRANS(SocketOpenCOTSClient), #endif /* TRANS_CLIENT */ @@ -2456,7 +2537,7 @@ Xtransport TRANS(SocketUNIXFuncs) = { /* Socket Interface */ "unix", -#if !defined(LOCALCONN) +#if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS) TRANS_ALIAS, #else 0, @@ -2502,3 +2583,6 @@ }; #endif /* UNIXCONN */ + +/* vim:set ts=8 sw=4: */ + Index: lib/xtrans/configure.ac =================================================================== RCS file: /cvs/xorg/lib/xtrans/configure.ac,v retrieving revision 1.14 diff -u -r1.14 configure.ac --- lib/xtrans/configure.ac 15 Dec 2005 00:24:36 -0000 1.14 +++ lib/xtrans/configure.ac 17 Mar 2006 04:08:43 -0000 @@ -48,5 +48,15 @@ XORG_RELEASE_VERSION +case $target in + *linux*) + abstract_socket_define="-DHAVE_ABSTRACT_SOCKETS" + ;; + *) + abstract_socket_define="" +esac + +AC_SUBST(abstract_socket_define) + AC_OUTPUT([Makefile xtrans.pc]) Index: lib/xtrans/xtrans.pc.in =================================================================== RCS file: /cvs/xorg/lib/xtrans/xtrans.pc.in,v retrieving revision 1.5 diff -u -r1.5 xtrans.pc.in --- lib/xtrans/xtrans.pc.in 2 Jul 2005 18:00:50 -0000 1.5 +++ lib/xtrans/xtrans.pc.in 17 Mar 2006 04:08:43 -0000 @@ -6,4 +6,4 @@ Name: XTrans Description: Abstract network code for X Version: @PACKAGE_VERSION@ -Cflags: -I${includedir} -D_BSD_SOURCE @fchown_define@ @sticky_bit_define@ +Cflags: -I${includedir} -D_BSD_SOURCE @fchown_define@ @sticky_bit_define@ @abstract_socket_define@