All pastes #2052042 Raw Edit

Zoolooc

public text v1 · immutable
#2052042 ·published 2011-04-29 22:24 UTC
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); }