mingw fixes from Nick

svn:r271
This commit is contained in:
Niels Provos 2006-11-22 01:21:10 +00:00
parent 4aa780d6ad
commit 868f10e7c9
9 changed files with 156 additions and 40 deletions

View File

@ -25,11 +25,15 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef _MSC_VER
#include "config.h" #include "config.h"
#else
#include <winsock2.h> /* Avoid the windows/msvc thing. */
#include "../config.h"
#endif
#include <windows.h> #include <windows.h>
#include <winsock2.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/tree.h> #include <sys/tree.h>

View File

@ -132,7 +132,7 @@ AC_C_INLINE
AC_HEADER_TIME AC_HEADER_TIME
dnl Checks for library functions. dnl Checks for library functions.
AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r) AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo)
AC_REPLACE_FUNCS(strlcpy) AC_REPLACE_FUNCS(strlcpy)
if test "x$ac_cv_func_clock_gettime" = "xyes"; then if test "x$ac_cv_func_clock_gettime" = "xyes"; then

17
evdns.c
View File

@ -39,6 +39,10 @@
#include "config.h" #include "config.h"
#endif #endif
#ifdef WIN32
#include "misc.h"
#endif
//#define NDEBUG //#define NDEBUG
#ifndef DNS_USE_CPU_CLOCK_FOR_ID #ifndef DNS_USE_CPU_CLOCK_FOR_ID
@ -235,7 +239,7 @@ static u16 transaction_id_pick(void);
static struct request *request_new(int type, const char *name, int flags, evdns_callback_type callback, void *ptr); static struct request *request_new(int type, const char *name, int flags, evdns_callback_type callback, void *ptr);
static void request_submit(struct request *req); static void request_submit(struct request *req);
#ifdef MS_WINDOWS #if defined(MS_WINDOWS) || defined(WIN32)
static int static int
last_error(int sock) last_error(int sock)
{ {
@ -1275,7 +1279,7 @@ evdns_nameserver_add(unsigned long int address) {
ns->socket = socket(PF_INET, SOCK_DGRAM, 0); ns->socket = socket(PF_INET, SOCK_DGRAM, 0);
if (ns->socket < 0) { err = 1; goto out1; } if (ns->socket < 0) { err = 1; goto out1; }
#ifdef MS_WINDOWS #if defined(MS_WINDOWS) || defined(WIN32)
{ {
u_long nonblocking = 1; u_long nonblocking = 1;
ioctlsocket(ns->socket, FIONBIO, &nonblocking); ioctlsocket(ns->socket, FIONBIO, &nonblocking);
@ -1330,7 +1334,8 @@ out1:
int int
evdns_nameserver_ip_add(const char *ip_as_string) { evdns_nameserver_ip_add(const char *ip_as_string) {
struct in_addr ina; struct in_addr ina;
if (!inet_aton(ip_as_string, &ina)) return 4; if (!inet_aton(ip_as_string, &ina))
return 4;
return evdns_nameserver_add(ina.s_addr); return evdns_nameserver_add(ina.s_addr);
} }
@ -1847,7 +1852,7 @@ out1:
return err; return err;
} }
#ifdef MS_WINDOWS #if defined(MS_WINDOWS) || defined(WIN32)
// Add multiple nameservers from a space-or-comma-separated list. // Add multiple nameservers from a space-or-comma-separated list.
static int static int
evdns_nameserver_ip_add_line(const char *ips) { evdns_nameserver_ip_add_line(const char *ips) {
@ -2043,8 +2048,8 @@ int
evdns_init() evdns_init()
{ {
int res = 0; int res = 0;
#ifdef MS_WINDOWS #if defined(MS_WINDOWS) || defined(WIN32)
evdns_config_windows_nameservers(void); evdns_config_windows_nameservers();
#else #else
res = evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf"); res = evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf");
#endif #endif

View File

@ -38,6 +38,7 @@ extern "C" {
#include <windows.h> #include <windows.h>
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
typedef unsigned char u_char; typedef unsigned char u_char;
typedef unsigned short u_short;
#endif #endif
#define EVLIST_TIMEOUT 0x01 #define EVLIST_TIMEOUT 0x01
@ -191,7 +192,7 @@ void event_active(struct event *, int, short);
int event_pending(struct event *, short, struct timeval *); int event_pending(struct event *, short, struct timeval *);
#ifdef WIN32 #ifdef WIN32
#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT && (ev)->ev_fd != INVALID_HANDLE_VALUE) #define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT && (ev)->ev_fd != (int)INVALID_HANDLE_VALUE)
#else #else
#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) #define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)
#endif #endif

View File

@ -32,7 +32,14 @@
#include "config.h" #include "config.h"
#endif #endif
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#else
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif
#include <sys/tree.h> #include <sys/tree.h>
#include <sys/queue.h> #include <sys/queue.h>
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
@ -43,7 +50,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifndef WIN32
#include <syslog.h> #include <syslog.h>
#endif
#include <unistd.h> #include <unistd.h>
#include "event.h" #include "event.h"

View File

@ -34,8 +34,8 @@ extern "C" {
#ifdef WIN32 #ifdef WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <winsock2.h>
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
typedef unsigned char u_char;
#endif #endif
/* /*

View File

@ -31,12 +31,16 @@
#ifdef WIN32 #ifdef WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <winsock2.h>
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include "misc.h" #include "misc.h"
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/tree.h> #include <sys/tree.h>
#ifndef WIN32
#include <sys/socket.h> #include <sys/socket.h>
#endif
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#else #else

141
http.c
View File

@ -38,22 +38,30 @@
#ifdef HAVE_SYS_IOCCOM_H #ifdef HAVE_SYS_IOCCOM_H
#include <sys/ioccom.h> #include <sys/ioccom.h>
#endif #endif
#ifndef WIN32
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/tree.h>
#include <sys/wait.h> #include <sys/wait.h>
#endif
#include <sys/tree.h>
#include <sys/queue.h> #include <sys/queue.h>
#ifndef WIN32
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#endif
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifndef WIN32
#include <syslog.h> #include <syslog.h>
#endif
#include <signal.h> #include <signal.h>
#ifdef HAVE_TIME_H #ifdef HAVE_TIME_H
#include <time.h> #include <time.h>
@ -69,18 +77,66 @@
#include "log.h" #include "log.h"
#include "http-internal.h" #include "http-internal.h"
#ifndef HAVE_GETADDRINFO
struct addrinfo {
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
struct sockaddr *ai_addr;
struct addrinfo *ai_next;
};
static int
fake_getaddrinfo(const char *hostname, struct addrinfo *ai)
{
struct hostent *he;
he = gethostbyname(hostname);
if (!he)
return (-1);
ai->ai_family = he->h_addrtype;
ai->ai_socktype = SOCK_STREAM;
ai->ai_protocol = 0;
ai->ai_addrlen = he->h_length;
if (NULL == (ai->ai_addr = malloc(ai->ai_addrlen)))
return (-1);
memcpy(ai->ai_addr, &he->h_addr_list[0], ai->ai_addrlen);
ai->ai_next = NULL;
return (0);
}
static void
fake_freeaddrinfo(struct addrinfo *ai)
{
free(ai->ai_addr);
}
#endif
extern int debug; extern int debug;
static int make_socket_ai(int (*f)(int, const struct sockaddr *, socklen_t), static int make_socket_ai(int should_bind, struct addrinfo *);
struct addrinfo *); static int make_socket(int should_bind, const char *, short);
static int make_socket(int (*)(int, const struct sockaddr *, socklen_t),
const char *, short);
static void name_from_addr(struct sockaddr *, socklen_t, char **, char **); static void name_from_addr(struct sockaddr *, socklen_t, char **, char **);
static int evhttp_associate_new_request_with_connection( static int evhttp_associate_new_request_with_connection(
struct evhttp_connection *evcon); struct evhttp_connection *evcon);
void evhttp_write(int, short, void *); void evhttp_write(int, short, void *);
#ifndef HAVE_STRSEP
static char *
strsep(char **s, const char *del)
{
char *d, *tok;
if (!s || !*s)
return NULL;
tok = *s;
d = strstr(tok, del);
if (d)
*s = d + strlen(del);
else
*s = NULL;
return tok;
}
#endif
static const char * static const char *
html_replace(char ch) html_replace(char ch)
{ {
@ -206,7 +262,7 @@ evhttp_make_header_request(struct evhttp_connection *evcon,
evhttp_find_header(req->output_headers, "Content-Length") == NULL){ evhttp_find_header(req->output_headers, "Content-Length") == NULL){
char size[12]; char size[12];
snprintf(size, sizeof(size), "%ld", snprintf(size, sizeof(size), "%ld",
EVBUFFER_LENGTH(req->output_buffer)); (long)EVBUFFER_LENGTH(req->output_buffer));
evhttp_add_header(req->output_headers, "Content-Length", size); evhttp_add_header(req->output_headers, "Content-Length", size);
} }
} }
@ -244,7 +300,7 @@ evhttp_make_header_response(struct evhttp_connection *evcon,
if (evhttp_find_header(req->output_headers, "Content-Length") == NULL){ if (evhttp_find_header(req->output_headers, "Content-Length") == NULL){
static char len[12]; static char len[12];
snprintf(len, sizeof(len), "%ld", snprintf(len, sizeof(len), "%ld",
EVBUFFER_LENGTH(req->output_buffer)); (long)EVBUFFER_LENGTH(req->output_buffer));
evhttp_add_header(req->output_headers, "Content-Length", len); evhttp_add_header(req->output_headers, "Content-Length", len);
} }
@ -593,7 +649,7 @@ evhttp_connectioncb(int fd, short what, void *arg)
} }
/* Check if the connection completed */ /* Check if the connection completed */
if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, &error, if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
&errsz) == -1) { &errsz) == -1) {
event_warn("%s: getsockopt for \"%s:%d\" on %d", event_warn("%s: getsockopt for \"%s:%d\" on %d",
__func__, evcon->address, evcon->port, evcon->fd); __func__, evcon->address, evcon->port, evcon->fd);
@ -1066,7 +1122,7 @@ evhttp_connection_connect(struct evhttp_connection *evcon)
/* Do async connection to HTTP server */ /* Do async connection to HTTP server */
if ((evcon->fd = make_socket( if ((evcon->fd = make_socket(
connect, evcon->address, evcon->port)) == -1) { 0, evcon->address, evcon->port)) == -1) {
event_warn("%s: failed to connect to \"%s:%d\"", event_warn("%s: failed to connect to \"%s:%d\"",
__func__, evcon->address, evcon->port); __func__, evcon->address, evcon->port);
return (-1); return (-1);
@ -1378,7 +1434,7 @@ bind_socket(struct evhttp *http, const char *address, u_short port)
struct event *ev = &http->bind_ev; struct event *ev = &http->bind_ev;
int fd; int fd;
if ((fd = make_socket(bind, address, port)) == -1) if ((fd = make_socket(1, address, port)) == -1)
return (-1); return (-1);
if (listen(fd, 10) == -1) { if (listen(fd, 10) == -1) {
@ -1637,6 +1693,7 @@ evhttp_get_request(struct evhttp *http, int fd,
static struct addrinfo * static struct addrinfo *
addr_from_name(char *address) addr_from_name(char *address)
{ {
#ifdef HAVE_GETADDRINFO
struct addrinfo ai, *aitop; struct addrinfo ai, *aitop;
memset(&ai, 0, sizeof (ai)); memset(&ai, 0, sizeof (ai));
@ -1649,12 +1706,17 @@ addr_from_name(char *address)
} }
return (aitop); return (aitop);
#else
assert(0);
return NULL; // XXXXX Use gethostbyname, if this function is ever used.
#endif
} }
static void static void
name_from_addr(struct sockaddr *sa, socklen_t salen, name_from_addr(struct sockaddr *sa, socklen_t salen,
char **phost, char **pport) char **phost, char **pport)
{ {
#ifdef HAVE_GETNAMEINFO
static char ntop[NI_MAXHOST]; static char ntop[NI_MAXHOST];
static char strport[NI_MAXSERV]; static char strport[NI_MAXSERV];
@ -1665,16 +1727,18 @@ name_from_addr(struct sockaddr *sa, socklen_t salen,
*phost = ntop; *phost = ntop;
*pport = strport; *pport = strport;
#else
// XXXX
#endif
} }
/* Either connect or bind */ /* Either connect or bind */
static int static int
make_socket_ai(int (*f)(int, const struct sockaddr *, socklen_t), make_socket_ai(int should_bind, struct addrinfo *ai)
struct addrinfo *ai)
{ {
struct linger linger; struct linger linger;
int fd, on = 1; int fd, on = 1, r;
int serrno; int serrno;
/* Create listen socket */ /* Create listen socket */
@ -1684,6 +1748,12 @@ make_socket_ai(int (*f)(int, const struct sockaddr *, socklen_t),
return (-1); return (-1);
} }
#ifdef WIN32
{
unsigned long nonblocking = 1;
ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking);
}
#else
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
event_warn("fcntl(O_NONBLOCK)"); event_warn("fcntl(O_NONBLOCK)");
goto out; goto out;
@ -1693,18 +1763,31 @@ make_socket_ai(int (*f)(int, const struct sockaddr *, socklen_t),
event_warn("fcntl(F_SETFD)"); event_warn("fcntl(F_SETFD)");
goto out; goto out;
} }
#endif
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
linger.l_onoff = 1; linger.l_onoff = 1;
linger.l_linger = 5; linger.l_linger = 5;
setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); setsockopt(fd, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
if ((f)(fd, ai->ai_addr, ai->ai_addrlen) == -1) { if (should_bind)
r = bind(fd, ai->ai_addr, ai->ai_addrlen);
else
r = connect(fd, ai->ai_addr, ai->ai_addrlen);
if (r == -1) {
#ifdef WIN32
int tmp_error = WSAGetLastError();
if (tmp_error != WSAEWOULDBLOCK && tmp_error != WSAEINVAL &&
tmp_error != WSAEINPROGRESS) {
goto out;
}
#else
if (errno != EINPROGRESS) { if (errno != EINPROGRESS) {
goto out; goto out;
} }
} #endif
}
return (fd); return (fd);
@ -1716,26 +1799,36 @@ make_socket_ai(int (*f)(int, const struct sockaddr *, socklen_t),
} }
static int static int
make_socket(int (*f)(int, const struct sockaddr *, socklen_t), make_socket(int should_bind, const char *address, short port)
const char *address, short port)
{ {
struct addrinfo ai, *aitop;
char strport[NI_MAXSERV];
int fd; int fd;
struct addrinfo ai, *aitop;
#ifdef HAVE_GETADDRINFO
char strport[NI_MAXSERV];
memset(&ai, 0, sizeof (ai)); memset(&ai, 0, sizeof (ai));
ai.ai_family = AF_INET; ai.ai_family = AF_INET;
ai.ai_socktype = SOCK_STREAM; ai.ai_socktype = SOCK_STREAM;
ai.ai_flags = f != connect ? AI_PASSIVE : 0; ai.ai_flags = should_bind ? AI_PASSIVE : 0;
snprintf(strport, sizeof (strport), "%d", port); snprintf(strport, sizeof (strport), "%d", port);
if (getaddrinfo(address, strport, &ai, &aitop) != 0) { if (getaddrinfo(address, strport, &ai, &aitop) != 0) {
event_warn("getaddrinfo"); event_warn("getaddrinfo");
return (-1); return (-1);
} }
#else
if (fake_getaddrinfo(address, &ai) < 0) {
event_warn("fake_getaddrinfo");
return (-1);
}
aitop = &ai;
#endif
fd = make_socket_ai(f, aitop); fd = make_socket_ai(should_bind, aitop);
#ifdef HAVE_GETADDRINFO
freeaddrinfo(aitop); freeaddrinfo(aitop);
#else
fake_freeaddrinfo(aitop);
#endif
return (fd); return (fd);
} }