aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/fakepoll.c23
-rw-r--r--src/common/util.c29
-rw-r--r--src/common/util.h28
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