@@ -1965,26 +1965,158 @@ static void ensure_socket_initialization(void)
19651965 initialized = 1 ;
19661966}
19671967
1968+ static int winsock_error_to_errno (DWORD err )
1969+ {
1970+ switch (err ) {
1971+ case WSAEINTR : return EINTR ;
1972+ case WSAEBADF : return EBADF ;
1973+ case WSAEACCES : return EACCES ;
1974+ case WSAEFAULT : return EFAULT ;
1975+ case WSAEINVAL : return EINVAL ;
1976+ case WSAEMFILE : return EMFILE ;
1977+ case WSAEWOULDBLOCK : return EWOULDBLOCK ;
1978+ case WSAEINPROGRESS : return EINPROGRESS ;
1979+ case WSAEALREADY : return EALREADY ;
1980+ case WSAENOTSOCK : return ENOTSOCK ;
1981+ case WSAEDESTADDRREQ : return EDESTADDRREQ ;
1982+ case WSAEMSGSIZE : return EMSGSIZE ;
1983+ case WSAEPROTOTYPE : return EPROTOTYPE ;
1984+ case WSAENOPROTOOPT : return ENOPROTOOPT ;
1985+ case WSAEPROTONOSUPPORT : return EPROTONOSUPPORT ;
1986+ case WSAEOPNOTSUPP : return EOPNOTSUPP ;
1987+ case WSAEAFNOSUPPORT : return EAFNOSUPPORT ;
1988+ case WSAEADDRINUSE : return EADDRINUSE ;
1989+ case WSAEADDRNOTAVAIL : return EADDRNOTAVAIL ;
1990+ case WSAENETDOWN : return ENETDOWN ;
1991+ case WSAENETUNREACH : return ENETUNREACH ;
1992+ case WSAENETRESET : return ENETRESET ;
1993+ case WSAECONNABORTED : return ECONNABORTED ;
1994+ case WSAECONNRESET : return ECONNRESET ;
1995+ case WSAENOBUFS : return ENOBUFS ;
1996+ case WSAEISCONN : return EISCONN ;
1997+ case WSAENOTCONN : return ENOTCONN ;
1998+ case WSAETIMEDOUT : return ETIMEDOUT ;
1999+ case WSAECONNREFUSED : return ECONNREFUSED ;
2000+ case WSAELOOP : return ELOOP ;
2001+ case WSAENAMETOOLONG : return ENAMETOOLONG ;
2002+ case WSAEHOSTUNREACH : return EHOSTUNREACH ;
2003+ case WSAENOTEMPTY : return ENOTEMPTY ;
2004+ /* No errno equivalent; default to EIO */
2005+ case WSAESOCKTNOSUPPORT :
2006+ case WSAEPFNOSUPPORT :
2007+ case WSAESHUTDOWN :
2008+ case WSAETOOMANYREFS :
2009+ case WSAEHOSTDOWN :
2010+ case WSAEPROCLIM :
2011+ case WSAEUSERS :
2012+ case WSAEDQUOT :
2013+ case WSAESTALE :
2014+ case WSAEREMOTE :
2015+ case WSASYSNOTREADY :
2016+ case WSAVERNOTSUPPORTED :
2017+ case WSANOTINITIALISED :
2018+ case WSAEDISCON :
2019+ case WSAENOMORE :
2020+ case WSAECANCELLED :
2021+ case WSAEINVALIDPROCTABLE :
2022+ case WSAEINVALIDPROVIDER :
2023+ case WSAEPROVIDERFAILEDINIT :
2024+ case WSASYSCALLFAILURE :
2025+ case WSASERVICE_NOT_FOUND :
2026+ case WSATYPE_NOT_FOUND :
2027+ case WSA_E_NO_MORE :
2028+ case WSA_E_CANCELLED :
2029+ case WSAEREFUSED :
2030+ case WSAHOST_NOT_FOUND :
2031+ case WSATRY_AGAIN :
2032+ case WSANO_RECOVERY :
2033+ case WSANO_DATA :
2034+ case WSA_QOS_RECEIVERS :
2035+ case WSA_QOS_SENDERS :
2036+ case WSA_QOS_NO_SENDERS :
2037+ case WSA_QOS_NO_RECEIVERS :
2038+ case WSA_QOS_REQUEST_CONFIRMED :
2039+ case WSA_QOS_ADMISSION_FAILURE :
2040+ case WSA_QOS_POLICY_FAILURE :
2041+ case WSA_QOS_BAD_STYLE :
2042+ case WSA_QOS_BAD_OBJECT :
2043+ case WSA_QOS_TRAFFIC_CTRL_ERROR :
2044+ case WSA_QOS_GENERIC_ERROR :
2045+ case WSA_QOS_ESERVICETYPE :
2046+ case WSA_QOS_EFLOWSPEC :
2047+ case WSA_QOS_EPROVSPECBUF :
2048+ case WSA_QOS_EFILTERSTYLE :
2049+ case WSA_QOS_EFILTERTYPE :
2050+ case WSA_QOS_EFILTERCOUNT :
2051+ case WSA_QOS_EOBJLENGTH :
2052+ case WSA_QOS_EFLOWCOUNT :
2053+ #ifndef _MSC_VER
2054+ case WSA_QOS_EUNKNOWNPSOBJ :
2055+ #endif
2056+ case WSA_QOS_EPOLICYOBJ :
2057+ case WSA_QOS_EFLOWDESC :
2058+ case WSA_QOS_EPSFLOWSPEC :
2059+ case WSA_QOS_EPSFILTERSPEC :
2060+ case WSA_QOS_ESDMODEOBJ :
2061+ case WSA_QOS_ESHAPERATEOBJ :
2062+ case WSA_QOS_RESERVED_PETYPE :
2063+ default : return EIO ;
2064+ }
2065+ }
2066+
2067+ /*
2068+ * On Windows, `errno` is a global macro to a function call.
2069+ * This makes it difficult to debug and single-step our mappings.
2070+ */
2071+ static inline void set_wsa_errno (void )
2072+ {
2073+ DWORD wsa = WSAGetLastError ();
2074+ int e = winsock_error_to_errno (wsa );
2075+ errno = e ;
2076+
2077+ #ifdef DEBUG_WSA_ERRNO
2078+ fprintf (stderr , "winsock error: %d -> %d\n" , wsa , e );
2079+ fflush (stderr );
2080+ #endif
2081+ }
2082+
2083+ static inline int winsock_return (int ret )
2084+ {
2085+ if (ret < 0 )
2086+ set_wsa_errno ();
2087+
2088+ return ret ;
2089+ }
2090+
2091+ #define WINSOCK_RETURN (x ) do { return winsock_return(x); } while (0)
2092+
19682093#undef gethostname
19692094int mingw_gethostname (char * name , int namelen )
19702095{
1971- ensure_socket_initialization ();
1972- return gethostname (name , namelen );
2096+ ensure_socket_initialization ();
2097+ WINSOCK_RETURN ( gethostname (name , namelen ) );
19732098}
19742099
19752100#undef gethostbyname
19762101struct hostent * mingw_gethostbyname (const char * host )
19772102{
2103+ struct hostent * ret ;
2104+
19782105 ensure_socket_initialization ();
1979- return gethostbyname (host );
2106+
2107+ ret = gethostbyname (host );
2108+ if (!ret )
2109+ set_wsa_errno ();
2110+
2111+ return ret ;
19802112}
19812113
19822114#undef getaddrinfo
19832115int mingw_getaddrinfo (const char * node , const char * service ,
19842116 const struct addrinfo * hints , struct addrinfo * * res )
19852117{
19862118 ensure_socket_initialization ();
1987- return getaddrinfo (node , service , hints , res );
2119+ WINSOCK_RETURN ( getaddrinfo (node , service , hints , res ) );
19882120}
19892121
19902122int mingw_socket (int domain , int type , int protocol )
@@ -2004,7 +2136,7 @@ int mingw_socket(int domain, int type, int protocol)
20042136 * in errno so that _if_ someone looks up the code somewhere,
20052137 * then it is at least the number that are usually listed.
20062138 */
2007- errno = WSAGetLastError ();
2139+ set_wsa_errno ();
20082140 return -1 ;
20092141 }
20102142 /* convert into a file descriptor */
@@ -2020,35 +2152,35 @@ int mingw_socket(int domain, int type, int protocol)
20202152int mingw_connect (int sockfd , struct sockaddr * sa , size_t sz )
20212153{
20222154 SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2023- return connect (s , sa , sz );
2155+ WINSOCK_RETURN ( connect (s , sa , sz ) );
20242156}
20252157
20262158#undef bind
20272159int mingw_bind (int sockfd , struct sockaddr * sa , size_t sz )
20282160{
20292161 SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2030- return bind (s , sa , sz );
2162+ WINSOCK_RETURN ( bind (s , sa , sz ) );
20312163}
20322164
20332165#undef setsockopt
20342166int mingw_setsockopt (int sockfd , int lvl , int optname , void * optval , int optlen )
20352167{
20362168 SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2037- return setsockopt (s , lvl , optname , (const char * )optval , optlen );
2169+ WINSOCK_RETURN ( setsockopt (s , lvl , optname , (const char * )optval , optlen ) );
20382170}
20392171
20402172#undef shutdown
20412173int mingw_shutdown (int sockfd , int how )
20422174{
20432175 SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2044- return shutdown (s , how );
2176+ WINSOCK_RETURN ( shutdown (s , how ) );
20452177}
20462178
20472179#undef listen
20482180int mingw_listen (int sockfd , int backlog )
20492181{
20502182 SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2051- return listen (s , backlog );
2183+ WINSOCK_RETURN ( listen (s , backlog ) );
20522184}
20532185
20542186#undef accept
@@ -2059,6 +2191,11 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
20592191 SOCKET s1 = (SOCKET )_get_osfhandle (sockfd1 );
20602192 SOCKET s2 = accept (s1 , sa , sz );
20612193
2194+ if (s2 == INVALID_SOCKET ) {
2195+ set_wsa_errno ();
2196+ return -1 ;
2197+ }
2198+
20622199 /* convert into a file descriptor */
20632200 if ((sockfd2 = _open_osfhandle (s2 , O_RDWR |O_BINARY )) < 0 ) {
20642201 int err = errno ;
0 commit comments