diff --git a/xorg-x11-xtrans-devel.spec b/xorg-x11-xtrans-devel.spec index 70ae18c..0115ba2 100644 --- a/xorg-x11-xtrans-devel.spec +++ b/xorg-x11-xtrans-devel.spec @@ -6,13 +6,14 @@ Summary: X.Org X11 developmental X transport library Name: xorg-x11-xtrans-devel Version: 1.0.3 -Release: 2%{?dist} +Release: 3%{?dist} License: MIT/X11 Group: System Environment/Libraries URL: http://www.x.org BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Source0: ftp://ftp.x.org/pub/individual/lib/xtrans-%{version}.tar.bz2 +Patch0: xtrans-1.0.3-abstract-sockets.patch BuildRequires: pkgconfig BuildRequires: xorg-x11-util-macros @@ -24,6 +25,7 @@ X.Org X11 developmental X transport library %prep %setup -q -n xtrans-%{version} +%patch0 -p1 -b .abstract %build @@ -57,6 +59,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/aclocal/xtrans.m4 %changelog +* Fri Aug 24 2007 Adam Jackson 1.0.3-3 +- Abstract sockets for PF_UNIX. + * Sat Apr 21 2007 Matthias Clasen 1.0.3-2 - Don't install INSTALL diff --git a/xtrans-1.0.3-abstract-sockets.patch b/xtrans-1.0.3-abstract-sockets.patch new file mode 100644 index 0000000..cc31f5d --- /dev/null +++ b/xtrans-1.0.3-abstract-sockets.patch @@ -0,0 +1,294 @@ +diff -up xtrans-1.0.3/Xtransint.h.abstract xtrans-1.0.3/Xtransint.h +--- xtrans-1.0.3/Xtransint.h.abstract 2006-12-06 11:08:53.000000000 -0500 ++++ xtrans-1.0.3/Xtransint.h 2007-08-24 10:28:25.000000000 -0400 +@@ -374,9 +374,10 @@ typedef struct _Xtransport_table { + #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 */ ++#define TRANS_ABSTRACT (1<<5) /* Use abstract sockets if available */ + + /* Flags to preserve when setting others */ +-#define TRANS_KEEPFLAGS (TRANS_NOUNLINK) ++#define TRANS_KEEPFLAGS (TRANS_NOUNLINK|TRANS_ABSTRACT) + + /* + * readv() and writev() don't exist or don't work correctly on some +diff -up xtrans-1.0.3/Xtranssock.c.abstract xtrans-1.0.3/Xtranssock.c +--- xtrans-1.0.3/Xtranssock.c.abstract 2006-12-06 11:08:53.000000000 -0500 ++++ xtrans-1.0.3/Xtranssock.c 2007-08-24 16:05:10.000000000 -0400 +@@ -163,6 +163,10 @@ static int IBMsockInit = 0; + #define SocketInitOnce() /**/ + #endif + ++#ifdef linux ++#define HAVE_ABSTRACT_SOCKETS ++#endif ++ + #define MIN_BACKLOG 128 + #ifdef SOMAXCONN + #if SOMAXCONN > MIN_BACKLOG +@@ -835,23 +839,28 @@ TRANS(SocketSetOption) (XtransConnInfo c + + #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, int abstract) + { + struct sockaddr_un s; + int maxlen = sizeof(s.sun_path) - 1; ++ const char *at = ""; + + 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 ++ 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, "%s%s%s", at, upath, port); + return 0; + } + #endif +@@ -1074,6 +1083,12 @@ TRANS(SocketUNIXCreateListener) (XtransC + int oldUmask; + int status; + unsigned int mode; ++ char tmpport[64]; ++ ++ int abstract = 0; ++#ifdef HAVE_ABSTRACT_SOCKETS ++ abstract = ciptr->transptr->flags & TRANS_ABSTRACT; ++#endif + + PRMSG (2, "SocketUNIXCreateListener(%s)\n", + port ? port : "NULL", 0, 0); +@@ -1096,16 +1111,17 @@ TRANS(SocketUNIXCreateListener) (XtransC + } + #endif + ++ memset(&sockname, 0, sizeof(sockname)); + 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 { ++ if (!(port && *port)) { + snprintf (sockname.sun_path, sizeof(sockname.sun_path), + "%s%ld", UNIX_PATH, (long)getpid()); ++ port = tmpport; ++ } ++ if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { ++ PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); ++ return TRANS_CREATE_LISTENER_FAILED; + } + + #if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) && !defined(Lynx) +@@ -1118,7 +1134,12 @@ TRANS(SocketUNIXCreateListener) (XtransC + namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); + #endif + +- unlink (sockname.sun_path); ++ if (abstract) { ++ sockname.sun_path[0] = '\0'; ++ namelen = sizeof(sockname); ++ } ++ else ++ unlink (sockname.sun_path); + + if ((status = TRANS(SocketCreateListener) (ciptr, + (struct sockaddr *) &sockname, namelen, flags)) < 0) +@@ -1148,6 +1169,9 @@ TRANS(SocketUNIXCreateListener) (XtransC + return TRANS_CREATE_LISTENER_FAILED; + } + ++ if (abstract) ++ sockname.sun_path[0] = '@'; ++ + ciptr->family = sockname.sun_family; + ciptr->addrlen = namelen; + memcpy (ciptr->addr, &sockname, ciptr->addrlen); +@@ -1170,16 +1194,22 @@ TRANS(SocketUNIXResetListener) (XtransCo + struct stat statb; + int status = TRANS_RESET_NOOP; + unsigned int mode; ++ int abstract = 0; ++#ifdef HAVE_ABSTRACT_SOCKETS ++ abstract = ciptr->transptr->flags & TRANS_ABSTRACT; ++#endif + + PRMSG (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd, 0); + +- if (stat (unsock->sun_path, &statb) == -1 || ++ if (!abstract && ( ++ 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 ++ ))) + { + int oldUmask = umask (0); + +@@ -1361,6 +1391,10 @@ TRANS(SocketUNIXAccept) (XtransConnInfo + 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); +@@ -1959,6 +1993,10 @@ TRANS(SocketUNIXConnect) (XtransConnInfo + int old_namelen; + #endif + ++ int abstract = 0; ++#ifdef HAVE_ABSTRACT_SOCKETS ++ abstract = ciptr->transptr->flags & TRANS_ABSTRACT; ++#endif + + PRMSG (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port); + +@@ -1996,7 +2034,7 @@ TRANS(SocketUNIXConnect) (XtransConnInfo + + 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, abstract) != 0) { + PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); + return TRANS_CONNECT_FAILED; + } +@@ -2017,7 +2055,7 @@ TRANS(SocketUNIXConnect) (XtransConnInfo + * 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, abstract) != 0) { + PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); + return TRANS_CONNECT_FAILED; + } +@@ -2025,6 +2063,17 @@ TRANS(SocketUNIXConnect) (XtransConnInfo + offsetof(struct sockaddr_un, sun_path); + #endif + ++ /* ++ * 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 ++ } + + /* + * Do the connect() +@@ -2062,12 +2111,19 @@ TRANS(SocketUNIXConnect) (XtransConnInfo + * 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) { ++ /* ++ * If opening as abstract socket failed, try again "normally" ++ */ ++ if (abstract) ++ ciptr->transptr->flags &= ~(TRANS_ABSTRACT); ++ return TRANS_TRY_CONNECT_AGAIN; ++ } ++ else { + PRMSG (2,"SocketUNIXConnect: Can't connect: errno = %d\n", + EGET(),0, 0); + +@@ -2090,12 +2146,15 @@ TRANS(SocketUNIXConnect) (XtransConnInfo + return TRANS_CONNECT_FAILED; + } + ++ if (abstract) ++ sockname.sun_path[0] = '@'; ++ + ciptr->family = AF_UNIX; + ciptr->addrlen = namelen; + ciptr->peeraddrlen = namelen; + memcpy (ciptr->addr, &sockname, ciptr->addrlen); + memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen); +- ++ + return 0; + } + +@@ -2235,7 +2294,6 @@ TRANS(SocketINETClose) (XtransConnInfo c + #ifdef UNIXCONN + static int + TRANS(SocketUNIXClose) (XtransConnInfo ciptr) +- + { + /* + * If this is the server side, then once the socket is closed, +@@ -2254,7 +2312,8 @@ TRANS(SocketUNIXClose) (XtransConnInfo c + && sockname->sun_family == AF_UNIX + && sockname->sun_path[0]) + { +- if (!(ciptr->flags & TRANS_NOUNLINK)) ++ if (!(ciptr->flags & TRANS_NOUNLINK ++ || ciptr->transptr->flags & TRANS_ABSTRACT)) + unlink (sockname->sun_path); + } + +@@ -2421,7 +2480,11 @@ Xtransport TRANS(SocketINET6Funcs) = + Xtransport TRANS(SocketLocalFuncs) = { + /* Socket Interface */ + "local", ++#ifdef HAVE_ABSTRACT_SOCKETS ++ TRANS_ABSTRACT, ++#else + 0, ++#endif + #ifdef TRANS_CLIENT + TRANS(SocketOpenCOTSClient), + #endif /* TRANS_CLIENT */ +@@ -2467,7 +2530,7 @@ static char* unix_nolisten[] = { "local" + Xtransport TRANS(SocketUNIXFuncs) = { + /* Socket Interface */ + "unix", +-#if !defined(LOCALCONN) ++#if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS) + TRANS_ALIAS, + #else + 0,