[Xcb] [PATCH xcb/libxcb] Fatal error message when we close libX11 window application
Arvind Umrao
arvind.umrao at oracle.com
Tue Oct 18 05:51:45 PDT 2011
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 <arvind.umrao at oracle.com>
---
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 <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#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
More information about the Xcb
mailing list