From f33105b026cd3c7b64fc5f03ab24b11e3df02a5b Mon Sep 17 00:00:00 2001 From: Daphne Pfister Date: Sun, 8 Sep 2013 19:38:15 -0500 Subject: [PATCH 1/2] Cleanup handling of multiple paths --- src/xcb_util.c | 152 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 56 deletions(-) diff --git a/src/xcb_util.c b/src/xcb_util.c index 463d085..c7dadee 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -78,6 +78,17 @@ int xcb_sumof(uint8_t *list, int len) return s; } +static int _xcb_add_socket_path(const char** socket_paths, int max_cnt, int* cnt, + const char* socket_path) +{ + if (*cnt >= max_cnt) + return -1; + + socket_paths[*cnt] = socket_path; + ++*cnt; + return 0; +} + static int _xcb_parse_display(const char *name, char **host, char **protocol, int *displayp, int *screenp) { @@ -164,89 +175,118 @@ static int _xcb_open_unix(char *protocol, const char *file); #ifdef HAVE_ABSTRACT_SOCKETS static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen); #endif +#ifndef _WIN32 +static int _xcb_open_socket_path(char *protocol, const int display, const char** socket_paths, int socket_path_cnt); +#endif static int _xcb_open(const char *host, char *protocol, const int display) { int fd; - static const char unix_base[] = "/tmp/.X11-unix/X"; - const char *base = unix_base; - size_t filelen; - char *file = NULL; - int actual_filelen; + const char* socket_paths[6]; + static const int max_socket_path = sizeof(socket_paths) / sizeof(socket_paths[0]); + int socket_path_cnt = 0; + +#ifndef _WIN32 + static const char unix_socket_path[] = "/tmp/.X11-unix/X"; +#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED) + static const char tsol_socket_path[] = "/var/tsol/doors/.X11-unix/X"; +#endif +#endif #ifdef HAVE_LAUNCHD if(strncmp(host, "/tmp/launch", 11) == 0) { - base = host; - host = ""; - protocol = "unix"; +#ifndef _WIN32 + _xcb_add_socket_path(socket_paths, max_socket_path, &socket_path_cnt, host); + + fd = _xcb_open_socket_path("unix", display, socket_paths, socket_path_cnt); + if( fd >= 0 ) + return fd; +#endif + host = ""; } + else +#endif + if ((protocol && (strcmp("unix",protocol) == 0)) || + (*host == '\0') || (strcmp("unix",host) == 0)) { +#ifndef _WIN32 +#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED) + /* Check special path for Unix sockets under Solaris Trusted Extensions */ + if (is_system_labeled()) { + _xcb_add_socket_path(socket_paths, max_socket_path, &socket_path_cnt, tsol_socket_path); + } #endif - /* If protocol or host is "unix", fall through to Unix socket code below */ - if ((!protocol || (strcmp("unix",protocol) != 0)) && - (*host != '\0') && (strcmp("unix",host) != 0)) - { - /* display specifies TCP */ - unsigned short port = X_TCP_PORT + display; - return _xcb_open_tcp(host, protocol, port); + _xcb_add_socket_path(socket_paths, max_socket_path, &socket_path_cnt, unix_socket_path); + + fd = _xcb_open_socket_path("unix", display, socket_paths, socket_path_cnt); + if( fd >= 0 ) + return fd; +#endif + + if(strcmp("unix",host) == 0) + host = ""; } -#ifndef _WIN32 -#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED) - /* Check special path for Unix sockets under Solaris Trusted Extensions */ - if (is_system_labeled()) - { - struct stat sbuf; - const char *tsol_base = "/var/tsol/doors/.X11-unix/X"; - char tsol_socket[PATH_MAX]; + /* display specifies TCP */ + unsigned short port = X_TCP_PORT + display; + return _xcb_open_tcp(host, protocol, port); - snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display); + return -1; /* if control reaches here then something has gone wrong */ +} - if (stat(tsol_socket, &sbuf) == 0) - base = tsol_base; +#ifndef _WIN32 +static int _xcb_open_socket_path(char *protocol, const int display, const char** socket_paths, int socket_path_cnt) +{ + int fd; + size_t filelen; + char *file = NULL; + int actual_filelen; + int i; + size_t socket_pathlen = 0; + size_t len; + + for(i = 0; i < socket_path_cnt; ++i) { + len = strlen(socket_paths[i]); + if (len > socket_pathlen) + socket_pathlen = len; } -#endif - filelen = strlen(base) + 1 + sizeof(display) * 3 + 1; + filelen = socket_pathlen + 1 + sizeof(display) * 3 + 1; file = malloc(filelen); if(file == NULL) return -1; - /* display specifies Unix socket */ + for(i = 0; i < socket_path_cnt; ++i) { #ifdef HAVE_LAUNCHD - if(strncmp(base, "/tmp/launch", 11) == 0) - actual_filelen = snprintf(file, filelen, "%s:%d", base, display); - else + if(strncmp(socket_paths[i], "/tmp/launch", 11) == 0) + actual_filelen = snprintf(file, filelen, "%s%c%d", socket_paths[i], ':', display); + else #endif - actual_filelen = snprintf(file, filelen, "%s%d", base, display); - if(actual_filelen < 0) - { - free(file); - return -1; - } - /* snprintf may truncate the file */ - filelen = MIN(actual_filelen, filelen - 1); -#ifdef HAVE_ABSTRACT_SOCKETS - fd = _xcb_open_abstract(protocol, file, filelen); - if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED)) - { - free(file); - return fd; - } + actual_filelen = snprintf(file, filelen, "%s%d", socket_paths[i], display); -#endif - fd = _xcb_open_unix(protocol, file); - free(file); + if(actual_filelen < 0) { + free(file); + return -1; + } - if (fd < 0 && !protocol && *host == '\0') { - unsigned short port = X_TCP_PORT + display; - fd = _xcb_open_tcp(host, protocol, port); +#ifdef HAVE_ABSTRACT_SOCKETS + fd = _xcb_open_abstract(protocol, file, actual_filelen); + if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED)) { + free(file); + return fd; + } +#endif + fd = _xcb_open_unix(protocol, file); + if (fd >= 0) { + free(file); + return fd; + } } + free(file); - return fd; -#endif /* !_WIN32 */ - return -1; /* if control reaches here then something has gone wrong */ + return -1; } +#endif static int _xcb_socket(int family, int type, int proto) { -- 1.8.3.1