Home | History | Annotate | Download | only in platform
      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2014 Karlson2k (Evgeny Grin)
      4 
      5   This library is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU Lesser General Public
      7   License as published by the Free Software Foundation; either
      8   version 2.1 of the License, or (at your option) any later version.
      9 
     10   This library is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with this library.
     17   If not, see <http://www.gnu.org/licenses/>.
     18 */
     19 
     20 /**
     21  * @file platform/w32functions.h
     22  * @brief  internal functions for W32 systems
     23  * @author Karlson2k (Evgeny Grin)
     24  */
     25 
     26 #include "w32functions.h"
     27 #include <errno.h>
     28 #include <winsock2.h>
     29 #include <string.h>
     30 #include <stdint.h>
     31 #include <time.h>
     32 #include <stdio.h>
     33 #include <stdarg.h>
     34 
     35 
     36 /**
     37  * Return errno equivalent of last winsock error
     38  * @return errno equivalent of last winsock error
     39  */
     40 int MHD_W32_errno_from_winsock_(void)
     41 {
     42   switch(WSAGetLastError())
     43   {
     44   case 0:                      return 0;
     45   case WSA_INVALID_HANDLE:     return EBADF;
     46   case WSA_NOT_ENOUGH_MEMORY:  return ENOMEM;
     47   case WSA_INVALID_PARAMETER:  return EINVAL;
     48   case WSAEINTR:               return EINTR;
     49   case WSAEWOULDBLOCK:         return EWOULDBLOCK;
     50   case WSAEINPROGRESS:         return EINPROGRESS;
     51   case WSAEALREADY:            return EALREADY;
     52   case WSAENOTSOCK:            return ENOTSOCK;
     53   case WSAEDESTADDRREQ:        return EDESTADDRREQ;
     54   case WSAEMSGSIZE:            return EMSGSIZE;
     55   case WSAEPROTOTYPE:          return EPROTOTYPE;
     56   case WSAENOPROTOOPT:         return ENOPROTOOPT;
     57   case WSAEPROTONOSUPPORT:     return EPROTONOSUPPORT;
     58   case WSAESOCKTNOSUPPORT:     return ESOCKTNOSUPPORT;
     59   case WSAEOPNOTSUPP:          return EOPNOTSUPP;
     60   case WSAEPFNOSUPPORT:        return EPFNOSUPPORT;
     61   case WSAEAFNOSUPPORT:        return EAFNOSUPPORT;
     62   case WSAEADDRINUSE:          return EADDRINUSE;
     63   case WSAEADDRNOTAVAIL:       return EADDRNOTAVAIL;
     64   case WSAENETDOWN:            return ENETDOWN;
     65   case WSAENETUNREACH:         return ENETUNREACH;
     66   case WSAENETRESET:           return ENETRESET;
     67   case WSAECONNABORTED:        return ECONNABORTED;
     68   case WSAECONNRESET:          return ECONNRESET;
     69   case WSAENOBUFS:             return ENOBUFS;
     70   case WSAEISCONN:             return EISCONN;
     71   case WSAENOTCONN:            return ENOTCONN;
     72   case WSAESHUTDOWN:           return ESHUTDOWN;
     73   case WSAETOOMANYREFS:        return ETOOMANYREFS;
     74   case WSAETIMEDOUT:           return ETIMEDOUT;
     75   case WSAECONNREFUSED:        return ECONNREFUSED;
     76   case WSAELOOP:               return ELOOP;
     77   case WSAENAMETOOLONG:        return ENAMETOOLONG;
     78   case WSAEHOSTDOWN:           return EHOSTDOWN;
     79   case WSAEHOSTUNREACH:        return EHOSTUNREACH;
     80   case WSAENOTEMPTY:           return ENOTEMPTY;
     81   case WSAEPROCLIM:            return EPROCLIM;
     82   case WSAEUSERS:              return EUSERS;
     83   case WSAEDQUOT:              return EDQUOT;
     84   case WSAESTALE:              return ESTALE;
     85   case WSAEREMOTE:             return EREMOTE;
     86   case WSAEINVAL:              return EINVAL;
     87   case WSAEFAULT:              return EFAULT;
     88   case WSANO_DATA:             return ENODATA;
     89   /* Rough equivalents */
     90   case WSAEDISCON:             return ECONNRESET;
     91   case WSAEINVALIDPROCTABLE:   return EFAULT;
     92   case WSASYSNOTREADY:
     93   case WSANOTINITIALISED:
     94   case WSASYSCALLFAILURE:      return ENOBUFS;
     95   case WSAVERNOTSUPPORTED:     return EOPNOTSUPP;
     96   case WSAEREFUSED:            return EIO;
     97   }
     98   return EINVAL;
     99 }
    100 
    101 /**
    102  * Return pointer to string description of errnum error
    103  * Works fine with both standard errno errnums
    104  * and errnums from MHD_W32_errno_from_winsock_
    105  * @param errnum the errno or value from MHD_W32_errno_from_winsock_()
    106  * @return pointer to string description of error
    107  */
    108 const char* MHD_W32_strerror_(int errnum)
    109 {
    110   switch(errnum)
    111   {
    112   case 0:
    113     return "No error";
    114   case EWOULDBLOCK:
    115     return "Operation would block";
    116   case EINPROGRESS:
    117     return "Connection already in progress";
    118   case EALREADY:
    119     return "Socket already connected";
    120   case ENOTSOCK:
    121     return "Socket operation on non-socket";
    122   case EDESTADDRREQ:
    123     return "Destination address required";
    124   case EMSGSIZE:
    125     return "Message too long";
    126   case EPROTOTYPE:
    127     return "Protocol wrong type for socket";
    128   case ENOPROTOOPT:
    129     return "Protocol not available";
    130   case EPROTONOSUPPORT:
    131     return "Unknown protocol";
    132   case ESOCKTNOSUPPORT:
    133     return "Socket type not supported";
    134   case EOPNOTSUPP:
    135     return "Operation not supported on socket";
    136   case EPFNOSUPPORT:
    137     return "Protocol family not supported";
    138   case EAFNOSUPPORT:
    139     return "Address family not supported by protocol family";
    140   case EADDRINUSE:
    141     return "Address already in use";
    142   case EADDRNOTAVAIL:
    143     return "Cannot assign requested address";
    144   case ENETDOWN:
    145     return "Network is down";
    146   case ENETUNREACH:
    147     return "Network is unreachable";
    148   case ENETRESET:
    149     return "Network dropped connection on reset";
    150   case ECONNABORTED:
    151     return "Software caused connection abort";
    152   case ECONNRESET:
    153     return "Connection reset by peer";
    154   case ENOBUFS:
    155     return "No system resources available";
    156   case EISCONN:
    157     return "Socket is already connected";
    158   case ENOTCONN:
    159     return "Socket is not connected";
    160   case ESHUTDOWN:
    161     return "Can't send after socket shutdown";
    162   case ETOOMANYREFS:
    163     return "Too many references: cannot splice";
    164   case ETIMEDOUT:
    165     return "Connection timed out";
    166   case ECONNREFUSED:
    167     return "Connection refused";
    168   case ELOOP:
    169     return "Cannot translate name";
    170   case EHOSTDOWN:
    171     return "Host is down";
    172   case EHOSTUNREACH:
    173     return "Host is unreachable";
    174   case EPROCLIM:
    175     return "Too many processes";
    176   case EUSERS:
    177     return "Too many users";
    178   case EDQUOT:
    179     return "Disk quota exceeded";
    180   case ESTALE:
    181     return "Stale file handle reference";
    182   case EREMOTE:
    183     return "Resource is remote";
    184   case ENODATA:
    185     return "No data available";
    186   }
    187   return strerror(errnum);
    188 }
    189 
    190 /**
    191  * Return pointer to string description of last winsock error
    192  * @return pointer to string description of last winsock error
    193  */
    194 const char* MHD_W32_strerror_last_winsock_(void)
    195 {
    196   switch (WSAGetLastError())
    197     {
    198   case 0:
    199     return "No error";
    200   case WSA_INVALID_HANDLE:
    201     return "Specified event object handle is invalid";
    202   case WSA_NOT_ENOUGH_MEMORY:
    203     return "Insufficient memory available";
    204   case WSA_INVALID_PARAMETER:
    205     return "One or more parameters are invalid";
    206   case WSA_OPERATION_ABORTED:
    207     return "Overlapped operation aborted";
    208   case WSA_IO_INCOMPLETE:
    209     return "Overlapped I/O event object not in signaled state";
    210   case WSA_IO_PENDING:
    211     return "Overlapped operations will complete later";
    212   case WSAEINTR:
    213     return "Interrupted function call";
    214   case WSAEBADF:
    215     return "File handle is not valid";
    216   case WSAEACCES:
    217     return "Permission denied";
    218   case WSAEFAULT:
    219     return "Bad address";
    220   case WSAEINVAL:
    221     return "Invalid argument";
    222   case WSAEMFILE:
    223     return "Too many open files";
    224   case WSAEWOULDBLOCK:
    225     return "Resource temporarily unavailable";
    226   case WSAEINPROGRESS:
    227     return "Operation now in progress";
    228   case WSAEALREADY:
    229     return "Operation already in progress";
    230   case WSAENOTSOCK:
    231     return "Socket operation on nonsocket";
    232   case WSAEDESTADDRREQ:
    233     return "Destination address required";
    234   case WSAEMSGSIZE:
    235     return "Message too long";
    236   case WSAEPROTOTYPE:
    237     return "Protocol wrong type for socket";
    238   case WSAENOPROTOOPT:
    239     return "Bad protocol option";
    240   case WSAEPROTONOSUPPORT:
    241     return "Protocol not supported";
    242   case WSAESOCKTNOSUPPORT:
    243     return "Socket type not supported";
    244   case WSAEOPNOTSUPP:
    245     return "Operation not supported";
    246   case WSAEPFNOSUPPORT:
    247     return "Protocol family not supported";
    248   case WSAEAFNOSUPPORT:
    249     return "Address family not supported by protocol family";
    250   case WSAEADDRINUSE:
    251     return "Address already in use";
    252   case WSAEADDRNOTAVAIL:
    253     return "Cannot assign requested address";
    254   case WSAENETDOWN:
    255     return "Network is down";
    256   case WSAENETUNREACH:
    257     return "Network is unreachable";
    258   case WSAENETRESET:
    259     return "Network dropped connection on reset";
    260   case WSAECONNABORTED:
    261     return "Software caused connection abort";
    262   case WSAECONNRESET:
    263     return "Connection reset by peer";
    264   case WSAENOBUFS:
    265     return "No buffer space available";
    266   case WSAEISCONN:
    267     return "Socket is already connected";
    268   case WSAENOTCONN:
    269     return "Socket is not connected";
    270   case WSAESHUTDOWN:
    271     return "Cannot send after socket shutdown";
    272   case WSAETOOMANYREFS:
    273     return "Too many references";
    274   case WSAETIMEDOUT:
    275     return "Connection timed out";
    276   case WSAECONNREFUSED:
    277     return "Connection refused";
    278   case WSAELOOP:
    279     return "Cannot translate name";
    280   case WSAENAMETOOLONG:
    281     return "Name too long";
    282   case WSAEHOSTDOWN:
    283     return "Host is down";
    284   case WSAEHOSTUNREACH:
    285     return "No route to host";
    286   case WSAENOTEMPTY:
    287     return "Directory not empty";
    288   case WSAEPROCLIM:
    289     return "Too many processes";
    290   case WSAEUSERS:
    291     return "User quota exceeded";
    292   case WSAEDQUOT:
    293     return "Disk quota exceeded";
    294   case WSAESTALE:
    295     return "Stale file handle reference";
    296   case WSAEREMOTE:
    297     return "Item is remote";
    298   case WSASYSNOTREADY:
    299     return "Network subsystem is unavailable";
    300   case WSAVERNOTSUPPORTED:
    301     return "Winsock.dll version out of range";
    302   case WSANOTINITIALISED:
    303     return "Successful WSAStartup not yet performed";
    304   case WSAEDISCON:
    305     return "Graceful shutdown in progress";
    306   case WSAENOMORE:
    307     return "No more results";
    308   case WSAECANCELLED:
    309     return "Call has been canceled";
    310   case WSAEINVALIDPROCTABLE:
    311     return "Procedure call table is invalid";
    312   case WSAEINVALIDPROVIDER:
    313     return "Service provider is invalid";
    314   case WSAEPROVIDERFAILEDINIT:
    315     return "Service provider failed to initialize";
    316   case WSASYSCALLFAILURE:
    317     return "System call failure";
    318   case WSASERVICE_NOT_FOUND:
    319     return "Service not found";
    320   case WSATYPE_NOT_FOUND:
    321     return "Class type not found";
    322   case WSA_E_NO_MORE:
    323     return "No more results";
    324   case WSA_E_CANCELLED:
    325     return "Call was canceled";
    326   case WSAEREFUSED:
    327     return "Database query was refused";
    328   case WSAHOST_NOT_FOUND:
    329     return "Host not found";
    330   case WSATRY_AGAIN:
    331     return "Nonauthoritative host not found";
    332   case WSANO_RECOVERY:
    333     return "This is a nonrecoverable error";
    334   case WSANO_DATA:
    335     return "Valid name, no data record of requested type";
    336   case WSA_QOS_RECEIVERS:
    337     return "QoS receivers";
    338   case WSA_QOS_SENDERS:
    339     return "QoS senders";
    340   case WSA_QOS_NO_SENDERS:
    341     return "No QoS senders";
    342   case WSA_QOS_NO_RECEIVERS:
    343     return "QoS no receivers";
    344   case WSA_QOS_REQUEST_CONFIRMED:
    345     return "QoS request confirmed";
    346   case WSA_QOS_ADMISSION_FAILURE:
    347     return "QoS admission error";
    348   case WSA_QOS_POLICY_FAILURE:
    349     return "QoS policy failure";
    350   case WSA_QOS_BAD_STYLE:
    351     return "QoS bad style";
    352   case WSA_QOS_BAD_OBJECT:
    353     return "QoS bad object";
    354   case WSA_QOS_TRAFFIC_CTRL_ERROR:
    355     return "QoS traffic control error";
    356   case WSA_QOS_GENERIC_ERROR:
    357     return "QoS generic error";
    358   case WSA_QOS_ESERVICETYPE:
    359     return "QoS service type error";
    360   case WSA_QOS_EFLOWSPEC:
    361     return "QoS flowspec error";
    362   case WSA_QOS_EPROVSPECBUF:
    363     return "Invalid QoS provider buffer";
    364   case WSA_QOS_EFILTERSTYLE:
    365     return "Invalid QoS filter style";
    366   case WSA_QOS_EFILTERTYPE:
    367     return "Invalid QoS filter type";
    368   case WSA_QOS_EFILTERCOUNT:
    369     return "Incorrect QoS filter count";
    370   case WSA_QOS_EOBJLENGTH:
    371     return "Invalid QoS object length";
    372   case WSA_QOS_EFLOWCOUNT:
    373     return "Incorrect QoS flow count";
    374   case WSA_QOS_EUNKOWNPSOBJ:
    375     return "Unrecognized QoS object";
    376   case WSA_QOS_EPOLICYOBJ:
    377     return "Invalid QoS policy object";
    378   case WSA_QOS_EFLOWDESC:
    379     return "Invalid QoS flow descriptor";
    380   case WSA_QOS_EPSFLOWSPEC:
    381     return "Invalid QoS provider-specific flowspec";
    382   case WSA_QOS_EPSFILTERSPEC:
    383     return "Invalid QoS provider-specific filterspec";
    384   case WSA_QOS_ESDMODEOBJ:
    385     return "Invalid QoS shape discard mode object";
    386   case WSA_QOS_ESHAPERATEOBJ:
    387     return "Invalid QoS shaping rate object";
    388   case WSA_QOS_RESERVED_PETYPE:
    389     return "Reserved policy QoS element type";
    390     }
    391   return "Unknown winsock error";
    392 }
    393 
    394 /**
    395  * Set last winsock error to equivalent of given errno value
    396  * @param errnum the errno value to set
    397  */
    398 void MHD_W32_set_last_winsock_error_(int errnum)
    399 {
    400   switch (errnum)
    401     {
    402   case 0:
    403     WSASetLastError(0);
    404     break;
    405   case EBADF:
    406     WSASetLastError(WSA_INVALID_HANDLE);
    407     break;
    408   case ENOMEM:
    409     WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
    410     break;
    411   case EINVAL:
    412     WSASetLastError(WSA_INVALID_PARAMETER);
    413     break;
    414   case EINTR:
    415     WSASetLastError(WSAEINTR);
    416     break;
    417   case EWOULDBLOCK:
    418     WSASetLastError(WSAEWOULDBLOCK);
    419     break;
    420   case EINPROGRESS:
    421     WSASetLastError(WSAEINPROGRESS);
    422     break;
    423   case EALREADY:
    424     WSASetLastError(WSAEALREADY);
    425     break;
    426   case ENOTSOCK:
    427     WSASetLastError(WSAENOTSOCK);
    428     break;
    429   case EDESTADDRREQ:
    430     WSASetLastError(WSAEDESTADDRREQ);
    431     break;
    432   case EMSGSIZE:
    433     WSASetLastError(WSAEMSGSIZE);
    434     break;
    435   case EPROTOTYPE:
    436     WSASetLastError(WSAEPROTOTYPE);
    437     break;
    438   case ENOPROTOOPT:
    439     WSASetLastError(WSAENOPROTOOPT);
    440     break;
    441   case EPROTONOSUPPORT:
    442     WSASetLastError(WSAEPROTONOSUPPORT);
    443     break;
    444   case ESOCKTNOSUPPORT:
    445     WSASetLastError(WSAESOCKTNOSUPPORT);
    446     break;
    447   case EOPNOTSUPP:
    448     WSASetLastError(WSAEOPNOTSUPP);
    449     break;
    450   case EPFNOSUPPORT:
    451     WSASetLastError(WSAEPFNOSUPPORT);
    452     break;
    453   case EAFNOSUPPORT:
    454     WSASetLastError(WSAEAFNOSUPPORT);
    455     break;
    456   case EADDRINUSE:
    457     WSASetLastError(WSAEADDRINUSE);
    458     break;
    459   case EADDRNOTAVAIL:
    460     WSASetLastError(WSAEADDRNOTAVAIL);
    461     break;
    462   case ENETDOWN:
    463     WSASetLastError(WSAENETDOWN);
    464     break;
    465   case ENETUNREACH:
    466     WSASetLastError(WSAENETUNREACH);
    467     break;
    468   case ENETRESET:
    469     WSASetLastError(WSAENETRESET);
    470     break;
    471   case ECONNABORTED:
    472     WSASetLastError(WSAECONNABORTED);
    473     break;
    474   case ECONNRESET:
    475     WSASetLastError(WSAECONNRESET);
    476     break;
    477   case ENOBUFS:
    478     WSASetLastError(WSAENOBUFS);
    479     break;
    480   case EISCONN:
    481     WSASetLastError(WSAEISCONN);
    482     break;
    483   case ENOTCONN:
    484     WSASetLastError(WSAENOTCONN);
    485     break;
    486   case ESHUTDOWN:
    487     WSASetLastError(WSAESHUTDOWN);
    488     break;
    489   case ETOOMANYREFS:
    490     WSASetLastError(WSAETOOMANYREFS);
    491     break;
    492   case ETIMEDOUT:
    493     WSASetLastError(WSAETIMEDOUT);
    494     break;
    495   case ECONNREFUSED:
    496     WSASetLastError(WSAECONNREFUSED);
    497     break;
    498   case ELOOP:
    499     WSASetLastError(WSAELOOP);
    500     break;
    501   case ENAMETOOLONG:
    502     WSASetLastError(WSAENAMETOOLONG);
    503     break;
    504   case EHOSTDOWN:
    505     WSASetLastError(WSAEHOSTDOWN);
    506     break;
    507   case EHOSTUNREACH:
    508     WSASetLastError(WSAEHOSTUNREACH);
    509     break;
    510   case ENOTEMPTY:
    511     WSASetLastError(WSAENOTEMPTY);
    512     break;
    513   case EPROCLIM:
    514     WSASetLastError(WSAEPROCLIM);
    515     break;
    516   case EUSERS:
    517     WSASetLastError(WSAEUSERS);
    518     break;
    519   case EDQUOT:
    520     WSASetLastError(WSAEDQUOT);
    521     break;
    522   case ESTALE:
    523     WSASetLastError(WSAESTALE);
    524     break;
    525   case EREMOTE:
    526     WSASetLastError(WSAEREMOTE);
    527     break;
    528   case EFAULT:
    529     WSASetLastError(WSAEFAULT);
    530     break;
    531   case ENODATA:
    532     WSASetLastError(WSANO_DATA);
    533     break;
    534 #if EAGAIN != EWOULDBLOCK
    535   case EAGAIN:
    536     WSASetLastError(WSAEWOULDBLOCK);
    537     break;
    538 #endif
    539   /* Rough equivalent */
    540   case EIO:
    541     WSASetLastError(WSAEREFUSED);
    542     break;
    543 
    544   default: /* Unmapped errors */
    545     WSASetLastError(WSAENOBUFS);
    546     break;
    547     }
    548 }
    549 
    550 /**
    551  * Create pair of mutually connected TCP/IP sockets on loopback address
    552  * @param sockets_pair array to receive resulted sockets
    553  * @return zero on success, -1 otherwise
    554  */
    555 int MHD_W32_pair_of_sockets_(SOCKET sockets_pair[2])
    556 {
    557   int i;
    558   if (!sockets_pair)
    559     {
    560       errno = EINVAL;
    561       return -1;
    562     }
    563 
    564 #define PAIRMAXTRYIES 800
    565   for (i = 0; i < PAIRMAXTRYIES; i++)
    566     {
    567       struct sockaddr_in listen_addr;
    568       SOCKET listen_s;
    569       static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
    570       int addr_len = c_addinlen;
    571       int opt = 1;
    572 
    573       listen_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    574       if (INVALID_SOCKET == listen_s)
    575         break; /* can't create even single socket */
    576 
    577       listen_addr.sin_family = AF_INET;
    578       listen_addr.sin_port = htons(0);
    579       listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    580       if (0 == bind(listen_s, (struct sockaddr*) &listen_addr, c_addinlen)
    581           && 0 == listen(listen_s, 1)
    582           && 0 == getsockname(listen_s, (struct sockaddr*) &listen_addr,
    583                   &addr_len))
    584         {
    585           SOCKET client_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    586           if (INVALID_SOCKET != client_s)
    587             {
    588               if (0 == ioctlsocket(client_s, FIONBIO, (u_long*) &opt)
    589                   && (0 == connect(client_s, (struct sockaddr*) &listen_addr, c_addinlen)
    590                       || WSAGetLastError() == WSAEWOULDBLOCK))
    591                 {
    592                   struct sockaddr_in accepted_from_addr;
    593                   addr_len = c_addinlen;
    594                   SOCKET server_s = accept(listen_s,
    595                       (struct sockaddr*) &accepted_from_addr, &addr_len);
    596                   if (INVALID_SOCKET != server_s)
    597                     {
    598                       struct sockaddr_in client_addr;
    599                       addr_len = c_addinlen;
    600                       opt = 0;
    601                       if (0 == getsockname(client_s, (struct sockaddr*) &client_addr, &addr_len)
    602                           && accepted_from_addr.sin_family == client_addr.sin_family
    603                           && accepted_from_addr.sin_port == client_addr.sin_port
    604                           && accepted_from_addr.sin_addr.s_addr == client_addr.sin_addr.s_addr
    605                           && 0 == ioctlsocket(client_s, FIONBIO, (u_long*) &opt)
    606                           && 0 == ioctlsocket(server_s, FIONBIO, (u_long*) &opt))
    607                         {
    608                           closesocket(listen_s);
    609                           sockets_pair[0] = client_s;
    610                           sockets_pair[1] = server_s;
    611                           return 0;
    612                         }
    613                       closesocket(server_s);
    614                     }
    615                 }
    616               closesocket(client_s);
    617             }
    618         }
    619       closesocket(listen_s);
    620     }
    621 
    622   sockets_pair[0] = INVALID_SOCKET;
    623   sockets_pair[1] = INVALID_SOCKET;
    624   return -1;
    625 }
    626 
    627 /**
    628  * Static variable used by pseudo random number generator
    629  */
    630 static int32_t rnd_val = 0;
    631 /**
    632  * Generate 31-bit pseudo random number.
    633  * Function initialize itself at first call to current time.
    634  * @return 31-bit pseudo random number.
    635  */
    636 int MHD_W32_random_(void)
    637 {
    638   if (0 == rnd_val)
    639     rnd_val = (int32_t)time(NULL);
    640   /* stolen from winsup\cygwin\random.cc */
    641   rnd_val = (16807 * (rnd_val % 127773) - 2836 * (rnd_val / 127773))
    642                & 0x7fffffff;
    643   return (int)rnd_val;
    644 }
    645 
    646 /* Emulate snprintf function on W32 */
    647 int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ...)
    648 {
    649   int ret;
    650   va_list args;
    651   if (0 != n && NULL != s )
    652   {
    653     va_start(args, format);
    654     ret = _vsnprintf(s, n, format, args);
    655     va_end(args);
    656     if (n == ret)
    657       s[n - 1] = 0;
    658     if (ret >= 0)
    659       return ret;
    660   }
    661   va_start(args, format);
    662   ret = _vscprintf(format, args);
    663   va_end(args);
    664   if (0 <= ret && 0 != n && NULL == s)
    665     return -1;
    666 
    667   return ret;
    668 }
    669 
    670 #ifdef _MSC_FULL_VER
    671 /**
    672  * Set thread name
    673  * @param thread_id ID of thread, -1 for current thread
    674  * @param thread_name name to set
    675  */
    676 void W32_SetThreadName(const DWORD thread_id, const char *thread_name)
    677 {
    678   static const DWORD VC_SETNAME_EXC = 0x406D1388;
    679 #pragma pack(push,8)
    680   struct thread_info_struct
    681   {
    682     DWORD type;   // Must be 0x1000.
    683     LPCSTR name;  // Pointer to name (in user address space).
    684     DWORD ID;     // Thread ID (-1=caller thread).
    685     DWORD flags;  // Reserved for future use, must be zero.
    686   } thread_info;
    687 #pragma pack(pop)
    688 
    689   if (NULL == thread_name)
    690     return;
    691 
    692   thread_info.type  = 0x1000;
    693   thread_info.name  = thread_name;
    694   thread_info.ID    = thread_id;
    695   thread_info.flags = 0;
    696 
    697   __try
    698   { /* This exception is intercepted by debugger */
    699     RaiseException(VC_SETNAME_EXC, 0, sizeof(thread_info) / sizeof(ULONG_PTR), (ULONG_PTR*)&thread_info);
    700   }
    701   __except (EXCEPTION_EXECUTE_HANDLER)
    702   {}
    703 }
    704 #endif /* _MSC_FULL_VER */
    705