From 25e59ccc0dc8baf344145d6d739229e8120330db Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Tue, 9 Sep 2008 04:42:36 +0100 Subject: Add support for the abstract socket namespace under Linux Based on same in Xtrans. Signed-off-by: Julien Danjou --- configure.ac | 6 ++++++ src/xcb_util.c | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index c9cbd0c..062c0cb 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,12 @@ AC_HEADER_STDC AC_SEARCH_LIBS(getaddrinfo, socket) AC_SEARCH_LIBS(connect, socket) +case $host_os in +linux*) + AC_DEFINE([HAVE_ABSTRACT_SOCKETS], 1, [Define if your platform supports abstract sockets]) + ;; +esac + dnl check for the sockaddr_un.sun_len member AC_CHECK_MEMBER([struct sockaddr_un.sun_len], [AC_DEFINE(HAVE_SOCKADDR_SUN_LEN,1,[Have the sockaddr_un.sun_len member.])], diff --git a/src/xcb_util.c b/src/xcb_util.c index 6b80c80..7c6a4dd 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -123,6 +124,9 @@ static int _xcb_open_unix(char *protocol, const char *file); #ifdef DNETCONN static int _xcb_open_decnet(const char *host, char *protocol, const unsigned short port); #endif +#ifdef HAVE_ABSTRACT_SOCKETS +static int _xcb_open_abstract(char *protocol, const char *file); +#endif static int _xcb_open(char *host, char *protocol, const int display) { @@ -156,10 +160,13 @@ static int _xcb_open(char *host, char *protocol, const int display) /* display specifies Unix socket */ snprintf(file, sizeof(file), "%s%d", base, display); - return _xcb_open_unix(protocol, file); - +#ifdef HAVE_ABSTRACT_SOCKETS + fd = _xcb_open_abstract(protocol, file); + if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED)) + return fd; - return fd; +#endif + return _xcb_open_unix(protocol, file); } #ifdef DNETCONN @@ -274,6 +281,33 @@ static int _xcb_open_unix(char *protocol, const char *file) return fd; } +#ifdef HAVE_ABSTRACT_SOCKETS +static int _xcb_open_abstract(char *protocol, const char *file) +{ + int fd; + struct sockaddr_un addr = {0}; + socklen_t namelen; + + if (protocol && strcmp("unix",protocol)) + return -1; + + strcpy(addr.sun_path + 1, file); + addr.sun_family = AF_UNIX; + namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(file); +#ifdef HAVE_SOCKADDR_SUN_LEN + addr.sun_len = 1 + strlen(file); +#endif + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) + return -1; + if (connect(fd, (struct sockaddr *) &addr, namelen) == -1) { + close(fd); + return -1; + } + return fd; +} +#endif + xcb_connection_t *xcb_connect(const char *displayname, int *screenp) { int fd, display = 0; -- cgit v1.2.3