rendered paste body--- linux/net_posix.c 2011-04-30 00:03:11.082316000 +0200+++ windows/net_winsock.c 2011-04-30 00:08:43.142316001 +0200@@ -1,6 +1,7 @@ /*- * Networking under POSIX+ * Networking under WINDOWS * Copyright (C) 2007-2008 Andreas Öman+ * Copyright (C) 2007-2008 Joakim Plate * Copyright (C) 2011 Team XBMC * * This program is free software; you can redistribute it and/or@@ -18,28 +19,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifdef __APPLE__-/* Needed on Mac OS/X */-#ifndef SOL_TCP-#define SOL_TCP IPPROTO_TCP-#endif-#include "OSXGNUReplacements.h"-#elif defined(__FreeBSD__)-#ifndef SOL_TCP-#define SOL_TCP IPPROTO_TCP-#endif-#else-#include <sys/epoll.h>-#endif #include <stdio.h>-#include <unistd.h> #include <stdlib.h> #include <string.h> #include <stdarg.h>-#include <fcntl.h> #include "../os-dependent_socket.h" +#ifndef EINPROGRESS+#define EINPROGRESS WSAEINPROGRESS+#endif++#ifndef ECONNRESET+#define ECONNRESET WSAECONNRESET+#endif++#ifndef EAGAIN+#define EAGAIN WSAEWOULDBLOCK+#endif++#ifndef EINVAL+#define EINVAL WSAEINVAL+#endif++#ifndef MSG_WAITALL+#define MSG_WAITALL 0x8+#endif++static int recv_fixed (SOCKET fdSock, char * szBuf, int nLen, int nFlags)+{+ char* org = szBuf;+ int nRes = 1;++ if ((nFlags & MSG_WAITALL) == 0)+ return recv(fdSock, szBuf, nLen, nFlags);++ nFlags &= ~MSG_WAITALL;+ while(nLen > 0 && nRes > 0)+ {+ nRes = recv(fdSock, szBuf, nLen, nFlags);+ if (nRes < 0)+ return nRes;++ szBuf += nRes;+ nLen -= nRes;+ }+ return szBuf - org;+}++#define recv(fdSock, szBuf, nLen, nFlags) recv_fixed(fdSock, szBuf, nLen, nFlags)+ int tcp_connect_poll(struct addrinfo* addr, socket_t fdSock, char *szErrbuf, size_t nErrbufSize, int nTimeout)@@ -48,7 +77,8 @@ socklen_t errlen = sizeof(int); /* switch to non blocking */- fcntl(fdSock, F_SETFL, fcntl(fdSock, F_GETFL) | O_NONBLOCK);+ int nVal = 1;+ ioctlsocket(fdSock, FIONBIO, &nVal); /* connect to the other side */ nRes = connect(fdSock, addr->ai_addr, addr->ai_addrlen);@@ -56,22 +86,29 @@ /* poll until a connection is established */ if (nRes == -1) {- if (errno == EINPROGRESS)+ if (WSAGetLastError() == EINPROGRESS ||+ WSAGetLastError() == EAGAIN) {- struct pollfd pfd;- pfd.fd = fdSock;- pfd.events = POLLOUT;- pfd.revents = 0;+ fd_set fd_write, fd_except;+ struct timeval tv;+ tv.tv_sec = nTimeout / 1000;+ tv.tv_usec = 1000 * (nTimeout % 1000);++ FD_ZERO(&fd_write);+ FD_ZERO(&fd_except);+ FD_SET(fdSock, &fd_write);+ FD_SET(fdSock, &fd_except); - nRes = poll(&pfd, 1, nTimeout);+ nRes = select((int)fdSock+1, NULL, &fd_write, &fd_except, &tv); if (nRes == 0) {- snprintf(szErrbuf, nErrbufSize, "attempt timed out after %d milliseconds", nTimeout);+ _snprintf(szErrbuf, nErrbufSize, "attempt timed out after %d milliseconds", nTimeout); return SOCKET_ERROR; }+ else if (nRes == -1) {- snprintf(szErrbuf, nErrbufSize, "poll() error '%s'", strerror(errno));+ _snprintf(szErrbuf, nErrbufSize, "select() error: %s", strerror(WSAGetLastError())); return SOCKET_ERROR; } @@ -80,18 +117,18 @@ } else {- nErr = errno;+ nErr = WSAGetLastError(); } } if (nErr != 0) {- snprintf(szErrbuf, nErrbufSize, "%s", strerror(nErr));+ _snprintf(szErrbuf, nErrbufSize, "%s", strerror(nErr)); return SOCKET_ERROR; } - /* switch back to blocking */- fcntl(fdSock, F_SETFL, fcntl(fdSock, F_GETFL) & ~O_NONBLOCK);+ nVal = 0;+ ioctlsocket(fdSock, FIONBIO, &nVal); return 0; }@@ -107,20 +144,20 @@ fdSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (fdSock == -1) {- snprintf(szErrbuf, nErrbufSize, "Unable to create socket: %s", strerror(errno));+ _snprintf(szErrbuf, nErrbufSize, "Unable to create socket: %s", strerror(WSAGetLastError())); return SOCKET_ERROR; } /* connect to the socket */ if (tcp_connect_poll(addr, fdSock, szErrbuf, nErrbufSize, nTimeout) != 0) {- close(fdSock);+ closesocket(fdSock); return SOCKET_ERROR; } /* set TCP_NODELAY socket option */ nVal = 1;- setsockopt(fdSock, SOL_TCP, TCP_NODELAY, &nVal, sizeof(nVal));+ setsockopt(fdSock, IPPROTO_TCP, TCP_NODELAY, (const char*)&nVal, sizeof(nVal)); return fdSock; }@@ -147,23 +184,23 @@ switch(nRes) { case EAI_NONAME:- snprintf(szErrbuf, nErrbufSize, "the specified host is unknown");+ _snprintf(szErrbuf, nErrbufSize, "the specified host is unknown"); break; case EAI_FAIL:- snprintf(szErrbuf, nErrbufSize, "a nonrecoverable failure in name resolution occurred");+ _snprintf(szErrbuf, nErrbufSize, "a nonrecoverable failure in name resolution occurred"); break; case EAI_MEMORY:- snprintf(szErrbuf, nErrbufSize, "a memory allocation failure occurred");+ _snprintf(szErrbuf, nErrbufSize, "a memory allocation failure occurred"); break; case EAI_AGAIN:- snprintf(szErrbuf, nErrbufSize, "a temporary error occurred on an authoritative name server");+ _snprintf(szErrbuf, nErrbufSize, "a temporary error occurred on an authoritative name server"); break; default:- snprintf(szErrbuf, nErrbufSize, "unknown error %d", nRes);+ _snprintf(szErrbuf, nErrbufSize, "unknown error %d", nRes); break; } @@ -187,7 +224,7 @@ int x = recv(fdSock, buf, nLen, MSG_WAITALL); if (x == -1)- return errno;+ return WSAGetLastError(); if (x != (int)nLen) return ECONNRESET; @@ -198,27 +235,40 @@ tcp_read_timeout(socket_t fdSock, void *buf, size_t nLen, int nTimeout) { int x, tot = 0;- struct pollfd fds;+ int nVal, nErr;+ fd_set fd_read;+ struct timeval tv; if (nTimeout <= 0) return EINVAL; - fds.fd = fdSock;- fds.events = POLLIN;- fds.revents = 0;- while(tot != (int)nLen) {- x = poll(&fds, 1, nTimeout);+ tv.tv_sec = nTimeout / 1000;+ tv.tv_usec = 1000 * (nTimeout % 1000);++ FD_ZERO(&fd_read);+ FD_SET(fdSock, &fd_read);++ x = select((int)fdSock+1, &fd_read, NULL, NULL, &tv);+ if (x == 0) return ETIMEDOUT; - x = recv(fdSock, buf + tot, nLen - tot, MSG_DONTWAIT);+ nVal = 1;+ ioctlsocket(fdSock, FIONBIO, &nVal);++ x = recv(fdSock, (char *)buf + tot, nLen - tot, 0);+ nErr = WSAGetLastError();++ nVal = 0;+ ioctlsocket(fdSock, FIONBIO, &nVal);+ if (x == -1) {- if (errno == EAGAIN)+ if (nErr == EAGAIN) continue;- return errno;+ return nErr; } if (x == 0)@@ -233,5 +283,5 @@ tcp_close(socket_t fdSock) { if (fdSock != SOCKET_ERROR)- close(fdSock);+ closesocket(fdSock); }