diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2010-09-04 10:01:00 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2010-09-04 10:01:00 +0000 |
commit | 63f14a79ad8b0a35bad143095a2b22d9f299a78d (patch) | |
tree | 78762a42bef153fbfcdc9c06f31a3b879cb6e51c /dist/libxcb/src | |
parent | ae0de1302839aabcc3583f9db40f92b63bed0291 (diff) |
Update to libxcb 1.7
Diffstat (limited to 'dist/libxcb/src')
-rw-r--r-- | dist/libxcb/src/c_client.py | 4 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_auth.c | 70 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_conn.c | 13 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_in.c | 28 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_out.c | 16 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_util.c | 76 | ||||
-rw-r--r-- | dist/libxcb/src/xcbint.h | 4 |
7 files changed, 149 insertions, 62 deletions
diff --git a/dist/libxcb/src/c_client.py b/dist/libxcb/src/c_client.py index d86d05e24..4f3b0894d 100644 --- a/dist/libxcb/src/c_client.py +++ b/dist/libxcb/src/c_client.py @@ -448,7 +448,9 @@ def _c_accessor_get_expr(expr, prefix=''): ''' lenexp = _c_accessor_get_length(expr, prefix) - if expr.op != None: + if expr.op == '~': + return '(' + '~' + _c_accessor_get_expr(expr.rhs, prefix) + ')' + elif expr.op != None: return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')' elif expr.bitfield: return 'xcb_popcount(' + lenexp + ')' diff --git a/dist/libxcb/src/xcb_auth.c b/dist/libxcb/src/xcb_auth.c index 00aad23c5..d774d1069 100644 --- a/dist/libxcb/src/xcb_auth.c +++ b/dist/libxcb/src/xcb_auth.c @@ -89,8 +89,7 @@ static int authname_match(enum auth_protos kind, char *name, size_t namelen) #define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr) -static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen, - int display) +static Xauth *get_authptr(struct sockaddr *sockname, int display) { char *addr = 0; int addrlen = 0; @@ -243,13 +242,55 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr * return 0; /* Unknown authorization type */ } +/* `sockaddr_un.sun_path' typical size usually ranges between 92 and 108 */ +#define INITIAL_SOCKNAME_SLACK 108 + +/* Return a dynamically allocated socket address structure according + to the value returned by either getpeername() or getsockname() + (according to POSIX, applications should not assume a particular + length for `sockaddr_un.sun_path') */ +static struct sockaddr *get_peer_sock_name(int (*socket_func)(int, + struct sockaddr *, + socklen_t *), + int fd) +{ + socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK; + socklen_t actual_socknamelen = socknamelen; + struct sockaddr *sockname = malloc(socknamelen), *new_sockname = NULL; + + if (sockname == NULL) + return NULL; + + /* Both getpeername() and getsockname() truncates sockname if + there is not enough space and set the required length in + actual_socknamelen */ + if (socket_func(fd, sockname, &actual_socknamelen) == -1) + goto sock_or_realloc_error; + + if (actual_socknamelen > socknamelen) + { + socknamelen = actual_socknamelen; + + if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL || + socket_func(fd, new_sockname, &actual_socknamelen) == -1 || + actual_socknamelen > socknamelen) + goto sock_or_realloc_error; + + sockname = new_sockname; + } + + return sockname; + + sock_or_realloc_error: + free(sockname); + return NULL; +} + int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display) { /* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c, xtrans/Xtransutils.c */ - char sockbuf[sizeof(struct sockaddr) + MAXPATHLEN]; - unsigned int socknamelen = sizeof(sockbuf); /* need extra space */ - struct sockaddr *sockname = (struct sockaddr *) &sockbuf; + struct sockaddr *sockname = NULL; int gotsockname = 0; Xauth *authptr = 0; int ret = 1; @@ -258,24 +299,30 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display) * for UNIX Domain Sockets, but this is irrelevant, * since compute_auth() ignores the peer name in this * case anyway.*/ - if (getpeername(fd, sockname, &socknamelen) == -1) + if ((sockname = get_peer_sock_name(getpeername, fd)) == NULL) { - if (getsockname(fd, sockname, &socknamelen) == -1) + if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL) return 0; /* can only authenticate sockets */ if (sockname->sa_family != AF_UNIX) + { + free(sockname); return 0; /* except for AF_UNIX, sockets should have peernames */ + } gotsockname = 1; } - authptr = get_authptr(sockname, socknamelen, display); + authptr = get_authptr(sockname, display); if (authptr == 0) + { + free(sockname); return 0; /* cannot find good auth data */ + } info->namelen = memdup(&info->name, authptr->name, authptr->name_length); if (!info->namelen) goto no_auth; /* out of memory */ - if (!gotsockname && getsockname(fd, sockname, &socknamelen) == -1) + if (!gotsockname && (sockname = get_peer_sock_name(getsockname, fd)) == NULL) { free(info->name); goto no_auth; /* can only authenticate sockets */ @@ -288,10 +335,15 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display) goto no_auth; /* cannot build auth record */ } + free(sockname); + sockname = NULL; + XauDisposeAuth(authptr); return ret; no_auth: + free(sockname); + info->name = 0; info->namelen = 0; XauDisposeAuth(authptr); diff --git a/dist/libxcb/src/xcb_conn.c b/dist/libxcb/src/xcb_conn.c index 1d3761452..7e18891a1 100644 --- a/dist/libxcb/src/xcb_conn.c +++ b/dist/libxcb/src/xcb_conn.c @@ -102,10 +102,7 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) assert(count <= (int) (sizeof(parts) / sizeof(*parts))); pthread_mutex_lock(&c->iolock); - { - struct iovec *parts_ptr = parts; - ret = _xcb_out_send(c, &parts_ptr, &count); - } + ret = _xcb_out_send(c, parts, count); pthread_mutex_unlock(&c->iolock); return ret; } @@ -313,15 +310,15 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec pthread_mutex_unlock(&c->iolock); do { #if USE_POLL - ret = poll(&fd, 1, -1); + ret = poll(&fd, 1, -1); #else - ret = select(c->fd + 1, &rfds, &wfds, 0, 0); + ret = select(c->fd + 1, &rfds, &wfds, 0, 0); #endif } while (ret == -1 && errno == EINTR); - if (ret < 0) + if(ret < 0) { _xcb_conn_shutdown(c); - ret = 0; + ret = 0; } pthread_mutex_lock(&c->iolock); diff --git a/dist/libxcb/src/xcb_in.c b/dist/libxcb/src/xcb_in.c index 80f55232e..6dd358cbd 100644 --- a/dist/libxcb/src/xcb_in.c +++ b/dist/libxcb/src/xcb_in.c @@ -69,16 +69,6 @@ typedef struct reader_list { struct reader_list *next; } reader_list; -static void wake_up_next_reader(xcb_connection_t *c) -{ - int pthreadret; - if(c->in.readers) - pthreadret = pthread_cond_signal(c->in.readers->data); - else - pthreadret = pthread_cond_signal(&c->in.event_cond); - assert(pthreadret == 0); -} - static int read_packet(xcb_connection_t *c) { xcb_generic_reply_t genrep; @@ -154,9 +144,7 @@ static int read_packet(xcb_connection_t *c) /* XGE events may have sizes > 32 */ if (genrep.response_type == XCB_XGE_EVENT) - { - eventlength = ((xcb_ge_event_t*)&genrep)->length * 4; - } + eventlength = genrep.length * 4; buf = malloc(length + eventlength + (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t))); @@ -404,7 +392,7 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_ pthread_cond_destroy(&cond); } - wake_up_next_reader(c); + _xcb_in_wake_up_next_reader(c); pthread_mutex_unlock(&c->iolock); return ret; } @@ -547,7 +535,7 @@ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c) if(!_xcb_conn_wait(c, &c->in.event_cond, 0, 0)) break; - wake_up_next_reader(c); + _xcb_in_wake_up_next_reader(c); pthread_mutex_unlock(&c->iolock); return ret; } @@ -631,6 +619,16 @@ void _xcb_in_destroy(_xcb_in *in) } } +void _xcb_in_wake_up_next_reader(xcb_connection_t *c) +{ + int pthreadret; + if(c->in.readers) + pthreadret = pthread_cond_signal(c->in.readers->data); + else + pthreadret = pthread_cond_signal(&c->in.event_cond); + assert(pthreadret == 0); +} + int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags) { pending_reply *pend = malloc(sizeof(pending_reply)); diff --git a/dist/libxcb/src/xcb_out.c b/dist/libxcb/src/xcb_out.c index b3050fe3d..fbce7a0ea 100644 --- a/dist/libxcb/src/xcb_out.c +++ b/dist/libxcb/src/xcb_out.c @@ -52,7 +52,7 @@ static int write_block(xcb_connection_t *c, struct iovec *vector, int count) vector[0].iov_base = c->out.queue; vector[0].iov_len = c->out.queue_len; c->out.queue_len = 0; - return _xcb_out_send(c, &vector, &count); + return _xcb_out_send(c, vector, count); } static void get_socket_back(xcb_connection_t *c) @@ -283,7 +283,7 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re return 0; pthread_mutex_lock(&c->iolock); c->out.request += requests; - ret = _xcb_out_send(c, &vector, &count); + ret = _xcb_out_send(c, vector, count); pthread_mutex_unlock(&c->iolock); return ret; } @@ -331,13 +331,14 @@ void _xcb_out_destroy(_xcb_out *out) pthread_mutex_destroy(&out->reqlenlock); } -int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count) +int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count) { int ret = 1; - while(ret && *count) - ret = _xcb_conn_wait(c, &c->out.cond, vector, count); + while(ret && count) + ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count); c->out.request_written = c->out.request; pthread_cond_broadcast(&c->out.cond); + _xcb_in_wake_up_next_reader(c); return ret; } @@ -348,12 +349,11 @@ int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request) return 1; if(c->out.queue_len) { - struct iovec vec, *vec_ptr = &vec; - int count = 1; + struct iovec vec; vec.iov_base = c->out.queue; vec.iov_len = c->out.queue_len; c->out.queue_len = 0; - return _xcb_out_send(c, &vec_ptr, &count); + return _xcb_out_send(c, &vec, 1); } while(c->out.writing) pthread_cond_wait(&c->out.cond, &c->iolock); diff --git a/dist/libxcb/src/xcb_util.c b/dist/libxcb/src/xcb_util.c index b4b56f43b..5a82ac129 100644 --- a/dist/libxcb/src/xcb_util.c +++ b/dist/libxcb/src/xcb_util.c @@ -28,6 +28,7 @@ #include <assert.h> #include <sys/types.h> #include <sys/socket.h> +#include <limits.h> #include <sys/un.h> #include <netinet/in.h> #include <netinet/tcp.h> @@ -63,11 +64,19 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol, { int len, display, screen; char *slash, *colon, *dot, *end; + if(!name || !*name) name = getenv("DISPLAY"); if(!name) return 0; + +#ifdef HAVE_LAUNCHD + if(strncmp(name, "/tmp/launch", 11) == 0) + slash = NULL; + else +#endif slash = strrchr(name, '/'); + if (slash) { len = slash - name; if (protocol) { @@ -129,7 +138,7 @@ int xcb_parse_display(const char *name, char **host, int *displayp, return _xcb_parse_display(name, host, NULL, displayp, screenp); } -static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port); +static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port); 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); @@ -138,16 +147,24 @@ static int _xcb_open_decnet(const char *host, char *protocol, const unsigned sho static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen); #endif -static int _xcb_open(char *host, char *protocol, const int display) +static int _xcb_open(const char *host, char *protocol, const int display) { -#ifdef HAVE_ABSTRACT_SOCKETS 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; + +#ifdef HAVE_LAUNCHD + if(strncmp(host, "/tmp/launch", 11) == 0) { + base = host; + host = ""; + protocol = NULL; + } #endif - static const char base[] = "/tmp/.X11-unix/X"; - char file[sizeof(base) + 20]; - int filelen; - if(*host) + if(*host || protocol) { #ifdef DNETCONN /* DECnet displays have two colons, so _xcb_parse_display will have @@ -171,19 +188,38 @@ static int _xcb_open(char *host, char *protocol, const int display) } } + filelen = strlen(base) + 1 + sizeof(display) * 3 + 1; + file = malloc(filelen); + if(file == NULL) + return -1; + /* display specifies Unix socket */ - filelen = snprintf(file, sizeof(file), "%s%d", base, display); - if(filelen < 0) +#ifdef HAVE_LAUNCHD + if(strncmp(base, "/tmp/launch", 11) == 0) + actual_filelen = snprintf(file, filelen, "%s:%d", base, 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(filelen, sizeof(file) - 1); + 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; + } #endif - return _xcb_open_unix(protocol, file); + fd = _xcb_open_unix(protocol, file); + free(file); + + return fd; } static int _xcb_socket(int family, int type, int proto) @@ -242,7 +278,7 @@ static int _xcb_open_decnet(const char *host, const char *protocol, const unsign } #endif -static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) +static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port) { int fd = -1; struct addrinfo hints; @@ -250,8 +286,15 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) struct addrinfo *results, *addr; char *bracket; - if (protocol && strcmp("tcp",protocol)) + if (protocol && strcmp("tcp",protocol) && strcmp("inet",protocol) +#ifdef AF_INET6 + && strcmp("inet6",protocol) +#endif + ) return -1; + + if (*host == '\0') + host = "localhost"; memset(&hints, 0, sizeof(hints)); #ifdef AI_ADDRCONFIG @@ -362,13 +405,6 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp); -#ifdef HAVE_LAUNCHD - if(!displayname) - displayname = getenv("DISPLAY"); - if(displayname && strlen(displayname)>11 && !strncmp(displayname, "/tmp/launch", 11)) - fd = _xcb_open_unix(NULL, displayname); - else -#endif if(!parsed) { c = (xcb_connection_t *) &error_connection; goto out; diff --git a/dist/libxcb/src/xcbint.h b/dist/libxcb/src/xcbint.h index 154cca04a..f07add8b9 100644 --- a/dist/libxcb/src/xcbint.h +++ b/dist/libxcb/src/xcbint.h @@ -106,7 +106,7 @@ typedef struct _xcb_out { int _xcb_out_init(_xcb_out *out); void _xcb_out_destroy(_xcb_out *out); -int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count); +int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count); int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request); @@ -137,6 +137,8 @@ typedef struct _xcb_in { int _xcb_in_init(_xcb_in *in); void _xcb_in_destroy(_xcb_in *in); +void _xcb_in_wake_up_next_reader(xcb_connection_t *c); + int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags); void _xcb_in_replies_done(xcb_connection_t *c); |