Skip to content

Commit 077656c

Browse files
committed
mingw: make sure errno is set when socket operations fail
Noticed by Jeff Hostetler. This closes #2404 Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 02af2cc commit 077656c

File tree

1 file changed

+119
-6
lines changed

1 file changed

+119
-6
lines changed

compat/mingw.c

Lines changed: 119 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,26 +2186,139 @@ static void ensure_socket_initialization(void)
21862186
initialized = 1;
21872187
}
21882188

2189+
static int winsock_error_to_errno(DWORD err)
2190+
{
2191+
switch (err) {
2192+
case WSAEINTR: return EINTR;
2193+
case WSAEBADF: return EBADF;
2194+
case WSAEACCES: return EACCES;
2195+
case WSAEFAULT: return EFAULT;
2196+
case WSAEINVAL: return EINVAL;
2197+
case WSAEMFILE: return EMFILE;
2198+
case WSAEWOULDBLOCK: return EWOULDBLOCK;
2199+
case WSAEINPROGRESS: return EINPROGRESS;
2200+
case WSAEALREADY: return EALREADY;
2201+
case WSAENOTSOCK: return ENOTSOCK;
2202+
case WSAEDESTADDRREQ: return EDESTADDRREQ;
2203+
case WSAEMSGSIZE: return EMSGSIZE;
2204+
case WSAEPROTOTYPE: return EPROTOTYPE;
2205+
case WSAENOPROTOOPT: return ENOPROTOOPT;
2206+
case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT;
2207+
case WSAEOPNOTSUPP: return EOPNOTSUPP;
2208+
case WSAEAFNOSUPPORT: return EAFNOSUPPORT;
2209+
case WSAEADDRINUSE: return EADDRINUSE;
2210+
case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL;
2211+
case WSAENETDOWN: return ENETDOWN;
2212+
case WSAENETUNREACH: return ENETUNREACH;
2213+
case WSAENETRESET: return ENETRESET;
2214+
case WSAECONNABORTED: return ECONNABORTED;
2215+
case WSAECONNRESET: return ECONNRESET;
2216+
case WSAENOBUFS: return ENOBUFS;
2217+
case WSAEISCONN: return EISCONN;
2218+
case WSAENOTCONN: return ENOTCONN;
2219+
case WSAETIMEDOUT: return ETIMEDOUT;
2220+
case WSAECONNREFUSED: return ECONNREFUSED;
2221+
case WSAELOOP: return ELOOP;
2222+
case WSAENAMETOOLONG: return ENAMETOOLONG;
2223+
case WSAEHOSTUNREACH: return EHOSTUNREACH;
2224+
case WSAENOTEMPTY: return ENOTEMPTY;
2225+
/* No errno equivalent; default to EIO */
2226+
case WSAESOCKTNOSUPPORT:
2227+
case WSAEPFNOSUPPORT:
2228+
case WSAESHUTDOWN:
2229+
case WSAETOOMANYREFS:
2230+
case WSAEHOSTDOWN:
2231+
case WSAEPROCLIM:
2232+
case WSAEUSERS:
2233+
case WSAEDQUOT:
2234+
case WSAESTALE:
2235+
case WSAEREMOTE:
2236+
case WSASYSNOTREADY:
2237+
case WSAVERNOTSUPPORTED:
2238+
case WSANOTINITIALISED:
2239+
case WSAEDISCON:
2240+
case WSAENOMORE:
2241+
case WSAECANCELLED:
2242+
case WSAEINVALIDPROCTABLE:
2243+
case WSAEINVALIDPROVIDER:
2244+
case WSAEPROVIDERFAILEDINIT:
2245+
case WSASYSCALLFAILURE:
2246+
case WSASERVICE_NOT_FOUND:
2247+
case WSATYPE_NOT_FOUND:
2248+
case WSA_E_NO_MORE:
2249+
case WSA_E_CANCELLED:
2250+
case WSAEREFUSED:
2251+
case WSAHOST_NOT_FOUND:
2252+
case WSATRY_AGAIN:
2253+
case WSANO_RECOVERY:
2254+
case WSANO_DATA:
2255+
case WSA_QOS_RECEIVERS:
2256+
case WSA_QOS_SENDERS:
2257+
case WSA_QOS_NO_SENDERS:
2258+
case WSA_QOS_NO_RECEIVERS:
2259+
case WSA_QOS_REQUEST_CONFIRMED:
2260+
case WSA_QOS_ADMISSION_FAILURE:
2261+
case WSA_QOS_POLICY_FAILURE:
2262+
case WSA_QOS_BAD_STYLE:
2263+
case WSA_QOS_BAD_OBJECT:
2264+
case WSA_QOS_TRAFFIC_CTRL_ERROR:
2265+
case WSA_QOS_GENERIC_ERROR:
2266+
case WSA_QOS_ESERVICETYPE:
2267+
case WSA_QOS_EFLOWSPEC:
2268+
case WSA_QOS_EPROVSPECBUF:
2269+
case WSA_QOS_EFILTERSTYLE:
2270+
case WSA_QOS_EFILTERTYPE:
2271+
case WSA_QOS_EFILTERCOUNT:
2272+
case WSA_QOS_EOBJLENGTH:
2273+
case WSA_QOS_EFLOWCOUNT:
2274+
#ifndef _MSC_VER
2275+
case WSA_QOS_EUNKNOWNPSOBJ:
2276+
#endif
2277+
case WSA_QOS_EPOLICYOBJ:
2278+
case WSA_QOS_EFLOWDESC:
2279+
case WSA_QOS_EPSFLOWSPEC:
2280+
case WSA_QOS_EPSFILTERSPEC:
2281+
case WSA_QOS_ESDMODEOBJ:
2282+
case WSA_QOS_ESHAPERATEOBJ:
2283+
case WSA_QOS_RESERVED_PETYPE:
2284+
default: return EIO;
2285+
}
2286+
}
2287+
2288+
#define WINSOCK_RETURN(x) { \
2289+
int ret = (x); \
2290+
if (ret < 0) \
2291+
errno = winsock_error_to_errno(WSAGetLastError()); \
2292+
return ret; \
2293+
}
2294+
21892295
#undef gethostname
21902296
int mingw_gethostname(char *name, int namelen)
21912297
{
2192-
ensure_socket_initialization();
2193-
return gethostname(name, namelen);
2298+
ensure_socket_initialization();
2299+
WINSOCK_RETURN(gethostname(name, namelen));
21942300
}
21952301

