X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fxcb_conn.c;h=a017c2075233fc53119e647f93f869e236e2a549;hb=69b78ced1a7bcdca538c0720fde9cf3e6f70d040;hp=870c438a69e390c881ff2c544dcdb7cf74064234;hpb=36c9a985aaee655c118c9f7b8425d3ac9ce0f840;p=free-sw%2Fxcb%2Flibxcb diff --git a/src/xcb_conn.c b/src/xcb_conn.c index 870c438..a017c20 100644 --- a/src/xcb_conn.c +++ b/src/xcb_conn.c @@ -47,13 +47,18 @@ #include #endif /* _WIN32 */ +/* SHUT_RDWR is fairly recent and is not available on all platforms */ +#if !defined(SHUT_RDWR) +#define SHUT_RDWR 2 +#endif + typedef struct { uint8_t status; uint8_t pad0[5]; uint16_t length; } xcb_setup_generic_t; -static const int error_connection = 1; +const int error_connection = 1; static int set_fd_flags(const int fd) { @@ -119,10 +124,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; } @@ -255,6 +257,16 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info) { xcb_connection_t* c; +#ifndef _WIN32 +#ifndef USE_POLL + if(fd >= FD_SETSIZE) /* would overflow in FD_SET */ + { + close(fd); + return (xcb_connection_t *) &error_connection; + } +#endif +#endif /* !_WIN32*/ + c = calloc(1, sizeof(xcb_connection_t)); if(!c) { close(fd); @@ -283,10 +295,13 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info) void xcb_disconnect(xcb_connection_t *c) { - if(c->has_error) + if(c == (xcb_connection_t *) &error_connection) return; free(c->setup); + + /* disallow further sends and receives */ + shutdown(c->fd, SHUT_RDWR); close(c->fd); pthread_mutex_destroy(&c->iolock); @@ -350,15 +365,22 @@ 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); + /* If poll() returns an event we didn't expect, such as POLLNVAL, treat + * it as if it failed. */ + if(ret >= 0 && (fd.revents & ~fd.events)) + { + ret = -1; + break; + } #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);