From bce72f63d2dfb61661f81e305ad3a7db0334403c Mon Sep 17 00:00:00 2001 From: Jeetu Golani Date: Fri, 26 Mar 2010 09:40:09 +0530 Subject: [PATCH 1/7] Win32 code for xcb-1.5 --- src/xcb.h | 4 ++++ src/xcb_auth.c | 11 ++++++++--- src/xcb_conn.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- src/xcb_in.c | 33 +++++++++++++++++++++++++++++++-- src/xcb_util.c | 24 +++++++++++++++++------- 5 files changed, 107 insertions(+), 14 deletions(-) diff --git a/src/xcb.h b/src/xcb.h index 35d8768..bd9b635 100644 --- a/src/xcb.h +++ b/src/xcb.h @@ -35,7 +35,11 @@ #include #endif +#ifndef _WIN32 #include +#else +#include "windefs.h" +#endif #include diff --git a/src/xcb_auth.c b/src/xcb_auth.c index 104f2f0..a52f922 100644 --- a/src/xcb_auth.c +++ b/src/xcb_auth.c @@ -27,13 +27,18 @@ #include #include -#include -#include -#include #include #include #include +#ifdef _WIN32 +#include "windefs.h" +#else +#include +#include +#include +#endif /* _WIN32 */ + #include "xcb.h" #include "xcbint.h" diff --git a/src/xcb_conn.c b/src/xcb_conn.c index ed2153d..4a50af3 100644 --- a/src/xcb_conn.c +++ b/src/xcb_conn.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -38,10 +37,16 @@ #include "xcbint.h" #if USE_POLL #include -#else +#elif !defined WIN32 #include #endif +#ifdef _WIN32 +#include "windefs.h" +#else +#include +#endif /* _WIN32 */ + typedef struct { uint8_t status; uint8_t pad0[5]; @@ -52,6 +57,17 @@ static const int error_connection = 1; static int set_fd_flags(const int fd) { +/* Win32 doesn't have file descriptors and the fcntl function. This block sets the socket in non-blocking mode */ + +#ifdef _WIN32 + u_long iMode = 1; /* non-zero puts it in non-blocking mode, 0 in blocking mode */ + int ret = 0; + + ret = ioctlsocket(fd, FIONBIO, &iMode); + if(ret != 0) + return 0; + return 1; +#else int flags = fcntl(fd, F_GETFL, 0); if(flags == -1) return 0; @@ -61,6 +77,7 @@ static int set_fd_flags(const int fd) if(fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) return 0; return 1; +#endif /* WIN32 */ } static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) @@ -156,9 +173,37 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) { int n; assert(!c->out.queue_len); + +#ifdef _WIN32 + int i = 0; + int ret = 0,err = 0; + struct iovec *vec; + n = 0; + + /* Could use the WSASend win32 function for scatter/gather i/o but setting up the WSABUF struct from + an iovec would require more work and I'm not sure of the benefit....works for now */ + vec = *vector; + while(i < *count) + { + ret = send(c->fd,vec->iov_base,vec->iov_len,0); + if(ret == SOCKET_ERROR) + { + err = WSAGetLastError(); + if(err == WSAEWOULDBLOCK) + { + return 1; + } + } + n += ret; + *vec++; + i++; + } +#else n = writev(c->fd, *vector, *count); if(n < 0 && errno == EAGAIN) return 1; +#endif /* _WIN32 */ + if(n <= 0) { _xcb_conn_shutdown(c); diff --git a/src/xcb_in.c b/src/xcb_in.c index 80f5523..20ff4f2 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -37,10 +37,14 @@ #include "xcbint.h" #if USE_POLL #include -#else +#elif !defined WIN32 #include #endif +#ifdef _WIN32 +#include "windefs.h" +#endif /* _WIN32 */ + #define XCB_ERROR 0 #define XCB_REPLY 1 #define XCB_XGE_EVENT 35 @@ -267,12 +271,22 @@ static int read_block(const int fd, void *buf, const ssize_t len) int done = 0; while(done < len) { +#ifndef _WIN32 int ret = read(fd, ((char *) buf) + done, len - done); +#else + int ret = recv(fd, ((char *) buf) + done, len - done,0); +#endif /* !_WIN32 */ + if(ret > 0) done += ret; +#ifndef _WIN32 if(ret < 0 && errno == EAGAIN) +#else + if(ret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) +#endif /* !_Win32 */ { #if USE_POLL +#ifndef _WIN32 struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; @@ -280,14 +294,21 @@ static int read_block(const int fd, void *buf, const ssize_t len) do { ret = poll(&pfd, 1, -1); } while (ret == -1 && errno == EINTR); +#endif /* !_WIN32 */ #else fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); +#ifndef _WIN32 do { ret = select(fd + 1, &fds, 0, 0, 0); } while (ret == -1 && errno == EINTR); -#endif +#else + /* the do while loop used for the non-windows version isn't required*/ + /* for windows since there are no signals in Windows hence no EINTR*/ + ret = select(fd + 1, &fds, 0, 0, 0); +#endif /* !_WIN32 */ +#endif /* USE_POLL */ } if(ret <= 0) return ret; @@ -665,12 +686,20 @@ void _xcb_in_replies_done(xcb_connection_t *c) int _xcb_in_read(xcb_connection_t *c) { +#ifndef _WIN32 int n = read(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len); +#else + int n = recv(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len,0); +#endif /* !_WIN32 */ if(n > 0) c->in.queue_len += n; while(read_packet(c)) /* empty */; +#ifndef _WIN32 if((n > 0) || (n < 0 && errno == EAGAIN)) +#else + if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK)) +#endif /* !_WIN32 */ return 1; _xcb_conn_shutdown(c); return 0; diff --git a/src/xcb_util.c b/src/xcb_util.c index 996ff25..1848abc 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -27,23 +27,26 @@ #include #include -#include -#include -#include -#include #ifdef DNETCONN #include #include #endif -#include #include #include #include #include #include -#include #include +#ifdef _WIN32 +#include "windefs.h" +#else +#include +#include +#include +#include +#endif /* _WIN32 */ + #include "xcb.h" #include "xcbext.h" #include "xcbint.h" @@ -122,7 +125,9 @@ int xcb_parse_display(const char *name, char **host, int *displayp, } static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port); +#ifndef _WIN32 static int _xcb_open_unix(char *protocol, const char *file); +#endif /* !WIN32 */ #ifdef DNETCONN static int _xcb_open_decnet(const char *host, char *protocol, const unsigned short port); #endif @@ -162,7 +167,7 @@ static int _xcb_open(char *host, char *protocol, const int display) return _xcb_open_tcp(host, protocol, port); } } - +#ifndef _WIN32 /* display specifies Unix socket */ filelen = snprintf(file, sizeof(file), "%s%d", base, display); if(filelen < 0) @@ -176,6 +181,7 @@ static int _xcb_open(char *host, char *protocol, const int display) #endif return _xcb_open_unix(protocol, file); +#endif /* !_WIN32 */ } static int _xcb_socket(int family, int type, int proto) @@ -188,8 +194,10 @@ static int _xcb_socket(int family, int type, int proto) #endif { fd = socket(family, type, proto); +#ifndef _WIN32 if (fd >= 0) fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif } return fd; } @@ -289,6 +297,7 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) return fd; } +#ifndef _WIN32 static int _xcb_open_unix(char *protocol, const char *file) { int fd; @@ -311,6 +320,7 @@ static int _xcb_open_unix(char *protocol, const char *file) } return fd; } +#endif /* !_WIN32 */ #ifdef HAVE_ABSTRACT_SOCKETS static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen) From 36c9a985aaee655c118c9f7b8425d3ac9ce0f840 Mon Sep 17 00:00:00 2001 From: Jeetu Golani Date: Mon, 29 Mar 2010 22:31:49 +0530 Subject: [PATCH 2/7] windefs.h is now called xcb_windefs.h - changed all includes to reflect that.Replaced one instance ofWIN32 with _WIN32 in each xcb_in.c and xcb_conn.c --- src/xcb.h | 2 +- src/xcb_auth.c | 2 +- src/xcb_conn.c | 6 +++--- src/xcb_in.c | 4 ++-- src/xcb_util.c | 2 +- src/xcb_windefs.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 src/xcb_windefs.h diff --git a/src/xcb.h b/src/xcb.h index bd9b635..14244a7 100644 --- a/src/xcb.h +++ b/src/xcb.h @@ -38,7 +38,7 @@ #ifndef _WIN32 #include #else -#include "windefs.h" +#include "xcb_windefs.h" #endif #include diff --git a/src/xcb_auth.c b/src/xcb_auth.c index a52f922..8fcfafd 100644 --- a/src/xcb_auth.c +++ b/src/xcb_auth.c @@ -32,7 +32,7 @@ #include #ifdef _WIN32 -#include "windefs.h" +#include "xcb_windefs.h" #else #include #include diff --git a/src/xcb_conn.c b/src/xcb_conn.c index 4a50af3..870c438 100644 --- a/src/xcb_conn.c +++ b/src/xcb_conn.c @@ -37,12 +37,12 @@ #include "xcbint.h" #if USE_POLL #include -#elif !defined WIN32 +#elif !defined _WIN32 #include #endif #ifdef _WIN32 -#include "windefs.h" +#include "xcb_windefs.h" #else #include #endif /* _WIN32 */ @@ -77,7 +77,7 @@ static int set_fd_flags(const int fd) if(fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) return 0; return 1; -#endif /* WIN32 */ +#endif /* _WIN32 */ } static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) diff --git a/src/xcb_in.c b/src/xcb_in.c index 20ff4f2..4191dc3 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -37,12 +37,12 @@ #include "xcbint.h" #if USE_POLL #include -#elif !defined WIN32 +#elif !defined _WIN32 #include #endif #ifdef _WIN32 -#include "windefs.h" +#include "xcb_windefs.h" #endif /* _WIN32 */ #define XCB_ERROR 0 diff --git a/src/xcb_util.c b/src/xcb_util.c index 1848abc..882db52 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -39,7 +39,7 @@ #include #ifdef _WIN32 -#include "windefs.h" +#include "xcb_windefs.h" #else #include #include diff --git a/src/xcb_windefs.h b/src/xcb_windefs.h new file mode 100644 index 0000000..a7c0104 --- /dev/null +++ b/src/xcb_windefs.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2009 Jatin Golani. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + + +#ifndef _WINDEFS_H +#define _WINDEFS_H + +#ifndef WINVER +#define WINVER 0x0501 /* required for getaddrinfo/freeaddrinfo defined only for WinXP and above */ +#endif + +#include +#include +#include + +struct iovec { + void *iov_base; /* Pointer to data. */ + int iov_len; /* Length of data. */ +}; + +typedef unsigned int in_addr_t; + +#endif /* windefs.h */ From d302f1e9b158d0a51936c28e5dc66251d90d1d56 Mon Sep 17 00:00:00 2001 From: Jeetu Golani Date: Mon, 29 Mar 2010 22:37:33 +0530 Subject: [PATCH 3/7] changes in xcb_windefs.h - the flag _XCB_WINDEFS_H replaces WINDEFS_H --- src/xcb_windefs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xcb_windefs.h b/src/xcb_windefs.h index a7c0104..d6c7329 100644 --- a/src/xcb_windefs.h +++ b/src/xcb_windefs.h @@ -24,8 +24,8 @@ */ -#ifndef _WINDEFS_H -#define _WINDEFS_H +#ifndef _XCB_WINDEFS_H +#define _XCB_WINDEFS_H #ifndef WINVER #define WINVER 0x0501 /* required for getaddrinfo/freeaddrinfo defined only for WinXP and above */ @@ -42,4 +42,4 @@ struct iovec { typedef unsigned int in_addr_t; -#endif /* windefs.h */ +#endif /* xcb_windefs.h */ From e8009194c9f5a6995c4a9b03a7a49d5bc09e96fc Mon Sep 17 00:00:00 2001 From: Jeetu Golani Date: Wed, 31 Mar 2010 09:50:51 +0530 Subject: [PATCH 4/7] restablished inclusion of fcntl.h and netinet/tcp.h in xcb_util.c -- without these the code no longer compiled on *ix --- src/xcb_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xcb_util.c b/src/xcb_util.c index 882db52..2be59d2 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #endif /* _WIN32 */ From 0e0c80e749eccf121e55c1e855c48d03b54f33ef Mon Sep 17 00:00:00 2001 From: Jeetu Golani Date: Wed, 31 Mar 2010 22:00:04 +0530 Subject: [PATCH 5/7] xcb_in.c #ifndef _WIN32 inside of #if USE_POLL redundant and removed --- src/xcb_in.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/xcb_in.c b/src/xcb_in.c index 4191dc3..8689344 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -286,7 +286,6 @@ static int read_block(const int fd, void *buf, const ssize_t len) #endif /* !_Win32 */ { #if USE_POLL -#ifndef _WIN32 struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; @@ -294,7 +293,6 @@ static int read_block(const int fd, void *buf, const ssize_t len) do { ret = poll(&pfd, 1, -1); } while (ret == -1 && errno == EINTR); -#endif /* !_WIN32 */ #else fd_set fds; FD_ZERO(&fds); From 56962e42a509dc4d0d9541e46b93689dac61c4fd Mon Sep 17 00:00:00 2001 From: Jeetu Golani Date: Thu, 22 Apr 2010 23:23:27 +0530 Subject: [PATCH 6/7] Set errno=0 in read_block. On Win32 there is no errno and this makes the do..while loop execute only once. Also set the return value to -1 in _xcb_open if control reaches the end - if all goes well it shouldn't reach there. --- src/xcb_in.c | 9 +++------ src/xcb_util.c | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/xcb_in.c b/src/xcb_in.c index 8689344..b481295 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -297,15 +297,12 @@ static int read_block(const int fd, void *buf, const ssize_t len) fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); -#ifndef _WIN32 + + /* Initializing errno here makes sure that for Win32 this loop will execute only once */ + errno = 0; do { ret = select(fd + 1, &fds, 0, 0, 0); } while (ret == -1 && errno == EINTR); -#else - /* the do while loop used for the non-windows version isn't required*/ - /* for windows since there are no signals in Windows hence no EINTR*/ - ret = select(fd + 1, &fds, 0, 0, 0); -#endif /* !_WIN32 */ #endif /* USE_POLL */ } if(ret <= 0) diff --git a/src/xcb_util.c b/src/xcb_util.c index 2be59d2..e08a320 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -180,10 +180,10 @@ static int _xcb_open(char *host, char *protocol, const int display) fd = _xcb_open_abstract(protocol, file, filelen); if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED)) return fd; - #endif return _xcb_open_unix(protocol, file); #endif /* !_WIN32 */ + return -1; /* if control reaches here then something has gone wrong */ } static int _xcb_socket(int family, int type, int proto) From 2dcf8b025be88a25d4333abdc28d425b88238d96 Mon Sep 17 00:00:00 2001 From: Jeetu Golani Date: Fri, 23 Apr 2010 00:47:16 +0530 Subject: [PATCH 7/7] Replaced read() in read_block and _xcb_in_read() with recv for all platforms. MSG_WAITALL is undefined in MinGW so it's been explicitly defined in xcb_in.c --- src/xcb_in.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/xcb_in.c b/src/xcb_in.c index b481295..e2f9936 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -39,6 +39,7 @@ #include #elif !defined _WIN32 #include +#include #endif #ifdef _WIN32 @@ -49,6 +50,11 @@ #define XCB_REPLY 1 #define XCB_XGE_EVENT 35 +/* required for compiling for Win32 using MinGW */ +#ifndef MSG_WAITALL +#define MSG_WAITALL 0 +#endif + struct event_list { xcb_generic_event_t *event; struct event_list *next; @@ -271,12 +277,7 @@ static int read_block(const int fd, void *buf, const ssize_t len) int done = 0; while(done < len) { -#ifndef _WIN32 - int ret = read(fd, ((char *) buf) + done, len - done); -#else - int ret = recv(fd, ((char *) buf) + done, len - done,0); -#endif /* !_WIN32 */ - + int ret = recv(fd, ((char *) buf) + done, len - done,MSG_WAITALL); if(ret > 0) done += ret; #ifndef _WIN32 @@ -681,11 +682,7 @@ void _xcb_in_replies_done(xcb_connection_t *c) int _xcb_in_read(xcb_connection_t *c) { -#ifndef _WIN32 - int n = read(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len); -#else - int n = recv(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len,0); -#endif /* !_WIN32 */ + int n = recv(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len,MSG_WAITALL); if(n > 0) c->in.queue_len += n; while(read_packet(c))