21962302
#undef gethostbyname
21972303
struct hostent *mingw_gethostbyname(const char *host)
21982304
{
2305+
struct hostent *ret;
2306+
21992307
ensure_socket_initialization();
2200-
return gethostbyname(host);
2308+
2309+
ret = gethostbyname(host);
2310+
if (!ret)
2311+
errno = winsock_error_to_errno(WSAGetLastError());
2312+
2313+
return ret;
22012314
}
22022315

22032316
#undef getaddrinfo
22042317
int mingw_getaddrinfo(const char *node, const char *service,
22052318
const struct addrinfo *hints, struct addrinfo **res)
22062319
{
22072320
ensure_socket_initialization();
2208-
return getaddrinfo(node, service, hints, res);
2321+
WINSOCK_RETURN(getaddrinfo(node, service, hints, res));
22092322
}
22102323

22112324
int mingw_socket(int domain, int type, int protocol)
@@ -2225,7 +2338,7 @@ int mingw_socket(int domain, int type, int protocol)
22252338
* in errno so that _if_ someone looks up the code somewhere,
22262339
* then it is at least the number that are usually listed.
22272340
*/
2228-
errno = WSAGetLastError();
2341+
errno = winsock_error_to_errno(WSAGetLastError());
22292342
return -1;
22302343
}
22312344
/* convert into a file descriptor */
@@ -2255,7 +2368,7 @@ int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz)
22552368
int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen)
22562369
{
22572370
SOCKET s = (SOCKET)_get_osfhandle(sockfd);
2258-
return setsockopt(s, lvl, optname, (const char*)optval, optlen);
2371+
WINSOCK_RETURN(setsockopt(s, lvl, optname, (const char*)optval, optlen));
22592372
}
22602373

22612374
#undef shutdown

0 commit comments

Comments
 (0)