diff options
author | Ulrich Sibiller <uli42@gmx.de> | 2016-10-31 02:29:18 +0100 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2016-11-02 19:46:36 +0100 |
commit | e65b106a8989bf5d71de613f5f8b9dcbd559d382 (patch) | |
tree | bdd95de44084c0460bef9c90bcfb82736e3ff834 /nx-X11/lib/xtrans/Xtranssock.c | |
parent | 793d587b46a7ec47ea62d99920de4dc607514604 (diff) | |
download | nx-libs-e65b106a8989bf5d71de613f5f8b9dcbd559d382.tar.gz nx-libs-e65b106a8989bf5d71de613f5f8b9dcbd559d382.tar.bz2 nx-libs-e65b106a8989bf5d71de613f5f8b9dcbd559d382.zip |
Xtrans: update to Xorg/xtrans upstream (1.3.5+)
This lifts xtrans to the state of this commit:
commit 560d7550e23e9b14056b4a9b2569c2f256015f8a
Author: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
Date: Sat Sep 10 22:09:51 2016 -0700
Update strlcpy macro check to also check HAVE_STRLCPY
xorg-server moved from HAS_STRLCPY to HAVE_STRLCPY in 2011
cf-xserver: d829a7c5cb42c979b58f3547136df5b05d906423
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
Diffstat (limited to 'nx-X11/lib/xtrans/Xtranssock.c')
-rw-r--r-- | nx-X11/lib/xtrans/Xtranssock.c | 826 |
1 files changed, 602 insertions, 224 deletions
diff --git a/nx-X11/lib/xtrans/Xtranssock.c b/nx-X11/lib/xtrans/Xtranssock.c index ccfa0e13b..95db315f3 100644 --- a/nx-X11/lib/xtrans/Xtranssock.c +++ b/nx-X11/lib/xtrans/Xtranssock.c @@ -132,12 +132,9 @@ from the copyright holders. #include <sys/stat.h> #endif -#if defined(MOTOROLA) && defined(SYSV) -#define NO_TCP_H -#endif #ifndef NO_TCP_H -#if defined(__osf__) || defined(linux) || defined(__GLIBC__) || defined(AIXV5) +#if defined(linux) || defined(__GLIBC__) #include <sys/param.h> #endif /* osf */ #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) @@ -148,18 +145,10 @@ from the copyright holders. #endif /* !NO_TCP_H */ #include <sys/ioctl.h> -#if defined(SVR4) && !defined(DGUX) && !defined(_SEQUENT_) +#if defined(SVR4) || defined(__SVR4) #include <sys/filio.h> #endif -#if (defined(__i386__) && defined(SYSV)) && !defined(SCO325) && !defined(sun) -#include <net/errno.h> -#endif - -#if (defined(__i386__) && defined(SYSV)) && (!defined(ISC) || !defined(I_NREAD) || defined(SCO325)) || defined(_SEQUENT_) -#include <sys/stropts.h> -#endif - #include <unistd.h> #else /* !WIN32 */ @@ -189,7 +178,7 @@ from the copyright holders. /* others don't need this */ #define SocketInitOnce() /**/ -#if defined(linux) +#ifdef linux #define HAVE_ABSTRACT_SOCKETS #endif @@ -212,7 +201,7 @@ from the copyright holders. */ typedef struct _Sockettrans2dev { - char *transname; + const char *transname; int family; int devcotsname; int devcltsname; @@ -263,14 +252,6 @@ static int TRANS(SocketINETClose) (XtransConnInfo ciptr); #define UNIX_PATH "/tmp/.ICE-unix/" #define UNIX_DIR "/tmp/.ICE-unix" #endif /* ICE_t */ -#if defined(TEST_t) -#define UNIX_PATH "/tmp/.Test-unix/test" -#define UNIX_DIR "/tmp/.Test-unix" -#endif -#if defined(LBXPROXY_t) -#define UNIX_PATH "/tmp/.X11-unix/X" -#define UNIX_DIR "/tmp/.X11-unix" -#endif #endif /* UNIXCONN */ @@ -281,17 +262,12 @@ static int TRANS(SocketINETClose) (XtransConnInfo ciptr); #define MAXHOSTNAMELEN 255 #endif -/* - * This provides compatibility for apps linked against system libraries - * that don't have IPv6 support. - */ -#if defined(IPv6) && defined(AF_INET6) -static const struct in6_addr local_in6addr_any = IN6ADDR_ANY_INIT; -#pragma weak in6addr_any = local_in6addr_any -#ifndef __USLC__ -#pragma weak getaddrinfo -#endif -static int haveIPv6 = 1; +#if defined HAVE_SOCKLEN_T || (defined(IPv6) && defined(AF_INET6)) +# define SOCKLEN_T socklen_t +#elif defined(SVR4) || defined(__SVR4) || defined(__SCO__) +# define SOCKLEN_T size_t +#else +# define SOCKLEN_T int #endif #ifndef X11_t @@ -307,6 +283,10 @@ static int haveIPv6 = 1; #ifdef NX_TRANS_SOCKET +#ifdef XTRANS_SEND_FDS + #error XTRANS_SEND_FDS is unsupported for NX! +#endif + #ifdef TRANS_CLIENT #include <nx/NX.h> @@ -686,7 +666,7 @@ int TRANS(SocketCongestionChange) (XtransConnInfo ciptr, int *state) */ static int -TRANS(SocketSelectFamily) (int first, char *family) +TRANS(SocketSelectFamily) (int first, const char *family) { int i; @@ -714,34 +694,26 @@ TRANS(SocketINETGetAddr) (XtransConnInfo ciptr) { #if defined(IPv6) && defined(AF_INET6) struct sockaddr_storage socknamev6; -#endif - struct sockaddr_in socknamev4; - void *socknamePtr; -#if defined(SVR4) || defined(__SCO__) -# define SOCKLEN_T_PTR void* - size_t namelen; #else -# define SOCKLEN_T_PTR socklen_t* - socklen_t namelen; + struct sockaddr_in socknamev4; #endif + void *socknamePtr; + SOCKLEN_T namelen; prmsg (3,"SocketINETGetAddr(%p)\n", ciptr); #if defined(IPv6) && defined(AF_INET6) - if (haveIPv6) - { namelen = sizeof(socknamev6); socknamePtr = &socknamev6; - } - else -#endif - { +#else namelen = sizeof(socknamev4); socknamePtr = &socknamev4; - } +#endif + + bzero(socknamePtr, namelen); if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr, - (SOCKLEN_T_PTR)&namelen) < 0) + (void *)&namelen) < 0) { #ifdef WIN32 errno = WSAGetLastError(); @@ -755,7 +727,7 @@ TRANS(SocketINETGetAddr) (XtransConnInfo ciptr) * Everything looks good: fill in the XtransConnInfo structure. */ - if ((ciptr->addr = (char *) malloc (namelen)) == NULL) + if ((ciptr->addr = malloc (namelen)) == NULL) { prmsg (1, "SocketINETGetAddr: Can't allocate space for the addr\n"); @@ -763,15 +735,10 @@ TRANS(SocketINETGetAddr) (XtransConnInfo ciptr) } #if defined(IPv6) && defined(AF_INET6) - if (haveIPv6) - { ciptr->family = ((struct sockaddr *)socknamePtr)->sa_family; - } - else -#endif - { +#else ciptr->family = socknamev4.sin_family; - } +#endif ciptr->addrlen = namelen; memcpy (ciptr->addr, socknamePtr, ciptr->addrlen); @@ -793,14 +760,10 @@ TRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr) #endif struct sockaddr_in socknamev4; void *socknamePtr; -#if defined(SVR4) || defined(__SCO__) - size_t namelen; -#else - int namelen; -#endif + SOCKLEN_T namelen; #if defined(IPv6) && defined(AF_INET6) - if (haveIPv6 && ciptr->family == AF_INET6) + if (ciptr->family == AF_INET6) { namelen = sizeof(socknamev6); socknamePtr = &socknamev6; @@ -812,6 +775,8 @@ TRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr) socknamePtr = &socknamev4; } + bzero(socknamePtr, namelen); + prmsg (3,"SocketINETGetPeerAddr(%p)\n", ciptr); if (getpeername (ciptr->fd, (struct sockaddr *) socknamePtr, @@ -829,7 +794,7 @@ TRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr) * Everything looks good: fill in the XtransConnInfo structure. */ - if ((ciptr->peeraddr = (char *) malloc (namelen)) == NULL) + if ((ciptr->peeraddr = malloc (namelen)) == NULL) { prmsg (1, "SocketINETGetPeerAddr: Can't allocate space for the addr\n"); @@ -851,16 +816,7 @@ TRANS(SocketOpen) (int i, int type) prmsg (3,"SocketOpen(%d,%d)\n", i, type); -#if defined(IPv6) && defined(AF_INET6) - if (getaddrinfo == NULL) - haveIPv6 = 0; - - if (!haveIPv6 && Sockettrans2devtab[i].family == AF_INET6) - return NULL; -#endif - - if ((ciptr = (XtransConnInfo) calloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) + if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) { prmsg (1, "SocketOpen: malloc failed\n"); return NULL; @@ -880,7 +836,7 @@ TRANS(SocketOpen) (int i, int type) prmsg (2, "SocketOpen: socket() failed for %s\n", Sockettrans2devtab[i].transname); - free ((char *) ciptr); + free (ciptr); return NULL; } @@ -901,6 +857,27 @@ TRANS(SocketOpen) (int i, int type) } #endif + /* + * Some systems provide a really small default buffer size for + * UNIX sockets. Bump it up a bit such that large transfers don't + * proceed at glacial speed. + */ +#ifdef SO_SNDBUF + if (Sockettrans2devtab[i].family == AF_UNIX) + { + SOCKLEN_T len = sizeof (int); + int val; + + if (getsockopt (ciptr->fd, SOL_SOCKET, SO_SNDBUF, + (char *) &val, &len) == 0 && val < 64 * 1024) + { + val = 64 * 1024; + setsockopt (ciptr->fd, SOL_SOCKET, SO_SNDBUF, + (char *) &val, sizeof (int)); + } + } +#endif + return ciptr; } @@ -908,22 +885,82 @@ TRANS(SocketOpen) (int i, int type) #ifdef TRANS_REOPEN static XtransConnInfo -TRANS(SocketReopen) (int i, int type, int fd, char *port) +TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, const char *port) { XtransConnInfo ciptr; + int portlen; + struct sockaddr *addr; + size_t addrlen; prmsg (3,"SocketReopen(%d,%d,%s)\n", type, fd, port); - if ((ciptr = (XtransConnInfo) calloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) + if (port == NULL) { + prmsg (1, "SocketReopen: port was null!\n"); + return NULL; + } + + portlen = strlen(port) + 1; // include space for trailing null +#ifdef SOCK_MAXADDRLEN + if (portlen < 0 || portlen > (SOCK_MAXADDRLEN + 2)) { + prmsg (1, "SocketReopen: invalid portlen %d\n", portlen); + return NULL; + } + if (portlen < 14) portlen = 14; +#else + if (portlen < 0 || portlen > 14) { + prmsg (1, "SocketReopen: invalid portlen %d\n", portlen); + return NULL; + } +#endif /*SOCK_MAXADDRLEN*/ + + if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) { - prmsg (1, "SocketReopen: malloc failed\n"); + prmsg (1, "SocketReopen: malloc(ciptr) failed\n"); return NULL; } ciptr->fd = fd; + addrlen = portlen + offsetof(struct sockaddr, sa_data); + if ((addr = calloc (1, addrlen)) == NULL) { + prmsg (1, "SocketReopen: malloc(addr) failed\n"); + free (ciptr); + return NULL; + } + ciptr->addr = (char *) addr; + ciptr->addrlen = addrlen; + + if ((ciptr->peeraddr = calloc (1, addrlen)) == NULL) { + prmsg (1, "SocketReopen: malloc(portaddr) failed\n"); + free (addr); + free (ciptr); + return NULL; + } + ciptr->peeraddrlen = addrlen; + + /* Initialize ciptr structure as if it were a normally-opened unix socket */ + ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK; +#ifdef BSD44SOCKETS + addr->sa_len = addrlen; +#endif + addr->sa_family = AF_UNIX; +#if defined(HAVE_STRLCPY) || defined(HAS_STRLCPY) + strlcpy(addr->sa_data, port, portlen); +#else + strncpy(addr->sa_data, port, portlen); +#endif + ciptr->family = AF_UNIX; + memcpy(ciptr->peeraddr, ciptr->addr, addrlen); + ciptr->port = rindex(addr->sa_data, ':'); + if (ciptr->port == NULL) { + if (is_numeric(addr->sa_data)) { + ciptr->port = addr->sa_data; + } + } else if (ciptr->port[0] == ':') { + ciptr->port++; + } + /* port should now point to portnum or NULL */ return ciptr; } @@ -937,8 +974,8 @@ TRANS(SocketReopen) (int i, int type, int fd, char *port) #ifdef TRANS_CLIENT static XtransConnInfo -TRANS(SocketOpenCOTSClientBase) (char *transname, char *protocol, - char *host, char *port, int previndex) +TRANS(SocketOpenCOTSClientBase) (const char *transname, const char *protocol, + const char *host, const char *port, int previndex) { XtransConnInfo ciptr; int i = previndex; @@ -973,7 +1010,10 @@ TRANS(SocketOpenCOTSClientBase) (char *transname, char *protocol, #endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ if ((ciptr = TRANS(SocketOpen) ( - i, Sockettrans2devtab[i].devcotsname)) != NULL) + i, Sockettrans2devtab[i].devcotsname)) != NULL) { + /* Save the index for later use */ + + ciptr->index = i; break; } } @@ -993,16 +1033,12 @@ TRANS(SocketOpenCOTSClientBase) (char *transname, char *protocol, #endif - /* Save the index for later use */ - - ciptr->index = i; - return ciptr; } static XtransConnInfo -TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, char *protocol, - char *host, char *port) +TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, const char *protocol, + const char *host, const char *port) { return TRANS(SocketOpenCOTSClientBase)( thistrans->TransName, protocol, host, port, -1); @@ -1015,8 +1051,8 @@ TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, char *protocol, #ifdef TRANS_SERVER static XtransConnInfo -TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, char *protocol, - char *host, char *port) +TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, const char *protocol, + const char *host, const char *port) { XtransConnInfo ciptr; @@ -1082,7 +1118,7 @@ TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, char *protocol, #ifdef TRANS_REOPEN static XtransConnInfo -TRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, char *port) +TRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, const char *port) { XtransConnInfo ciptr; @@ -1168,7 +1204,7 @@ TRANS(SocketCreateListener) (XtransConnInfo ciptr, int socknamelen, unsigned int flags) { - int namelen = socknamelen; + SOCKLEN_T namelen = socknamelen; int fd = ciptr->fd; int retry; @@ -1248,7 +1284,8 @@ TRANS(SocketCreateListener) (XtransConnInfo ciptr, #ifdef TCPCONN static int -TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags) +TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, const char *port, + unsigned int flags) { #if defined(IPv6) && defined(AF_INET6) @@ -1257,7 +1294,7 @@ TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int struct sockaddr_in sockname; #endif unsigned short sport; - int namelen = sizeof(sockname); + SOCKLEN_T namelen = sizeof(sockname); int status; long tmpport; #ifdef XTHREADS_NEEDS_BYNAMEPARAMS @@ -1285,7 +1322,7 @@ TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int { /* fixup the server port address */ tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); - sprintf (portbuf,"%lu", tmpport); + snprintf (portbuf, sizeof(portbuf), "%lu", tmpport); port = portbuf; } #endif @@ -1370,13 +1407,13 @@ TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int return 0; } -#endif /* SOCKCONN */ +#endif /* TCPCONN */ #ifdef UNIXCONN static int -TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, char *port, +TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, const char *port, unsigned int flags) { @@ -1426,28 +1463,23 @@ TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, char *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, abstract) != 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, abstract) != 0) { #endif prmsg (1, "SocketUNIXCreateListener: path too long\n"); return TRANS_CREATE_LISTENER_FAILED; } - } else { -#ifdef NX_TRANS_SOCKET - sprintf (sockname.sun_path, "%s%ld", _NXGetUnixPath(UNIX_PATH), (long)getpid()); -#else - sprintf (sockname.sun_path, "%s%ld", UNIX_PATH, (long)getpid()); -#endif - } #if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) sockname.sun_len = strlen(sockname.sun_path); +#endif + +#if defined(BSD44SOCKETS) || defined(SUN_LEN) namelen = SUN_LEN(&sockname); #else - namelen = strlen(sockname.sun_path) + sizeof(sockname.sun_family); + namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); #endif #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) @@ -1479,7 +1511,7 @@ TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, char *port, namelen = sizeof (sockname); /* this will always make it the same size */ - if ((ciptr->addr = (char *) malloc (namelen)) == NULL) + if ((ciptr->addr = malloc (namelen)) == NULL) { prmsg (1, "SocketUNIXCreateListener: Can't allocate space for the addr\n"); @@ -1522,11 +1554,12 @@ TRANS(SocketUNIXResetListener) (XtransConnInfo ciptr) 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)) +#if defined(NCR) || defined(SCO325) || !defined(S_IFSOCK) + S_IFIFO #else - S_IFSOCK))) + S_IFSOCK #endif + ))) { int oldUmask = umask (0); @@ -1594,12 +1627,11 @@ TRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status) { XtransConnInfo newciptr; struct sockaddr_in sockname; - int namelen = sizeof(sockname); + SOCKLEN_T namelen = sizeof(sockname); prmsg (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd); - if ((newciptr = (XtransConnInfo) calloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) + if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) { prmsg (1, "SocketINETAccept: malloc failed\n"); *status = TRANS_ACCEPT_BAD_MALLOC; @@ -1671,16 +1703,11 @@ TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) { XtransConnInfo newciptr; struct sockaddr_un sockname; -#if defined(SVR4) || defined(__SCO__) - size_t namelen = sizeof sockname; -#else - int namelen = sizeof sockname; -#endif + SOCKLEN_T namelen = sizeof sockname; prmsg (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd); - if ((newciptr = (XtransConnInfo) calloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) + if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) { prmsg (1, "SocketUNIXAccept: malloc() failed\n"); *status = TRANS_ACCEPT_BAD_MALLOC; @@ -1696,12 +1723,13 @@ TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) return NULL; } + ciptr->addrlen = namelen; /* * Get the socket name and the peer name from the listener socket, * since this is unix domain. */ - if ((newciptr->addr = (char *) malloc (ciptr->addrlen)) == NULL) + if ((newciptr->addr = malloc (ciptr->addrlen)) == NULL) { prmsg (1, "SocketUNIXAccept: Can't allocate space for the addr\n"); @@ -1719,7 +1747,7 @@ TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) newciptr->addrlen = ciptr->addrlen; memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen); - if ((newciptr->peeraddr = (char *) malloc (ciptr->addrlen)) == NULL) + if ((newciptr->peeraddr = malloc (ciptr->addrlen)) == NULL) { prmsg (1, "SocketUNIXAccept: Can't allocate space for the addr\n"); @@ -1761,7 +1789,8 @@ static struct addrlist *addrlist = NULL; static int -TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) +TRANS(SocketINETConnect) (XtransConnInfo ciptr, + const char *host, const char *port) { struct sockaddr * socketaddr = NULL; @@ -1771,20 +1800,20 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) struct addrinfo hints; char ntopbuf[INET6_ADDRSTRLEN]; int resetonce = 0; -#endif +#else struct sockaddr_in sockname; + struct hostent *hostp; + struct servent *servp; + unsigned long tmpaddr; +#endif #ifdef XTHREADS_NEEDS_BYNAMEPARAMS _Xgethostbynameparams hparams; _Xgetservbynameparams sparams; #endif - struct hostent *hostp; - struct servent *servp; - unsigned long tmpaddr; #ifdef X11_t char portbuf[PORTBUFSIZE]; #endif - long tmpport; char hostnamebuf[256]; /* tmp space */ prmsg (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port); @@ -1808,14 +1837,14 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) if (is_numeric (port)) { - tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); - sprintf (portbuf, "%lu", tmpport); + long tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); + snprintf (portbuf, sizeof(portbuf), "%lu", tmpport); port = portbuf; } #endif #if defined(IPv6) && defined(AF_INET6) - if (haveIPv6) { + { if (addrlist != NULL) { if (strcmp(host,addrlist->host) || strcmp(port,addrlist->port)) { if (addrlist->firstaddr) @@ -1954,8 +1983,8 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) addrlist->addr = addrlist->addr->ai_next; } } - } else -#endif + } +#else { /* * Build the socket name. @@ -2018,7 +2047,7 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) } sockname.sin_port = htons (servp->s_port); } else { - tmpport = strtol (port, (char**)NULL, 10); + long tmpport = strtol (port, (char**)NULL, 10); if (tmpport < 1024 || tmpport > USHRT_MAX) return TRANS_CONNECT_FAILED; sockname.sin_port = htons (((unsigned short) tmpport)); @@ -2029,6 +2058,7 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) socketaddr = (struct sockaddr *) &sockname; socketaddrlen = sizeof(sockname); } +#endif /* * Turn on socket keepalive so the client process will eventually @@ -2079,7 +2109,7 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) if (olderrno == ECONNREFUSED || olderrno == EINTR #if defined(IPv6) && defined(AF_INET6) - || (haveIPv6 && ((addrlist->addr->ai_next != NULL) || + || (((addrlist->addr->ai_next != NULL) || (addrlist->addr != addrlist->firstaddr)) && (olderrno == ENETUNREACH || olderrno == EAFNOSUPPORT || olderrno == EADDRNOTAVAIL || olderrno == ETIMEDOUT @@ -2123,7 +2153,7 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) } #if defined(IPv6) && defined(AF_INET6) - if (haveIPv6 && res != 0) { + if (res != 0) { addrlist->addr = addrlist->addr->ai_next; } #endif @@ -2142,25 +2172,18 @@ TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) */ static int -UnixHostReallyLocal (char *host) +UnixHostReallyLocal (const char *host) { char hostnamebuf[256]; -#if defined(IPv6) && defined(AF_INET6) - if (getaddrinfo == NULL) - haveIPv6 = 0; -#endif - TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf)); if (strcmp (hostnamebuf, host) == 0) { return (1); - } + } else { #if defined(IPv6) && defined(AF_INET6) - else if (haveIPv6) - { struct addrinfo *localhostaddr; struct addrinfo *otherhostaddr; struct addrinfo *i, *j; @@ -2206,10 +2229,7 @@ UnixHostReallyLocal (char *host) freeaddrinfo(localhostaddr); freeaddrinfo(otherhostaddr); return equiv; - } -#endif - else - { +#else /* * A host may have more than one network address. If any of the * network addresses of 'host' (specified to the connect call) @@ -2278,15 +2298,17 @@ UnixHostReallyLocal (char *host) i++; } return (equiv); +#endif } } static int -TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) +TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, + const char *host, const char *port) { struct sockaddr_un sockname; - int namelen; + SOCKLEN_T namelen; int abstract = 0; @@ -2305,10 +2327,10 @@ TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) */ #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) - if (strcmp(host, "unix") != 0 && strcasecmp(host, "nx") != 0 && + if (host && *host && host[0]!='/' && strcmp(host, "unix") != 0 && strcasecmp(host, "nx") != 0 && strncasecmp(host, "nx,", 3) != 0 && !UnixHostReallyLocal (host)) #else - if (strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host)) + if (host && *host && host[0]!='/' && strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host)) #endif { prmsg (1, @@ -2345,9 +2367,12 @@ TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) #if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) sockname.sun_len = strlen (sockname.sun_path); +#endif + +#if defined(BSD44SOCKETS) || defined(SUN_LEN) namelen = SUN_LEN (&sockname); #else - namelen = strlen (sockname.sun_path) + sizeof (sockname.sun_family); + namelen = strlen (sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); #endif @@ -2371,8 +2396,9 @@ TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) * Done here because otherwise all the strlen() calls above would fail. */ - if (abstract) + if (abstract) { sockname.sun_path[0] = '\0'; + } /* * Do the connect() @@ -2388,8 +2414,13 @@ TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) errno = olderrno; /* - * If the error was ENOENT, the server may be starting up - * and we should try again. + * If the error was ENOENT, the server may be starting up; we used + * to suggest to try again in this case with + * TRANS_TRY_CONNECT_AGAIN, but this introduced problems for + * processes still referencing stale sockets in their environment. + * Hence, we now return a hard error, TRANS_CONNECT_FAILED, and it + * is suggested that higher level stacks handle retries on their + * level when they face a slow starting server. * * If the error was EWOULDBLOCK or EINPROGRESS then the socket * was non-blocking and we should poll using select @@ -2402,13 +2433,14 @@ TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) return TRANS_IN_PROGRESS; else if (olderrno == EINTR) return TRANS_TRY_CONNECT_AGAIN; - else if (olderrno == ENOENT || olderrno == ECONNREFUSED) - /* If opening as abstract failed, try again normally */ + else if (olderrno == ENOENT || olderrno == ECONNREFUSED) { + /* If opening as abstract socket 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()); @@ -2429,8 +2461,8 @@ SocketUNIXConnectPost: * since this is unix domain. */ - if ((ciptr->addr = (char *) malloc(namelen)) == NULL || - (ciptr->peeraddr = (char *) malloc(namelen)) == NULL) + if ((ciptr->addr = malloc(namelen)) == NULL || + (ciptr->peeraddr = malloc(namelen)) == NULL) { prmsg (1, "SocketUNIXCreateListener: Can't allocate space for the addr\n"); @@ -2512,24 +2544,123 @@ TRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) #endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ -#if defined(QNX4) - *pend = 0L; /* FIONREAD only returns a short. Zero out upper bits */ -#endif #ifdef WIN32 { int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend); - errno = WSAGetLastError(); + if (ret == SOCKET_ERROR) errno = WSAGetLastError(); return ret; } #else -#if (defined(__i386__) && defined(SYSV) && !defined(SCO325)) || (defined(_SEQUENT_) && _SOCKET_VERSION == 1) - return ioctl (ciptr->fd, I_NREAD, (char *) pend); -#else return ioctl (ciptr->fd, FIONREAD, (char *) pend); -#endif /* __i386__ && SYSV || _SEQUENT_ && _SOCKET_VERSION == 1 */ #endif /* WIN32 */ } +#if XTRANS_SEND_FDS + +static void +appendFd(struct _XtransConnFd **prev, int fd, int do_close) +{ + struct _XtransConnFd *cf, *new; + + new = malloc (sizeof (struct _XtransConnFd)); + if (!new) { + /* XXX mark connection as broken */ + close(fd); + return; + } + new->next = 0; + new->fd = fd; + new->do_close = do_close; + /* search to end of list */ + for (; (cf = *prev); prev = &(cf->next)); + *prev = new; +} + +static int +removeFd(struct _XtransConnFd **prev) +{ + struct _XtransConnFd *cf; + int fd; + + if ((cf = *prev)) { + *prev = cf->next; + fd = cf->fd; + free(cf); + } else + fd = -1; + return fd; +} + +static void +discardFd(struct _XtransConnFd **prev, struct _XtransConnFd *upto, int do_close) +{ + struct _XtransConnFd *cf, *next; + + for (cf = *prev; cf != upto; cf = next) { + next = cf->next; + if (do_close || cf->do_close) + close(cf->fd); + free(cf); + } + *prev = upto; +} + +static void +cleanupFds(XtransConnInfo ciptr) +{ + /* Clean up the send list but don't close the fds */ + discardFd(&ciptr->send_fds, NULL, 0); + /* Clean up the recv list and *do* close the fds */ + discardFd(&ciptr->recv_fds, NULL, 1); +} + +static int +nFd(struct _XtransConnFd **prev) +{ + struct _XtransConnFd *cf; + int n = 0; + + for (cf = *prev; cf; cf = cf->next) + n++; + return n; +} + +static int +TRANS(SocketRecvFd) (XtransConnInfo ciptr) +{ + prmsg (2, "SocketRecvFd(%d)\n", ciptr->fd); + return removeFd(&ciptr->recv_fds); +} + +static int +TRANS(SocketSendFd) (XtransConnInfo ciptr, int fd, int do_close) +{ + appendFd(&ciptr->send_fds, fd, do_close); + return 0; +} + +static int +TRANS(SocketRecvFdInvalid)(XtransConnInfo ciptr) +{ + errno = EINVAL; + return -1; +} + +static int +TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close) +{ + errno = EINVAL; + return -1; +} + +#define MAX_FDS 128 + +union fd_pass { + struct cmsghdr cmsghdr; + char buf[CMSG_SPACE(MAX_FDS * sizeof(int))]; +}; + +#endif /* XTRANS_SEND_FDS */ static int TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) @@ -2567,7 +2698,41 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) } else { + /* FIXME: same code as below, should be possible without duplication */ +#if XTRANS_SEND_FDS + struct iovec iov = { + .iov_base = buf, + .iov_len = size + }; + union fd_pass cmsgbuf; + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = cmsgbuf.buf, + .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int)) + }; + + size = recvmsg(ciptr->fd, &msg, 0); + if (size >= 0) { + struct cmsghdr *hdr; + + for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) { + if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) { + int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int); + int i; + int *fd = (int *) CMSG_DATA(hdr); + + for (i = 0; i < nfd; i++) + appendFd(&ciptr->recv_fds, fd[i], 0); + } + } + } + return size; +#else return read (ciptr->fd, buf, size); +#endif /* XTRANS_SEND_FDS */ } #else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ @@ -2576,137 +2741,323 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) { int ret = recv ((SOCKET)ciptr->fd, buf, size, 0); #ifdef WIN32 - errno = WSAGetLastError(); + if (ret == SOCKET_ERROR) errno = WSAGetLastError(); #endif return ret; } #else +#if XTRANS_SEND_FDS + { + struct iovec iov = { + .iov_base = buf, + .iov_len = size + }; + union fd_pass cmsgbuf; + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = cmsgbuf.buf, + .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int)) + }; + + size = recvmsg(ciptr->fd, &msg, 0); + if (size >= 0) { + struct cmsghdr *hdr; + + for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) { + if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) { + int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int); + int i; + int *fd = (int *) CMSG_DATA(hdr); + + for (i = 0; i < nfd; i++) + appendFd(&ciptr->recv_fds, fd[i], 0); + } + } + } + return size; + } +#else return read (ciptr->fd, buf, size); +#endif /* XTRANS_SEND_FDS */ #endif /* WIN32 */ #endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ } - static int -TRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size) +TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) { - prmsg (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size); + prmsg (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size); #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) /* * If we have a valid priv pointer then this * is an internal connection to the proxy. - * In this case we should emulate the write. + * In this case we should emulate the readv. */ if (ciptr->priv) { - int result; - - result = NXTransWrite(ciptr->fd, buf, size); - -#ifdef NX_TRANS_DEBUG - if (result < 0 && EGET() == EAGAIN) - { - fprintf(stderr, "SocketWrite: Write on descriptor [%d] would block.\n", - ciptr->fd); - } - else - { - fprintf(stderr, "SocketWrite: Written [%d] bytes on descriptor [%d].\n", - result, ciptr->fd); - } -#endif - return result; + return NXTransReadVector(ciptr->fd, buf, size); } else { - return write (ciptr->fd, buf, size); + /* FIXME: same code as below, should be possible without duplication */ +#if XTRANS_SEND_FDS + union fd_pass cmsgbuf; + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = buf, + .msg_iovlen = size, + .msg_control = cmsgbuf.buf, + .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int)) + }; + + size = recvmsg(ciptr->fd, &msg, 0); + if (size >= 0) { + struct cmsghdr *hdr; + + for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) { + if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) { + int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int); + int i; + int *fd = (int *) CMSG_DATA(hdr); + + for (i = 0; i < nfd; i++) + appendFd(&ciptr->recv_fds, fd[i], 0); + } + } + } + return size; +#else + return READV (ciptr, buf, size); +#endif } #else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ -#if defined(WIN32) - { - int ret = send ((SOCKET)ciptr->fd, buf, size, 0); -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - return ret; +#if XTRANS_SEND_FDS + { + union fd_pass cmsgbuf; + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = buf, + .msg_iovlen = size, + .msg_control = cmsgbuf.buf, + .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int)) + }; + + size = recvmsg(ciptr->fd, &msg, 0); + if (size >= 0) { + struct cmsghdr *hdr; + + for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) { + if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) { + int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int); + int i; + int *fd = (int *) CMSG_DATA(hdr); + + for (i = 0; i < nfd; i++) + appendFd(&ciptr->recv_fds, fd[i], 0); + } + } + } + return size; } #else - return write (ciptr->fd, buf, size); -#endif /* WIN32 */ + return READV (ciptr, buf, size); +#endif #endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ } static int -TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) +TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) { - prmsg (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size); + prmsg (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size); #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) /* * If we have a valid priv pointer then this * is an internal connection to the proxy. - * In this case we should emulate the readv. + * In this case we should emulate the writev. */ if (ciptr->priv) { - return NXTransReadVector(ciptr->fd, buf, size); + return NXTransWriteVector(ciptr->fd, buf, size); } else { - return READV (ciptr, buf, size); + /* FIXME: same code as below, should be possible without duplication */ +#if XTRANS_SEND_FDS + if (ciptr->send_fds) + { + union fd_pass cmsgbuf; + int nfd = nFd(&ciptr->send_fds); + struct _XtransConnFd *cf = ciptr->send_fds; + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = buf, + .msg_iovlen = size, + .msg_control = cmsgbuf.buf, + .msg_controllen = CMSG_LEN(nfd * sizeof(int)) + }; + struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); + int i; + int *fds; + + hdr->cmsg_len = msg.msg_controllen; + hdr->cmsg_level = SOL_SOCKET; + hdr->cmsg_type = SCM_RIGHTS; + + fds = (int *) CMSG_DATA(hdr); + /* Set up fds */ + for (i = 0; i < nfd; i++) { + fds[i] = cf->fd; + cf = cf->next; + } + + i = sendmsg(ciptr->fd, &msg, 0); + if (i > 0) + discardFd(&ciptr->send_fds, cf, 0); + return i; + } +#endif + return WRITEV (ciptr, buf, size); } #else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ - return READV (ciptr, buf, size); +#if XTRANS_SEND_FDS + if (ciptr->send_fds) + { + union fd_pass cmsgbuf; + int nfd = nFd(&ciptr->send_fds); + struct _XtransConnFd *cf = ciptr->send_fds; + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = buf, + .msg_iovlen = size, + .msg_control = cmsgbuf.buf, + .msg_controllen = CMSG_LEN(nfd * sizeof(int)) + }; + struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); + int i; + int *fds; + + hdr->cmsg_len = msg.msg_controllen; + hdr->cmsg_level = SOL_SOCKET; + hdr->cmsg_type = SCM_RIGHTS; + + fds = (int *) CMSG_DATA(hdr); + /* Set up fds */ + for (i = 0; i < nfd; i++) { + fds[i] = cf->fd; + cf = cf->next; + } + + i = sendmsg(ciptr->fd, &msg, 0); + if (i > 0) + discardFd(&ciptr->send_fds, cf, 0); + return i; + } +#endif + return WRITEV (ciptr, buf, size); #endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ } static int -TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) +TRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size) { - prmsg (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size); + prmsg (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size); #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) /* * If we have a valid priv pointer then this * is an internal connection to the proxy. - * In this case we should emulate the writev. + * In this case we should emulate the write. */ if (ciptr->priv) { - return NXTransWriteVector(ciptr->fd, buf, size); + int result; + + result = NXTransWrite(ciptr->fd, buf, size); + +#ifdef NX_TRANS_DEBUG + if (result < 0 && EGET() == EAGAIN) + { + fprintf(stderr, "SocketWrite: Write on descriptor [%d] would block.\n", + ciptr->fd); + } + else + { + fprintf(stderr, "SocketWrite: Written [%d] bytes on descriptor [%d].\n", + result, ciptr->fd); + } +#endif + return result; } else { - return WRITEV (ciptr, buf, size); + /* FIXME: same code as below, should be possible without duplication */ +#if XTRANS_SEND_FDS + if (ciptr->send_fds) + { + struct iovec iov; + + iov.iov_base = buf; + iov.iov_len = size; + return TRANS(SocketWritev)(ciptr, &iov, 1); + } +#endif /* XTRANS_SEND_FDS */ + return write (ciptr->fd, buf, size); } #else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ - return WRITEV (ciptr, buf, size); +#if defined(WIN32) + { + int ret = send ((SOCKET)ciptr->fd, buf, size, 0); +#ifdef WIN32 + if (ret == SOCKET_ERROR) errno = WSAGetLastError(); +#endif + return ret; + } +#else +#if XTRANS_SEND_FDS + if (ciptr->send_fds) + { + struct iovec iov; + + iov.iov_base = buf; + iov.iov_len = size; + return TRANS(SocketWritev)(ciptr, &iov, 1); + } +#endif /* XTRANS_SEND_FDS */ + return write (ciptr->fd, buf, size); +#endif /* WIN32 */ #endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */ } - static int TRANS(SocketDisconnect) (XtransConnInfo ciptr) @@ -2716,7 +3067,7 @@ TRANS(SocketDisconnect) (XtransConnInfo ciptr) #ifdef WIN32 { int ret = shutdown (ciptr->fd, 2); - errno = WSAGetLastError(); + if (ret == SOCKET_ERROR) errno = WSAGetLastError(); return ret; } #else @@ -2735,7 +3086,7 @@ TRANS(SocketINETClose) (XtransConnInfo ciptr) #ifdef WIN32 { int ret = close (ciptr->fd); - errno = WSAGetLastError(); + if (ret == SOCKET_ERROR) errno = WSAGetLastError(); return ret; } #else @@ -2769,6 +3120,9 @@ TRANS(SocketUNIXClose) (XtransConnInfo ciptr) #endif +#if XTRANS_SEND_FDS + cleanupFds(ciptr); +#endif ret = close(ciptr->fd); #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) @@ -2783,14 +3137,16 @@ TRANS(SocketUNIXClose) (XtransConnInfo ciptr) && sockname->sun_path[0]) { #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) - if (!(ciptr->flags & TRANS_NOUNLINK)) + if (!(ciptr->flags & TRANS_NOUNLINK + || ciptr->transptr->flags & TRANS_ABSTRACT)) { fprintf(stderr, "SocketUNIXClose: Unlinking path [%s] for ciptr at [%p].\n", sockname->sun_path, (void *) ciptr); unlink (sockname->sun_path); } #else - if (!(ciptr->flags & TRANS_NOUNLINK)) + if (!(ciptr->flags & TRANS_NOUNLINK + || ciptr->transptr->flags & TRANS_ABSTRACT)) unlink (sockname->sun_path); #endif } @@ -2820,6 +3176,9 @@ TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr) #endif +#if XTRANS_SEND_FDS + cleanupFds(ciptr); +#endif ret = close(ciptr->fd); return ret; @@ -2830,7 +3189,7 @@ TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr) #ifdef TCPCONN # ifdef TRANS_SERVER -static char* tcp_nolisten[] = { +static const char* tcp_nolisten[] = { "inet", #if defined(IPv6) && defined(AF_INET6) "inet6", @@ -2867,6 +3226,10 @@ Xtransport TRANS(SocketTCPFuncs) = { TRANS(SocketWrite), TRANS(SocketReadv), TRANS(SocketWritev), +#if XTRANS_SEND_FDS + TRANS(SocketSendFdInvalid), + TRANS(SocketRecvFdInvalid), +#endif TRANS(SocketDisconnect), TRANS(SocketINETClose), TRANS(SocketINETClose), @@ -2900,6 +3263,10 @@ Xtransport TRANS(SocketINETFuncs) = { TRANS(SocketWrite), TRANS(SocketReadv), TRANS(SocketWritev), +#if XTRANS_SEND_FDS + TRANS(SocketSendFdInvalid), + TRANS(SocketRecvFdInvalid), +#endif TRANS(SocketDisconnect), TRANS(SocketINETClose), TRANS(SocketINETClose), @@ -2934,6 +3301,10 @@ Xtransport TRANS(SocketINET6Funcs) = { TRANS(SocketWrite), TRANS(SocketReadv), TRANS(SocketWritev), +#if XTRANS_SEND_FDS + TRANS(SocketSendFdInvalid), + TRANS(SocketRecvFdInvalid), +#endif TRANS(SocketDisconnect), TRANS(SocketINETClose), TRANS(SocketINETClose), @@ -2975,6 +3346,10 @@ Xtransport TRANS(SocketLocalFuncs) = { TRANS(SocketWrite), TRANS(SocketReadv), TRANS(SocketWritev), +#if XTRANS_SEND_FDS + TRANS(SocketSendFd), + TRANS(SocketRecvFd), +#endif TRANS(SocketDisconnect), TRANS(SocketUNIXClose), TRANS(SocketUNIXCloseForCloning), @@ -2982,7 +3357,7 @@ Xtransport TRANS(SocketLocalFuncs) = { #endif /* !LOCALCONN */ # ifdef TRANS_SERVER # if !defined(LOCALCONN) -static char* unix_nolisten[] = { "local" , NULL }; +static const char* unix_nolisten[] = { "local" , NULL }; # endif # endif @@ -3022,6 +3397,10 @@ Xtransport TRANS(SocketUNIXFuncs) = { TRANS(SocketWrite), TRANS(SocketReadv), TRANS(SocketWritev), +#if XTRANS_SEND_FDS + TRANS(SocketSendFd), + TRANS(SocketRecvFd), +#endif TRANS(SocketDisconnect), TRANS(SocketUNIXClose), TRANS(SocketUNIXCloseForCloning), @@ -3029,7 +3408,6 @@ Xtransport TRANS(SocketUNIXFuncs) = { #endif /* UNIXCONN */ - #ifdef NX_TRANS_SOCKET /* * Override the UNIX_DIR and UNIX_PATH settings and |