From 8c7a601e8094413a46f96ddb3130b7975c7c25ed Mon Sep 17 00:00:00 2001 From: Arvind Umrao Date: Mon, 17 Oct 2011 16:00:11 +0530 Subject: [PATCH xcb/libxcb] Fatal error message when we close libX11 window application Fixes:https://bugs.freedesktop.org/show_bug.cgi?id=41443 When we close any libX11 window application, we get fatal error. XIO: fatal IO error 11 (Resource temporarily unavailable). Fatal error messages are strange and confusing to developers. Error is simply because we quit the application, without exiting while loop of XNextEvent. XCB should give same error messages as legacy libX11 were. In order to fix this issue, I have set right error number at xcb_connection_t::has_error.This xcb_connection_t::has_error will be passed to default io handler of libX11, This value could then be used to display corrrect error messages in default IO error handler of libX11. Signed-off-by: Arvind Umrao --- src/xcb_conn.c | 14 ++++++++++---- src/xcb_in.c | 25 ++++++++++++++++++------- src/xcb_out.c | 7 +++++-- src/xcbint.h | 2 +- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/xcb_conn.c b/src/xcb_conn.c index 3ab5385..89bf068 100644 --- a/src/xcb_conn.c +++ b/src/xcb_conn.c @@ -209,7 +209,7 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) if(n <= 0) { - _xcb_conn_shutdown(c); + _xcb_conn_shutdown(c, errno); return 0; } @@ -317,9 +317,15 @@ void xcb_disconnect(xcb_connection_t *c) /* Private interface */ -void _xcb_conn_shutdown(xcb_connection_t *c) +void _xcb_conn_shutdown(xcb_connection_t *c, int err) { - c->has_error = 1; +#ifndef _WIN32 + /* Only error number greater than zero possible*/ + if(err > 0) + c->has_error = err; + else +#endif /* !_WIN32*/ + c->has_error = 1; } int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count) @@ -380,7 +386,7 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec } while (ret == -1 && errno == EINTR); if(ret < 0) { - _xcb_conn_shutdown(c); + _xcb_conn_shutdown(c, errno); ret = 0; } pthread_mutex_lock(&c->iolock); diff --git a/src/xcb_in.c b/src/xcb_in.c index e075a40..299a0fe 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -174,7 +174,9 @@ static int read_packet(xcb_connection_t *c) (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t))); if(!buf) { - _xcb_conn_shutdown(c); + /* Unix98 standard set errno to ENOMEM upon failure. + * We do not bother about Win32 behaviour of malloc here*/ + _xcb_conn_shutdown(c, errno); return 0; } @@ -210,7 +212,9 @@ static int read_packet(xcb_connection_t *c) struct reply_list *cur = malloc(sizeof(struct reply_list)); if(!cur) { - _xcb_conn_shutdown(c); + /* Unix98 standard set errno to ENOMEM upon failure. + * We do not bother about Win32 behaviour of malloc here*/ + _xcb_conn_shutdown(c, errno); free(buf); return 0; } @@ -227,7 +231,9 @@ static int read_packet(xcb_connection_t *c) event = malloc(sizeof(struct event_list)); if(!event) { - _xcb_conn_shutdown(c); + /* Unix98 standard set errno to ENOMEM upon failure. + * We do not bother about Win32 behaviour of malloc here*/ + _xcb_conn_shutdown(c, errno); free(buf); return 0; } @@ -433,7 +439,9 @@ static void insert_pending_discard(xcb_connection_t *c, pending_reply **prev_nex pend = malloc(sizeof(*pend)); if(!pend) { - _xcb_conn_shutdown(c); + /* Unix98 standard set errno to ENOMEM upon failure. + * We do not bother about Win32 behaviour of malloc here*/ + _xcb_conn_shutdown(c, errno); return; } @@ -633,7 +641,7 @@ int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds assert(workaround != WORKAROUND_NONE || flags != 0); if(!pend) { - _xcb_conn_shutdown(c); + _xcb_conn_shutdown(c, errno); return 0; } pend->first_request = pend->last_request = request; @@ -672,7 +680,10 @@ int _xcb_in_read(xcb_connection_t *c) if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK)) #endif /* !_WIN32 */ return 1; - _xcb_conn_shutdown(c); + /* if bytes_read == 0 Read failed because of end of file! + * set error (EPIPE); + */ + _xcb_conn_shutdown(c, EPIPE); return 0; } @@ -691,7 +702,7 @@ int _xcb_in_read_block(xcb_connection_t *c, void *buf, int len) int ret = read_block(c->fd, (char *) buf + done, len - done); if(ret <= 0) { - _xcb_conn_shutdown(c); + _xcb_conn_shutdown(c, errno); return ret; } } diff --git a/src/xcb_out.c b/src/xcb_out.c index 5eb1e42..d431b1e 100644 --- a/src/xcb_out.c +++ b/src/xcb_out.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "xcb.h" #include "xcbext.h" @@ -173,7 +174,8 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext); if(!(extension && extension->present)) { - _xcb_conn_shutdown(c); + /* ENOTSUP: Operation not supported */ + _xcb_conn_shutdown(c, ENOTSUP); return 0; } ((uint8_t *) vector[0].iov_base)[0] = extension->major_opcode; @@ -203,7 +205,8 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect } else if(longlen > xcb_get_maximum_request_length(c)) { - _xcb_conn_shutdown(c); + /* ECOMM: Communication error on send */ + _xcb_conn_shutdown(c, ECOMM); return 0; /* server can't take this; maybe need BIGREQUESTS? */ } diff --git a/src/xcbint.h b/src/xcbint.h index 096576c..048a3b1 100644 --- a/src/xcbint.h +++ b/src/xcbint.h @@ -193,7 +193,7 @@ struct xcb_connection_t { _xcb_xid xid; }; -void _xcb_conn_shutdown(xcb_connection_t *c); +void _xcb_conn_shutdown(xcb_connection_t *c, int err); int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count); -- 1.7.3.2