aboutsummaryrefslogtreecommitdiff
path: root/libxcb
diff options
context:
space:
mode:
Diffstat (limited to 'libxcb')
-rw-r--r--libxcb/configure.ac2
-rw-r--r--libxcb/src/c_client.py12
-rw-r--r--libxcb/src/xcb_auth.c6
-rw-r--r--libxcb/src/xcb_util.c56
4 files changed, 65 insertions, 11 deletions
diff --git a/libxcb/configure.ac b/libxcb/configure.ac
index 1a8cd2ef2..cba9dbdad 100644
--- a/libxcb/configure.ac
+++ b/libxcb/configure.ac
@@ -135,6 +135,8 @@ AC_PREREQ([2.59c], [], [AC_SUBST([htmldir], [m4_ifset([AC_PACKAGE_TARNAME],
XCB_CHECK_DOXYGEN()
+AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAVE_GETADDRINFO, 1, [getaddrinfo() function is available])], )
+
case $host_os in
# darwin through Snow Leopard has poll() but can't be used to poll character devices.
darwin@<:@789@:>@*|darwin10*) ;;
diff --git a/libxcb/src/c_client.py b/libxcb/src/c_client.py
index ef245c561..ad3ea22ea 100644
--- a/libxcb/src/c_client.py
+++ b/libxcb/src/c_client.py
@@ -171,9 +171,13 @@ def c_open(self):
_c('#include <stdlib.h>')
_c('#include <string.h>')
_c('#include <assert.h>')
+ _c('#include <stddef.h> /* for offsetof() */')
_c('#include "xcbext.h"')
_c('#include "%s.h"', _ns.header)
+ _c('')
+ _c('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)')
+
if _ns.is_ext:
for (n, h) in self.imports:
_hc('#include "%s.h"', h)
@@ -637,7 +641,7 @@ def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'):
def _c_serialize_helper_insert_padding(context, code_lines, space, postpone):
code_lines.append('%s /* insert padding */' % space)
- code_lines.append('%s xcb_pad = -xcb_block_len & 3;' % space)
+ code_lines.append('%s xcb_pad = -xcb_block_len & (xcb_align_to - 1);' % space)
# code_lines.append('%s printf("automatically inserting padding: %%%%d\\n", xcb_pad);' % space)
code_lines.append('%s xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
@@ -993,6 +997,8 @@ def _c_serialize_helper_fields(context, self,
code_lines.append('%s xcb_parts_idx++;' % space)
count += 1
+ code_lines.append('%s xcb_align_to = ALIGNOF(%s);' % (space, 'char' if field.c_field_type == 'void' else field.c_field_type))
+
need_padding = True
if self.var_followed_by_fixed_fields:
need_padding = False
@@ -1100,9 +1106,11 @@ def _c_serialize(context, self):
_c(' %s *xcb_out = *_buffer;', self.c_type)
_c(' unsigned int xcb_out_pad = -sizeof(%s) & 3;', self.c_type)
_c(' unsigned int xcb_buffer_len = sizeof(%s) + xcb_out_pad;', self.c_type)
+ _c(' unsigned int xcb_align_to;')
else:
_c(' char *xcb_out = *_buffer;')
_c(' unsigned int xcb_buffer_len = 0;')
+ _c(' unsigned int xcb_align_to;')
prefix = [('_aux', '->', self)]
aux_ptr = 'xcb_out'
@@ -1125,6 +1133,7 @@ def _c_serialize(context, self):
_c(' unsigned int xcb_buffer_len = 0;')
_c(' unsigned int xcb_block_len = 0;')
_c(' unsigned int xcb_pad = 0;')
+ _c(' unsigned int xcb_align_to;')
elif 'sizeof' == context:
param_names = [p[2] for p in params]
@@ -1169,6 +1178,7 @@ def _c_serialize(context, self):
_c(' unsigned int xcb_buffer_len = 0;')
_c(' unsigned int xcb_block_len = 0;')
_c(' unsigned int xcb_pad = 0;')
+ _c(' unsigned int xcb_align_to;')
_c('')
for t in temp_vars:
diff --git a/libxcb/src/xcb_auth.c b/libxcb/src/xcb_auth.c
index a3a7e45b5..859ab8a76 100644
--- a/libxcb/src/xcb_auth.c
+++ b/libxcb/src/xcb_auth.c
@@ -30,6 +30,12 @@
#include <sys/param.h>
#include <unistd.h>
#include <stdlib.h>
+#include <arpa/inet.h>
+
+#ifdef __INTERIX
+/* _don't_ ask. interix has INADDR_LOOPBACK in here. */
+#include <rpc/types.h>
+#endif
#ifdef _WIN32
#include "xcb_windefs.h"
diff --git a/libxcb/src/xcb_util.c b/libxcb/src/xcb_util.c
index fde4f85f1..fcb11f042 100644
--- a/libxcb/src/xcb_util.c
+++ b/libxcb/src/xcb_util.c
@@ -34,6 +34,7 @@
#include <stddef.h>
#include <unistd.h>
#include <string.h>
+#include <arpa/inet.h>
#ifdef _WIN32
#include "xcb_windefs.h"
@@ -258,13 +259,27 @@ static int _xcb_socket(int family, int type, int proto)
}
+static int _xcb_do_connect(int fd, const struct sockaddr* addr, int addrlen) {
+ int on = 1;
+
+ if(fd < 0)
+ return -1;
+
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+ setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
+
+ return connect(fd, addr, addrlen);
+}
+
static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port)
{
int fd = -1;
+#if HAVE_GETADDRINFO
struct addrinfo hints;
char service[6]; /* "65535" with the trailing '\0' */
struct addrinfo *results, *addr;
char *bracket;
+#endif
if (protocol && strcmp("tcp",protocol) && strcmp("inet",protocol)
#ifdef AF_INET6
@@ -276,10 +291,8 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
if (*host == '\0')
host = "localhost";
+#if HAVE_GETADDRINFO
memset(&hints, 0, sizeof(hints));
-#ifdef AI_ADDRCONFIG
- hints.ai_flags |= AI_ADDRCONFIG;
-#endif
#ifdef AI_NUMERICSERV
hints.ai_flags |= AI_NUMERICSERV;
#endif
@@ -305,19 +318,42 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
for(addr = results; addr; addr = addr->ai_next)
{
fd = _xcb_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
- if(fd >= 0) {
- int on = 1;
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
- setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
+ if (_xcb_do_connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
+ break;
+ close(fd);
+ fd = -1;
+ }
+ freeaddrinfo(results);
+ return fd;
+#else
+ {
+ struct hostent* _h;
+ struct sockaddr_in _s;
+ struct in_addr ** _c;
+
+ if((_h = gethostbyname(host)) == NULL)
+ return -1;
- if (connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
+ _c = (struct in_addr**)_h->h_addr_list;
+ fd = -1;
+
+ while(*_c) {
+ _s.sin_family = AF_INET;
+ _s.sin_port = htons(port);
+ _s.sin_addr = *(*_c);
+
+ fd = _xcb_socket(_s.sin_family, SOCK_STREAM, 0);
+ if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0)
break;
+
close(fd);
fd = -1;
+ ++_c;
}
+
+ return fd;
}
- freeaddrinfo(results);
- return fd;
+#endif
}
#ifndef _WIN32