aboutsummaryrefslogtreecommitdiff
path: root/debian/patches/0028_nx-X11_abstract-kernel-sockets.full.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0028_nx-X11_abstract-kernel-sockets.full.patch')
-rw-r--r--debian/patches/0028_nx-X11_abstract-kernel-sockets.full.patch321
1 files changed, 321 insertions, 0 deletions
diff --git a/debian/patches/0028_nx-X11_abstract-kernel-sockets.full.patch b/debian/patches/0028_nx-X11_abstract-kernel-sockets.full.patch
new file mode 100644
index 000000000..279f9a9af
--- /dev/null
+++ b/debian/patches/0028_nx-X11_abstract-kernel-sockets.full.patch
@@ -0,0 +1,321 @@
+Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+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;
+@@ -914,9 +920,11 @@
+ struct sockaddr_in socknamev4;
+ void *socknamePtr;
+ #if defined(SVR4) || defined(__SCO__)
++# define SOCKLEN_T_PTR void*
+ size_t namelen;
+ #else
+- int namelen;
++# define SOCKLEN_T_PTR socklen_t*
++ socklen_t namelen;
+ #endif
+
+ PRMSG (3,"SocketINETGetAddr(%p)\n", ciptr, 0, 0);
+@@ -935,7 +943,7 @@
+ }
+
+ if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr,
+- (void *)&namelen) < 0)
++ (SOCKLEN_T_PTR)&namelen) < 0)
+ {
+ #ifdef WIN32
+ errno = WSAGetLastError();
+@@ -1477,23 +1485,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 +1739,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 +1760,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 +1773,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 +1808,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 +1843,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 +1855,6 @@
+ return 0;
+ }
+
+-
+ static int
+ TRANS(SocketUNIXResetListener) (XtransConnInfo ciptr)
+
+@@ -1836,15 +1867,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 +2070,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 +2667,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 +2721,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 +2769,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 +2812,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 +2852,9 @@
+ return TRANS_CONNECT_FAILED;
+ }
+
++ if (abstract)
++ sockname.sun_path[0] = '@';
++
+ ciptr->family = AF_UNIX;
+ ciptr->addrlen = namelen;
+ ciptr->peeraddrlen = namelen;
+@@ -3323,7 +3387,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 +3437,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