From: Eli Zaretskii Date: Sat, 16 Feb 2013 11:08:49 +0000 (+0200) Subject: Don't set h_errno on MS-Windows except in gethostbyname. X-Git-Tag: emacs-24.3.90~173^2~7^2~19 X-Git-Url: https://code.delx.au/gnu-emacs/commitdiff_plain/f277993be3a50b375c670351cb4051c806edd97f?hp=2b0afdd959577f6049dbcb64e17885fcf75a95b9 Don't set h_errno on MS-Windows except in gethostbyname. See http://lists.gnu.org/archive/html/emacs-devel/2013-02/msg00293.html and the following discussion for the details. src/w32.c (set_errno): Reset h_errno and don't set it to any other value. Set errno instead. (check_errno): Reset h_errno. (sys_socket, socket_to_fd, sys_bind, sys_connect) (sys_gethostname, sys_getservbyname, sys_getpeername) (sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname) (sys_accept, sys_recvfrom, sys_sendto, fcntl, sys_read): Don't set h_errno. (sys_gethostbyname): Set h_errno only errors detected. --- diff --git a/src/ChangeLog b/src/ChangeLog index 6ff25edac5..d326532ecb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2013-02-16 Eli Zaretskii + + * w32.c (set_errno): Reset h_errno and don't set it to any other + value. Set errno instead. + (check_errno): Reset h_errno. + (sys_socket, socket_to_fd, sys_bind, sys_connect) + (sys_gethostname, sys_getservbyname, sys_getpeername) + (sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname) + (sys_accept, sys_recvfrom, sys_sendto, fcntl, sys_read): Don't set + h_errno. + (sys_gethostbyname): Set h_errno only errors detected. + 2013-02-15 Paul Eggert * process.c (h_errno) [!HAVE_H_ERRNO]: Remove unused decl. diff --git a/src/w32.c b/src/w32.c index 25cc218579..12fb248b2d 100644 --- a/src/w32.c +++ b/src/w32.c @@ -6092,35 +6092,39 @@ init_winsock (int load_now) int h_errno = 0; -/* function to set h_errno for compatibility; map winsock error codes to - normal system codes where they overlap (non-overlapping definitions - are already in */ +/* Function to map winsock error codes to errno codes for those errno + code defined in errno.h (errno values not defined by errno.h are + already in nt/inc/sys/socket.h). */ static void set_errno (void) { + int wsa_err; + + h_errno = 0; if (winsock_lib == NULL) - h_errno = EINVAL; + wsa_err = EINVAL; else - h_errno = pfn_WSAGetLastError (); + wsa_err = pfn_WSAGetLastError (); - switch (h_errno) + switch (wsa_err) { - case WSAEACCES: h_errno = EACCES; break; - case WSAEBADF: h_errno = EBADF; break; - case WSAEFAULT: h_errno = EFAULT; break; - case WSAEINTR: h_errno = EINTR; break; - case WSAEINVAL: h_errno = EINVAL; break; - case WSAEMFILE: h_errno = EMFILE; break; - case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break; - case WSAENOTEMPTY: h_errno = ENOTEMPTY; break; + case WSAEACCES: errno = EACCES; break; + case WSAEBADF: errno = EBADF; break; + case WSAEFAULT: errno = EFAULT; break; + case WSAEINTR: errno = EINTR; break; + case WSAEINVAL: errno = EINVAL; break; + case WSAEMFILE: errno = EMFILE; break; + case WSAENAMETOOLONG: errno = ENAMETOOLONG; break; + case WSAENOTEMPTY: errno = ENOTEMPTY; break; + default: errno = wsa_err; break; } - errno = h_errno; } static void check_errno (void) { - if (h_errno == 0 && winsock_lib != NULL) + h_errno = 0; + if (winsock_lib != NULL) pfn_WSASetLastError (0); } @@ -6232,7 +6236,7 @@ sys_socket (int af, int type, int protocol) if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return INVALID_SOCKET; } @@ -6242,13 +6246,7 @@ sys_socket (int af, int type, int protocol) s = pfn_socket (af, type, protocol); if (s != INVALID_SOCKET) - { - int retval = socket_to_fd (s); - - if (retval == -1) - errno = h_errno; - return retval; - } + return socket_to_fd (s); set_errno (); return -1; @@ -6344,8 +6342,9 @@ socket_to_fd (SOCKET s) /* clean up */ _close (fd); } + else pfn_closesocket (s); - h_errno = EMFILE; + errno = EMFILE; return -1; } @@ -6354,7 +6353,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen) { if (winsock_lib == NULL) { - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6366,7 +6365,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen) set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6375,7 +6374,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen) { if (winsock_lib == NULL) { - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6387,7 +6386,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen) set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6416,12 +6415,20 @@ int sys_gethostname (char * name, int namelen) { if (winsock_lib != NULL) - return pfn_gethostname (name, namelen); + { + int retval; + + check_errno (); + retval = pfn_gethostname (name, namelen); + if (retval == SOCKET_ERROR) + set_errno (); + return retval; + } if (namelen > MAX_COMPUTERNAME_LENGTH) return !GetComputerName (name, (DWORD *)&namelen); - errno = h_errno = EFAULT; + errno = EFAULT; return SOCKET_ERROR; } @@ -6429,17 +6436,24 @@ struct hostent * sys_gethostbyname (const char * name) { struct hostent * host; + int h_err = h_errno; if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + h_errno = NO_RECOVERY; + errno = ENETDOWN; return NULL; } check_errno (); host = pfn_gethostbyname (name); if (!host) - set_errno (); + { + set_errno (); + h_errno = errno; + } + else + h_errno = h_err; return host; } @@ -6450,7 +6464,7 @@ sys_getservbyname (const char * name, const char * proto) if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return NULL; } @@ -6466,7 +6480,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen) { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return SOCKET_ERROR; } @@ -6478,7 +6492,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen) set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6487,7 +6501,7 @@ sys_shutdown (int s, int how) { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return SOCKET_ERROR; } @@ -6499,7 +6513,7 @@ sys_shutdown (int s, int how) set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6508,7 +6522,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen) { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return SOCKET_ERROR; } @@ -6521,7 +6535,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen) set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6530,7 +6544,7 @@ sys_listen (int s, int backlog) { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return SOCKET_ERROR; } @@ -6544,7 +6558,7 @@ sys_listen (int s, int backlog) fd_info[s].flags |= FILE_LISTEN; return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6553,7 +6567,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen) { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return SOCKET_ERROR; } @@ -6565,7 +6579,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen) set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6574,7 +6588,7 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen) { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return -1; } @@ -6586,11 +6600,7 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen) if (t == INVALID_SOCKET) set_errno (); else - { - fd = socket_to_fd (t); - if (fd < 0) - errno = h_errno; /* socket_to_fd sets h_errno */ - } + fd = socket_to_fd (t); if (fd >= 0) { @@ -6599,7 +6609,7 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen) } return fd; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return -1; } @@ -6609,7 +6619,7 @@ sys_recvfrom (int s, char * buf, int len, int flags, { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return SOCKET_ERROR; } @@ -6621,7 +6631,7 @@ sys_recvfrom (int s, char * buf, int len, int flags, set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6631,7 +6641,7 @@ sys_sendto (int s, const char * buf, int len, int flags, { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return SOCKET_ERROR; } @@ -6643,7 +6653,7 @@ sys_sendto (int s, const char * buf, int len, int flags, set_errno (); return rc; } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -6654,7 +6664,7 @@ fcntl (int s, int cmd, int options) { if (winsock_lib == NULL) { - errno = h_errno = ENETDOWN; + errno = ENETDOWN; return -1; } @@ -6673,11 +6683,11 @@ fcntl (int s, int cmd, int options) } else { - h_errno = EINVAL; + errno = EINVAL; return SOCKET_ERROR; } } - errno = h_errno = ENOTSOCK; + errno = ENOTSOCK; return SOCKET_ERROR; } @@ -7108,7 +7118,7 @@ sys_read (int fd, char * buffer, unsigned int count) pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting); if (waiting == 0 && nchars == 0) { - h_errno = errno = EWOULDBLOCK; + errno = EWOULDBLOCK; return -1; }