Support pre-IPv6 systems (without getaddrinfo)
Some of these systems (eg. Interix on XP) are still in use. Reviewed-by: Josh Triplett <josh@joshtriplett.org> Signed-off-by: Peter Harris <pharris@opentext.com>
This commit is contained in:
parent
aa02096b8e
commit
163c47bdc0
|
@ -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*) ;;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,6 +291,7 @@ 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_NUMERICSERV
|
||||
hints.ai_flags |= AI_NUMERICSERV;
|
||||
|
@ -302,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 (connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
|
||||
break;
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
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;
|
||||
|
||||
_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;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
|
Loading…
Reference in New Issue