From 656f29cc631972002ec0fe1ee8f2ee53438f818d Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 11 Jun 2014 16:35:13 +0200 Subject: Add 028_nx-X11_abstract-kernel-sockets.full.patch. Provide abstract local socket support for Linux based systems. This patch pulls in abstract socket relevant code from xtrans 1.2.7. --- debian/changelog | 3 + .../028_nx-X11_abstract-kernel-sockets.full.patch | 299 +++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 303 insertions(+) create mode 100644 debian/patches/028_nx-X11_abstract-kernel-sockets.full.patch (limited to 'debian') diff --git a/debian/changelog b/debian/changelog index 9218a1882..28deb7120 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,9 @@ nx-libs (2:3.5.0.25-0x2go1) UNRELEASED; urgency=low available. (Fixes: #505). * Make 220_nxproxy-bind-loopback-only.full+lite.patch cleanly apply after having added 027_nxcomp_abstract-X11-socket.full+lite.patch. + * Add 028_nx-X11_abstract-kernel-sockets.full.patch. Provide abstract local + socket support for Linux based systems. This patch pulls in abstract + socket relevant code from xtrans 1.2.7. (Fixes: #504). -- Mike Gabriel Wed, 07 May 2014 09:58:10 +0200 diff --git a/debian/patches/028_nx-X11_abstract-kernel-sockets.full.patch b/debian/patches/028_nx-X11_abstract-kernel-sockets.full.patch new file mode 100644 index 000000000..ae672e94b --- /dev/null +++ b/debian/patches/028_nx-X11_abstract-kernel-sockets.full.patch @@ -0,0 +1,299 @@ +Author: Mike Gabriel +Description: Support abstract local sockets for Linux systems +Abstract: + Relevant code taken from xtrans 1.2.7 on 2014-06-11. + +--- a/nx-X11/lib/xtrans/Xtranssock.c ++++ b/nx-X11/lib/xtrans/Xtranssock.c +@@ -172,6 +172,8 @@ + sock_init();\ + IBMsockInit = 1;\ + } ++ ++ + #undef EINTR + #define EINTR SOCEINTR + #undef EINVAL +@@ -192,6 +194,10 @@ + #define SocketInitOnce() /**/ + #endif + ++#if defined(linux) ++#define HAVE_ABSTRACT_SOCKETS ++#endif ++ + #define MIN_BACKLOG 128 + #ifdef SOMAXCONN + #if SOMAXCONN > MIN_BACKLOG +@@ -532,7 +538,7 @@ + + void TRANS(SocketRejectConnection) (XtransConnInfo ciptr) + { +- size_t sa_l = sizeof(struct sockaddr); ++ socklen_t sa_l = sizeof(struct sockaddr); + struct sockaddr sa; + fd_set fs; + struct timeval t; +@@ -1477,23 +1483,28 @@ + + #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; ++ snprintf(path, sizeof(s.sun_path), "%s%s%s", at, upath, port); + return 0; + } + #endif +@@ -1726,6 +1737,12 @@ + int oldUmask; + int status; + unsigned int mode; ++ char tmpport[108]; ++ ++ int abstract = 0; ++#ifdef HAVE_ABSTRACT_SOCKETS ++ abstract = ciptr->transptr->flags & TRANS_ABSTRACT; ++#endif + + PRMSG (2, "SocketUNIXCreateListener(%s)\n", + port ? port : "NULL", 0, 0); +@@ -1741,11 +1758,11 @@ + mode = 0777; + #endif + #ifdef NX_TRANS_SOCKET +- if (trans_mkdir(_NXGetUnixDir(UNIX_DIR), mode) == -1) { ++ if (!abstract && trans_mkdir(_NXGetUnixDir(UNIX_DIR), mode) == -1) { + PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n", + _NXGetUnixDir(UNIX_DIR), errno, 0); + #else +- if (trans_mkdir(UNIX_DIR, mode) == -1) { ++ if (!abstract && trans_mkdir(UNIX_DIR, mode) == -1) { + PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n", + UNIX_DIR, errno, 0); + #endif +@@ -1754,13 +1771,18 @@ + } + #endif + ++ memset(&sockname, 0, sizeof(sockname)); + sockname.sun_family = AF_UNIX; + ++ if (!(port && *port)) { ++ snprintf (tmpport, sizeof(tmpport), "%s%ld", UNIX_PATH, (long)getpid()); ++ port = tmpport; ++ } + if (port && *port) { + #ifdef NX_TRANS_SOCKET +- if (set_sun_path(port, _NXGetUnixPath(UNIX_PATH), sockname.sun_path) != 0) { ++ if (set_sun_path(port, _NXGetUnixPath(UNIX_PATH), sockname.sun_path, abstract) != 0) { + #else +- if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) { ++ if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { + #endif + PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); + return TRANS_CREATE_LISTENER_FAILED; +@@ -1784,7 +1806,12 @@ + fprintf(stderr, "SocketUNIXCreateListener: Unlinking path [%s] for ciptr at [%p].\n", + sockname.sun_path, (void *) ciptr); + #endif +- unlink (sockname.sun_path); ++ if (abstract) { ++ sockname.sun_path[0] = '\0'; ++ namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&sockname.sun_path[1]); ++ } ++ else ++ unlink (sockname.sun_path); + + if ((status = TRANS(SocketCreateListener) (ciptr, + (struct sockaddr *) &sockname, namelen, flags)) < 0) +@@ -1814,6 +1841,9 @@ + 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); +@@ -1823,7 +1853,6 @@ + return 0; + } + +- + static int + TRANS(SocketUNIXResetListener) (XtransConnInfo ciptr) + +@@ -1836,15 +1865,20 @@ + 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)) + #else +- S_IFSOCK)) ++ S_IFSOCK))) + #endif + { + int oldUmask = umask (0); +@@ -2034,6 +2068,11 @@ + } + + ++ /* ++ * 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); + +@@ -2626,6 +2665,12 @@ + struct sockaddr_un sockname; + int namelen; + ++ ++ int abstract = 0; ++#ifdef HAVE_ABSTRACT_SOCKETS ++ abstract = ciptr->transptr->flags & TRANS_ABSTRACT; ++#endif ++ + #if defined(hpux) && defined(X11_t) + struct sockaddr_un old_sockname; + int old_namelen; +@@ -2674,9 +2719,9 @@ + sockname.sun_family = AF_UNIX; + + #ifdef NX_TRANS_SOCKET +- if (set_sun_path(port, _NXGetUnixPath(UNIX_PATH), sockname.sun_path) != 0) { ++ if (set_sun_path(port, _NXGetUnixPath(UNIX_PATH), sockname.sun_path, abstract) != 0) { + #else +- if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) { ++ if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { + #endif + PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); + return TRANS_CONNECT_FAILED; +@@ -2722,6 +2767,14 @@ + #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'; ++ ++ /* + * Do the connect() + */ + +@@ -2757,12 +2810,18 @@ + * 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 || olderrno == ECONNREFUSED) ++ /* If opening as abstract failed, try again normally */ ++ if (abstract) { ++ ciptr->transptr->flags &= ~(TRANS_ABSTRACT); ++ return TRANS_TRY_CONNECT_AGAIN; ++ } else { ++ return TRANS_CONNECT_FAILED; ++ } else { + PRMSG (2,"SocketUNIXConnect: Can't connect: errno = %d\n", + EGET(),0, 0); + +@@ -2791,6 +2850,9 @@ + return TRANS_CONNECT_FAILED; + } + ++ if (abstract) ++ sockname.sun_path[0] = '@'; ++ + ciptr->family = AF_UNIX; + ciptr->addrlen = namelen; + ciptr->peeraddrlen = namelen; +@@ -3323,7 +3385,11 @@ + Xtransport TRANS(SocketLocalFuncs) = { + /* Socket Interface */ + "local", ++#ifdef HAVE_ABSTRACT_SOCKETS ++ TRANS_ABSTRACT, ++#else + 0, ++#endif + #ifdef TRANS_CLIENT + TRANS(SocketOpenCOTSClient), + #endif /* TRANS_CLIENT */ +@@ -3369,7 +3435,7 @@ + Xtransport TRANS(SocketUNIXFuncs) = { + /* Socket Interface */ + "unix", +-#if !defined(LOCALCONN) ++#if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS) + TRANS_ALIAS, + #else + 0, +--- a/nx-X11/lib/xtrans/Xtransint.h ++++ b/nx-X11/lib/xtrans/Xtransint.h +@@ -374,9 +374,10 @@ + #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 --git a/debian/patches/series b/debian/patches/series index fdb76702d..414b28589 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -23,6 +23,7 @@ 026_nxcomp_honour-optflags.full+lite.patch 026_nxcompshad_honour-optflags.full.patch 027_nxcomp_abstract-X11-socket.full+lite.patch +028_nx-X11_abstract-kernel-sockets.full.patch 030_nx-X11_configure-args.full.patch 031_nx-X11_parallel-make.full.patch 051_nxcomp_macos105-fdisset.full+lite.patch -- cgit v1.2.3