@@ -1979,26 +1979,158 @@ static void ensure_socket_initialization(void)
1979
1979
initialized = 1 ;
1980
1980
}
1981
1981
1982
+ static int winsock_error_to_errno (DWORD err )
1983
+ {
1984
+ switch (err ) {
1985
+ case WSAEINTR : return EINTR ;
1986
+ case WSAEBADF : return EBADF ;
1987
+ case WSAEACCES : return EACCES ;
1988
+ case WSAEFAULT : return EFAULT ;
1989
+ case WSAEINVAL : return EINVAL ;
1990
+ case WSAEMFILE : return EMFILE ;
1991
+ case WSAEWOULDBLOCK : return EWOULDBLOCK ;
1992
+ case WSAEINPROGRESS : return EINPROGRESS ;
1993
+ case WSAEALREADY : return EALREADY ;
1994
+ case WSAENOTSOCK : return ENOTSOCK ;
1995
+ case WSAEDESTADDRREQ : return EDESTADDRREQ ;
1996
+ case WSAEMSGSIZE : return EMSGSIZE ;
1997
+ case WSAEPROTOTYPE : return EPROTOTYPE ;
1998
+ case WSAENOPROTOOPT : return ENOPROTOOPT ;
1999
+ case WSAEPROTONOSUPPORT : return EPROTONOSUPPORT ;
2000
+ case WSAEOPNOTSUPP : return EOPNOTSUPP ;
2001
+ case WSAEAFNOSUPPORT : return EAFNOSUPPORT ;
2002
+ case WSAEADDRINUSE : return EADDRINUSE ;
2003
+ case WSAEADDRNOTAVAIL : return EADDRNOTAVAIL ;
2004
+ case WSAENETDOWN : return ENETDOWN ;
2005
+ case WSAENETUNREACH : return ENETUNREACH ;
2006
+ case WSAENETRESET : return ENETRESET ;
2007
+ case WSAECONNABORTED : return ECONNABORTED ;
2008
+ case WSAECONNRESET : return ECONNRESET ;
2009
+ case WSAENOBUFS : return ENOBUFS ;
2010
+ case WSAEISCONN : return EISCONN ;
2011
+ case WSAENOTCONN : return ENOTCONN ;
2012
+ case WSAETIMEDOUT : return ETIMEDOUT ;
2013
+ case WSAECONNREFUSED : return ECONNREFUSED ;
2014
+ case WSAELOOP : return ELOOP ;
2015
+ case WSAENAMETOOLONG : return ENAMETOOLONG ;
2016
+ case WSAEHOSTUNREACH : return EHOSTUNREACH ;
2017
+ case WSAENOTEMPTY : return ENOTEMPTY ;
2018
+ /* No errno equivalent; default to EIO */
2019
+ case WSAESOCKTNOSUPPORT :
2020
+ case WSAEPFNOSUPPORT :
2021
+ case WSAESHUTDOWN :
2022
+ case WSAETOOMANYREFS :
2023
+ case WSAEHOSTDOWN :
2024
+ case WSAEPROCLIM :
2025
+ case WSAEUSERS :
2026
+ case WSAEDQUOT :
2027
+ case WSAESTALE :
2028
+ case WSAEREMOTE :
2029
+ case WSASYSNOTREADY :
2030
+ case WSAVERNOTSUPPORTED :
2031
+ case WSANOTINITIALISED :
2032
+ case WSAEDISCON :
2033
+ case WSAENOMORE :
2034
+ case WSAECANCELLED :
2035
+ case WSAEINVALIDPROCTABLE :
2036
+ case WSAEINVALIDPROVIDER :
2037
+ case WSAEPROVIDERFAILEDINIT :
2038
+ case WSASYSCALLFAILURE :
2039
+ case WSASERVICE_NOT_FOUND :
2040
+ case WSATYPE_NOT_FOUND :
2041
+ case WSA_E_NO_MORE :
2042
+ case WSA_E_CANCELLED :
2043
+ case WSAEREFUSED :
2044
+ case WSAHOST_NOT_FOUND :
2045
+ case WSATRY_AGAIN :
2046
+ case WSANO_RECOVERY :
2047
+ case WSANO_DATA :
2048
+ case WSA_QOS_RECEIVERS :
2049
+ case WSA_QOS_SENDERS :
2050
+ case WSA_QOS_NO_SENDERS :
2051
+ case WSA_QOS_NO_RECEIVERS :
2052
+ case WSA_QOS_REQUEST_CONFIRMED :
2053
+ case WSA_QOS_ADMISSION_FAILURE :
2054
+ case WSA_QOS_POLICY_FAILURE :
2055
+ case WSA_QOS_BAD_STYLE :
2056
+ case WSA_QOS_BAD_OBJECT :
2057
+ case WSA_QOS_TRAFFIC_CTRL_ERROR :
2058
+ case WSA_QOS_GENERIC_ERROR :
2059
+ case WSA_QOS_ESERVICETYPE :
2060
+ case WSA_QOS_EFLOWSPEC :
2061
+ case WSA_QOS_EPROVSPECBUF :
2062
+ case WSA_QOS_EFILTERSTYLE :
2063
+ case WSA_QOS_EFILTERTYPE :
2064
+ case WSA_QOS_EFILTERCOUNT :
2065
+ case WSA_QOS_EOBJLENGTH :
2066
+ case WSA_QOS_EFLOWCOUNT :
2067
+ #ifndef _MSC_VER
2068
+ case WSA_QOS_EUNKNOWNPSOBJ :
2069
+ #endif
2070
+ case WSA_QOS_EPOLICYOBJ :
2071
+ case WSA_QOS_EFLOWDESC :
2072
+ case WSA_QOS_EPSFLOWSPEC :
2073
+ case WSA_QOS_EPSFILTERSPEC :
2074
+ case WSA_QOS_ESDMODEOBJ :
2075
+ case WSA_QOS_ESHAPERATEOBJ :
2076
+ case WSA_QOS_RESERVED_PETYPE :
2077
+ default : return EIO ;
2078
+ }
2079
+ }
2080
+
2081
+ /*
2082
+ * On Windows, `errno` is a global macro to a function call.
2083
+ * This makes it difficult to debug and single-step our mappings.
2084
+ */
2085
+ static inline void set_wsa_errno (void )
2086
+ {
2087
+ DWORD wsa = WSAGetLastError ();
2088
+ int e = winsock_error_to_errno (wsa );
2089
+ errno = e ;
2090
+
2091
+ #ifdef DEBUG_WSA_ERRNO
2092
+ fprintf (stderr , "winsock error: %d -> %d\n" , wsa , e );
2093
+ fflush (stderr );
2094
+ #endif
2095
+ }
2096
+
2097
+ static inline int winsock_return (int ret )
2098
+ {
2099
+ if (ret < 0 )
2100
+ set_wsa_errno ();
2101
+
2102
+ return ret ;
2103
+ }
2104
+
2105
+ #define WINSOCK_RETURN (x ) do { return winsock_return(x); } while (0)
2106
+
1982
2107
#undef gethostname
1983
2108
int mingw_gethostname (char * name , int namelen )
1984
2109
{
1985
- ensure_socket_initialization ();
1986
- return gethostname (name , namelen );
2110
+ ensure_socket_initialization ();
2111
+ WINSOCK_RETURN ( gethostname (name , namelen ) );
1987
2112
}
1988
2113
1989
2114
#undef gethostbyname
1990
2115
struct hostent * mingw_gethostbyname (const char * host )
1991
2116
{
2117
+ struct hostent * ret ;
2118
+
1992
2119
ensure_socket_initialization ();
1993
- return gethostbyname (host );
2120
+
2121
+ ret = gethostbyname (host );
2122
+ if (!ret )
2123
+ set_wsa_errno ();
2124
+
2125
+ return ret ;
1994
2126
}
1995
2127
1996
2128
#undef getaddrinfo
1997
2129
int mingw_getaddrinfo (const char * node , const char * service ,
1998
2130
const struct addrinfo * hints , struct addrinfo * * res )
1999
2131
{
2000
2132
ensure_socket_initialization ();
2001
- return getaddrinfo (node , service , hints , res );
2133
+ WINSOCK_RETURN ( getaddrinfo (node , service , hints , res ) );
2002
2134
}
2003
2135
2004
2136
int mingw_socket (int domain , int type , int protocol )
@@ -2018,7 +2150,7 @@ int mingw_socket(int domain, int type, int protocol)
2018
2150
* in errno so that _if_ someone looks up the code somewhere,
2019
2151
* then it is at least the number that are usually listed.
2020
2152
*/
2021
- errno = WSAGetLastError ();
2153
+ set_wsa_errno ();
2022
2154
return -1 ;
2023
2155
}
2024
2156
/* convert into a file descriptor */
@@ -2034,35 +2166,35 @@ int mingw_socket(int domain, int type, int protocol)
2034
2166
int mingw_connect (int sockfd , struct sockaddr * sa , size_t sz )
2035
2167
{
2036
2168
SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2037
- return connect (s , sa , sz );
2169
+ WINSOCK_RETURN ( connect (s , sa , sz ) );
2038
2170
}
2039
2171
2040
2172
#undef bind
2041
2173
int mingw_bind (int sockfd , struct sockaddr * sa , size_t sz )
2042
2174
{
2043
2175
SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2044
- return bind (s , sa , sz );
2176
+ WINSOCK_RETURN ( bind (s , sa , sz ) );
2045
2177
}
2046
2178
2047
2179
#undef setsockopt
2048
2180
int mingw_setsockopt (int sockfd , int lvl , int optname , void * optval , int optlen )
2049
2181
{
2050
2182
SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2051
- return setsockopt (s , lvl , optname , (const char * )optval , optlen );
2183
+ WINSOCK_RETURN ( setsockopt (s , lvl , optname , (const char * )optval , optlen ) );
2052
2184
}
2053
2185
2054
2186
#undef shutdown
2055
2187
int mingw_shutdown (int sockfd , int how )
2056
2188
{
2057
2189
SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2058
- return shutdown (s , how );
2190
+ WINSOCK_RETURN ( shutdown (s , how ) );
2059
2191
}
2060
2192
2061
2193
#undef listen
2062
2194
int mingw_listen (int sockfd , int backlog )
2063
2195
{
2064
2196
SOCKET s = (SOCKET )_get_osfhandle (sockfd );
2065
- return listen (s , backlog );
2197
+ WINSOCK_RETURN ( listen (s , backlog ) );
2066
2198
}
2067
2199
2068
2200
#undef accept
@@ -2073,6 +2205,11 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
2073
2205
SOCKET s1 = (SOCKET )_get_osfhandle (sockfd1 );
2074
2206
SOCKET s2 = accept (s1 , sa , sz );
2075
2207
2208
+ if (s2 == INVALID_SOCKET ) {
2209
+ set_wsa_errno ();
2210
+ return -1 ;
2211
+ }
2212
+
2076
2213
/* convert into a file descriptor */
2077
2214
if ((sockfd2 = _open_osfhandle (s2 , O_RDWR |O_BINARY )) < 0 ) {
2078
2215
int err = errno ;
0 commit comments