diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/fakepoll.c | 23 | ||||
-rw-r--r-- | src/common/util.c | 29 | ||||
-rw-r--r-- | src/common/util.h | 28 |
3 files changed, 67 insertions, 13 deletions
diff --git a/src/common/fakepoll.c b/src/common/fakepoll.c index ec1201a79..17bd18d40 100644 --- a/src/common/fakepoll.c +++ b/src/common/fakepoll.c @@ -8,6 +8,7 @@ #include "orconfig.h" #include "fakepoll.h" + #ifdef USE_FAKE_POLL #include <sys/types.h> #ifdef HAVE_UNISTD_H @@ -30,6 +31,9 @@ poll(struct pollfd *ufds, unsigned int nfds, int timeout) { unsigned int idx, maxfd, fd; int r; +#ifdef MS_WINDOWS + int any_fds_set = 0; +#endif fd_set readfds, writefds, exceptfds; #ifdef USING_FAKE_TIMEVAL #undef timeval @@ -46,15 +50,26 @@ poll(struct pollfd *ufds, unsigned int nfds, int timeout) maxfd = -1; for (idx = 0; idx < nfds; ++idx) { fd = ufds[idx].fd; - if (fd > maxfd && ufds[idx].events) - maxfd = fd; - if (ufds[idx].events & (POLLIN)) + if (ufds[idx].events) { + if (fd > maxfd) + maxfd = fd; +#ifdef MS_WINDOWS + any_fds_set = 1; +#endif + } + if (ufds[idx].events & POLLIN) FD_SET(fd, &readfds); if (ufds[idx].events & POLLOUT) FD_SET(fd, &writefds); - if (ufds[idx].events & (POLLERR)) + if (ufds[idx].events & POLLERR) FD_SET(fd, &exceptfds); } +#ifdef MS_WINDOWS + if (!any_fds_set) { + usleep(timeout); + return 0; + } +#endif r = select(maxfd+1, &readfds, &writefds, &exceptfds, timeout == -1 ? NULL : &_timeout); if (r <= 0) diff --git a/src/common/util.c b/src/common/util.c index 378612d10..dea4b3371 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -4,7 +4,7 @@ #include "../or/or.h" -#ifdef _MSC_VER +#ifdef MS_WINDOWS #include <io.h> #include <limits.h> #include <process.h> @@ -90,7 +90,7 @@ void tv_addms(struct timeval *a, long ms) { void set_socket_nonblocking(int socket) { -#ifdef _MSC_VER +#ifdef MS_WINDOWS /* Yes means no and no means yes. Do you not want to be nonblocking? */ int nonblocking = 0; ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking); @@ -101,7 +101,7 @@ void set_socket_nonblocking(int socket) int spawn_func(int (*func)(void *), void *data) { -#ifdef _MSC_VER +#ifdef MS_WINDOWS int rv; rv = _beginthread(func, 0, data); if (rv == (unsigned long) -1) @@ -125,7 +125,7 @@ int spawn_func(int (*func)(void *), void *data) void spawn_exit() { -#ifdef _MSC_VER +#ifdef MS_WINDOWS _endthread(); #else exit(0); @@ -137,7 +137,7 @@ void spawn_exit() int tor_socketpair(int family, int type, int protocol, int fd[2]) { -#ifdef HAVE_SOCKETPAIR_XXX +#ifdef HAVE_SOCKETPAIR_XXXX /* For testing purposes, we never fall back to real socketpairs. */ return socketpair(family, type, protocol, fd); #else @@ -153,8 +153,8 @@ tor_socketpair(int family, int type, int protocol, int fd[2]) || family != AF_UNIX #endif ) { -#ifdef _MSC_VER - errno = WSAEAFNOSUPPORT; +#ifdef MS_WINDOWS + errno = WSAEAFNOSUPPORT; #else errno = EAFNOSUPPORT; #endif @@ -213,7 +213,7 @@ tor_socketpair(int family, int type, int protocol, int fd[2]) return 0; abort_tidy_up_and_fail: -#ifdef _MSC_VER +#ifdef MS_WINDOWS errno = WSAECONNABORTED; #else errno = ECONNABORTED; /* I hope this is portable and appropriate. */ @@ -232,3 +232,16 @@ tor_socketpair(int family, int type, int protocol, int fd[2]) } #endif } + +#ifdef MS_WINDOWS +int correct_socket_errno(int s) +{ + int r, optval, optvallen=sizeof(optval); + assert(errno == WSAEWOULDBLOCK); + if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen)) + return errno; + if (optval) + return optval; + return WSAEWOULDBLOCK; +} +#endif diff --git a/src/common/util.h b/src/common/util.h index 3569632e9..0590f8ed7 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -13,6 +13,12 @@ #ifdef HAVE_TIME_H #include <time.h> #endif +#if _MSC_VER > 1300 +#include <winsock2.h> +#include <ws2tcpip.h> +#elif defined(_MSC_VER) +#include <winsock.h> +#endif #ifndef HAVE_GETTIMEOFDAY #ifdef HAVE_FTIME #define USING_FAKE_TIMEVAL @@ -23,7 +29,7 @@ #endif #endif -#ifdef _MSC_VER +#ifdef MS_WINDOWS /* Windows names string functions funnily. */ #define strncasecmp strnicmp #define strcasecmp stricmp @@ -55,4 +61,24 @@ void spawn_exit(); int tor_socketpair(int family, int type, int protocol, int fd[2]); +/* For stupid historical reasons, windows sockets have an independent set of + * errnos which they use as the fancy strikes them. + */ +#ifdef MS_WINDOWS +#define ERRNO_EAGAIN(e) ((e) == EAGAIN || \ + (e) == WSAEWOULDBLOCK || \ + (e) == EWOULDBLOCK) +#define ERRNO_EINPROGRESS(e) ((e) == EINPROGRESS || \ + (e) == WSAEINPROGRESS) +#define ERRNO_CONN_EINPROGRESS(e) ((e) == EINPROGRESS || \ + (e) == WSAEINPROGRESS || (e) == WSAEINVAL) +int correct_socket_errno(int s); +#else +#define ERRNO_EAGAIN(e) ((e) == EAGAIN) +#define ERRNO_EINPROGRESS(e) ((e) == EINPROGRESS) +#define ERRNO_CONN_EINPROGRESS(e) ((e) == EINPROGRESS) +#define correct_socket_errno(s) (errno) +#endif + + #endif |