summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Hay <steve.m.hay@googlemail.com>2013-09-03 22:57:29 +0100
committerSteve Hay <steve.m.hay@googlemail.com>2013-09-16 15:37:30 +0100
commitb0ba21900202318f75a549d9ac72765fc83945c6 (patch)
treee97bb686f7b6855400e2a91b75471c2755be7c1c
parenta05353bfa2b031e0c0283559432496d3915c83b2 (diff)
downloadperl-b0ba21900202318f75a549d9ac72765fc83945c6.tar.gz
Fix a problem with mod_perl on Windows using VS2010+.
The problem is caused by the following two commits, which sought to deal with new Exxx values (with values >= 100) in errno.h which Microsoft added in VS2010: http://perl5.git.perl.org/perl.git/commit/b59e75b34cef3fedd214c9b6ee744146cf8b3308 http://perl5.git.perl.org/perl.git/commit/912c63ed00375338703043928cac3c740d00cc9d The former commit was mostly a patch to Errno and POSIX, together with some other cleaning up in win32/win32.h and win32/include/sys/socket.h; the latter commit was a fixup to win32/include/sys/socket.h which restored (more aggressively) the ENOTSOCK->WSAENOTSOCK redefinition and added similar redefinitions for ECONNABORTED, ECONNRESET and EAFNOSUPPORT. It is the latter commit which causes this little program to output ECONNABORTED=10053 rather than ECONNABORTED=106 as it ought to do in VC10 (and higher) builds of perl: #include <windows.h> #include "EXTERN.h" #include "perl.h" #include "XSUB.h" void main(void) { printf("ECONNABORTED=%d\n", ECONNABORTED); } That change is now causing problems with mod_perl, in which the (Perl level) APR::Status::is_ECONNABORTED() and the (C level) APR_STATUS_IS_ECONNABORTED() which it calls are failing to recognize an aborted connection (indicated by error code ECONNABORTED set by Apache httpd.exe). The APR_STATUS_IS_ECONNABORTED() macro is picked up by mod_perl from APR's apr_errno.h: #define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ || (s) == APR_OS_START_SYSERR + WSAECONNABORTED) where #ifdef ECONNABORTED #define APR_ECONNABORTED ECONNABORTED #else #define APR_ECONNABORTED (APR_OS_START_CANONERR + 18) #endif When this is compiled into httpd.exe ECONNABORTED is 106 (from errno.h) and APR_STATUS_IS_ECONNABORTED(s) amounts to #define APR_STATUS_IS_ECONNABORTED(s) ((s) == 106 || (s) == 730053) but when compiled into APR/Status.dll ECONNABORTED is 10053 (redefined to WSAECONNABORTED as above) so APR_STATUS_IS_ECONNABORTED(s) then amounts to #define APR_STATUS_IS_ECONNABORTED(s) ((s) == 10053 || (s) == 730053) which doesn't pick up an error code of 106 coming from httpd.exe. This could be worked around in mod_perl by redefining ECONNABORTED and the other three back to their original errno.h values to match what httpd.exe is using, but that might just cause problems in the other direction, with those values no longer matching the values which perl.exe is using. Moreoever, this problem could affect other XS interfaces (not just mod_perl), so it really needs to be fixed in perl. This commit implements the alternative solution mentioned the commit message for the first commit cited above. (As noted in that previous commit message, this solution equally has potential problems, missing out on the advantages of the original solution implemented, namely, better backwards compatibility with other perl code having hard-coded numeric error codes, but this will be unavoidable if we want to get to a sane state.) Note that changing the $! values is an incompatible change, so should probably not be done for 5.18.x. That's unfortunate for mod_perl (and anything else similarly affected), but that will just have to either live with the breakage (which was introduced in 5.14.0) until 5.20.0 or else try the workaround mentioned above for 5.14.x, 5.16.x and 5.18.x. The main change is to use a new function throughout win32/win32sck.c to convert WSAGetLastError() values into errno.h constants before assigning to errno. Every possible WSAExxx value (as documented by MSDN) is mapped to an Exxx value, although it is still possible for other WSAxxx values to get assigned to errno unchanged (but that has always been the case, and any non-existent Exxx values get mapped back to WSAExxx values anyway...). We must then ensure that all of those Exxx values are defined, which is now done (in the new file, win32/include/sys/errno2.h) in a friendlier manner, being careful not to redefine any (specifically the new ones in VC++ 2010 and above) which already exist. The rest are defined as the WSAExxx values, as mentioned above. Finally, we need the Errno module to know about these values, which is done by having it include that same new header file to ensure that it gets the same definitions, rather than having to play its own games. The new header is also used in POSIX, which similarly wants definitions of as many as possible of its hard-coded list of Exxx values.
-rw-r--r--MANIFEST1
-rw-r--r--ext/Errno/Errno_pm.PL20
-rw-r--r--ext/POSIX/POSIX.xs157
-rw-r--r--ext/POSIX/lib/POSIX.pm2
-rw-r--r--win32/include/sys/errno2.h169
-rw-r--r--win32/include/sys/socket.h14
-rw-r--r--win32/win32.c2
-rw-r--r--win32/win32sck.c140
8 files changed, 311 insertions, 194 deletions
diff --git a/MANIFEST b/MANIFEST
index c83d0d05e2..81f21490a1 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -5608,6 +5608,7 @@ win32/FindExt.pm Scan for extensions
win32/include/arpa/inet.h Win32 port
win32/include/dirent.h Win32 port
win32/include/netdb.h Win32 port
+win32/include/sys/errno2.h Win32 port
win32/include/sys/socket.h Win32 port
win32/list_static_libs.pl prints libraries for static linking
win32/Makefile Win32 makefile for NMAKE (Visual C++ build)
diff --git a/ext/Errno/Errno_pm.PL b/ext/Errno/Errno_pm.PL
index b372875480..8267cbc153 100644
--- a/ext/Errno/Errno_pm.PL
+++ b/ext/Errno/Errno_pm.PL
@@ -2,10 +2,9 @@ use ExtUtils::MakeMaker;
use Config;
use strict;
-our $VERSION = "1.19";
+our $VERSION = "1.20";
my %err = ();
-my %wsa = ();
# Symbian cross-compiling environment.
my $IsSymbian = exists $ENV{SDK} && -d "$ENV{SDK}\\epoc32";
@@ -84,10 +83,6 @@ sub process_file {
while(<FH>) {
$err{$1} = 1
if /^\s*#\s*define\s+(E\w+)\s+/;
- if ($IsMSWin32) {
- $wsa{$1} = 1
- if /^\s*#\s*define\s+WSA(E\w+)\s+/;
- }
}
close(FH);
@@ -161,8 +156,7 @@ sub get_files {
} else {
print CPPI "#include <errno.h>\n";
if ($IsMSWin32) {
- print CPPI "#define _WINSOCKAPI_\n"; # don't drag in everything
- print CPPI "#include <winsock.h>\n";
+ print CPPI qq[#include "../../win32/include/sys/errno2.h"\n];
}
}
@@ -216,15 +210,7 @@ sub write_errno_pm {
}
if ($IsMSWin32) {
print CPPI "#include <winsock.h>\n";
- foreach $err (keys %wsa) {
- print CPPI "#if defined($err) && $err >= 100\n";
- print CPPI "#undef $err\n";
- print CPPI "#endif\n";
- print CPPI "#ifndef $err\n";
- print CPPI "#define $err WSA$err\n";
- print CPPI "#endif\n";
- $err{$err} = 1;
- }
+ print CPPI qq[#include "../../win32/include/sys/errno2.h"\n];
}
foreach $err (keys %err) {
diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs
index 655fda39e9..b3319fb901 100644
--- a/ext/POSIX/POSIX.xs
+++ b/ext/POSIX/POSIX.xs
@@ -28,6 +28,9 @@
#include <dirent.h>
#endif
#include <errno.h>
+#ifdef WIN32
+#include <sys/errno2.h>
+#endif
#ifdef I_FLOAT
#include <float.h>
#endif
@@ -193,160 +196,6 @@ char *tzname[] = { "" , "" };
#endif /* WIN32 || NETWARE */
#endif /* __VMS */
-#ifdef WIN32
- /* Perl on Windows assigns WSAGetLastError() return values to errno
- * (in win32/win32sck.c). Therefore we need to map these values
- * back to standard symbolic names, but only for those names having
- * no existing value or an existing value >= 100. (VC++ 2010 defines
- * a group of names with values >= 100 in its errno.h which we *do*
- * need to redefine.) The Errno.pm module does a similar mapping.
- */
-# ifdef EWOULDBLOCK
-# undef EWOULDBLOCK
-# endif
-# define EWOULDBLOCK WSAEWOULDBLOCK
-# ifdef EINPROGRESS
-# undef EINPROGRESS
-# endif
-# define EINPROGRESS WSAEINPROGRESS
-# ifdef EALREADY
-# undef EALREADY
-# endif
-# define EALREADY WSAEALREADY
-# ifdef ENOTSOCK
-# undef ENOTSOCK
-# endif
-# define ENOTSOCK WSAENOTSOCK
-# ifdef EDESTADDRREQ
-# undef EDESTADDRREQ
-# endif
-# define EDESTADDRREQ WSAEDESTADDRREQ
-# ifdef EMSGSIZE
-# undef EMSGSIZE
-# endif
-# define EMSGSIZE WSAEMSGSIZE
-# ifdef EPROTOTYPE
-# undef EPROTOTYPE
-# endif
-# define EPROTOTYPE WSAEPROTOTYPE
-# ifdef ENOPROTOOPT
-# undef ENOPROTOOPT
-# endif
-# define ENOPROTOOPT WSAENOPROTOOPT
-# ifdef EPROTONOSUPPORT
-# undef EPROTONOSUPPORT
-# endif
-# define EPROTONOSUPPORT WSAEPROTONOSUPPORT
-# ifdef ESOCKTNOSUPPORT
-# undef ESOCKTNOSUPPORT
-# endif
-# define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
-# ifdef EOPNOTSUPP
-# undef EOPNOTSUPP
-# endif
-# define EOPNOTSUPP WSAEOPNOTSUPP
-# ifdef EPFNOSUPPORT
-# undef EPFNOSUPPORT
-# endif
-# define EPFNOSUPPORT WSAEPFNOSUPPORT
-# ifdef EAFNOSUPPORT
-# undef EAFNOSUPPORT
-# endif
-# define EAFNOSUPPORT WSAEAFNOSUPPORT
-# ifdef EADDRINUSE
-# undef EADDRINUSE
-# endif
-# define EADDRINUSE WSAEADDRINUSE
-# ifdef EADDRNOTAVAIL
-# undef EADDRNOTAVAIL
-# endif
-# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
-# ifdef ENETDOWN
-# undef ENETDOWN
-# endif
-# define ENETDOWN WSAENETDOWN
-# ifdef ENETUNREACH
-# undef ENETUNREACH
-# endif
-# define ENETUNREACH WSAENETUNREACH
-# ifdef ENETRESET
-# undef ENETRESET
-# endif
-# define ENETRESET WSAENETRESET
-# ifdef ECONNABORTED
-# undef ECONNABORTED
-# endif
-# define ECONNABORTED WSAECONNABORTED
-# ifdef ECONNRESET
-# undef ECONNRESET
-# endif
-# define ECONNRESET WSAECONNRESET
-# ifdef ENOBUFS
-# undef ENOBUFS
-# endif
-# define ENOBUFS WSAENOBUFS
-# ifdef EISCONN
-# undef EISCONN
-# endif
-# define EISCONN WSAEISCONN
-# ifdef ENOTCONN
-# undef ENOTCONN
-# endif
-# define ENOTCONN WSAENOTCONN
-# ifdef ESHUTDOWN
-# undef ESHUTDOWN
-# endif
-# define ESHUTDOWN WSAESHUTDOWN
-# ifdef ETOOMANYREFS
-# undef ETOOMANYREFS
-# endif
-# define ETOOMANYREFS WSAETOOMANYREFS
-# ifdef ETIMEDOUT
-# undef ETIMEDOUT
-# endif
-# define ETIMEDOUT WSAETIMEDOUT
-# ifdef ECONNREFUSED
-# undef ECONNREFUSED
-# endif
-# define ECONNREFUSED WSAECONNREFUSED
-# ifdef ELOOP
-# undef ELOOP
-# endif
-# define ELOOP WSAELOOP
-# ifdef EHOSTDOWN
-# undef EHOSTDOWN
-# endif
-# define EHOSTDOWN WSAEHOSTDOWN
-# ifdef EHOSTUNREACH
-# undef EHOSTUNREACH
-# endif
-# define EHOSTUNREACH WSAEHOSTUNREACH
-# ifdef EPROCLIM
-# undef EPROCLIM
-# endif
-# define EPROCLIM WSAEPROCLIM
-# ifdef EUSERS
-# undef EUSERS
-# endif
-# define EUSERS WSAEUSERS
-# ifdef EDQUOT
-# undef EDQUOT
-# endif
-# define EDQUOT WSAEDQUOT
-# ifdef ESTALE
-# undef ESTALE
-# endif
-# define ESTALE WSAESTALE
-# ifdef EREMOTE
-# undef EREMOTE
-# endif
-# define EREMOTE WSAEREMOTE
-# ifdef EDISCON
-# undef EDISCON
-# endif
-# define EDISCON WSAEDISCON
-#endif
-
typedef int SysRet;
typedef long SysRetLong;
typedef sigset_t* POSIX__SigSet;
diff --git a/ext/POSIX/lib/POSIX.pm b/ext/POSIX/lib/POSIX.pm
index 40b02aca95..b3e12726eb 100644
--- a/ext/POSIX/lib/POSIX.pm
+++ b/ext/POSIX/lib/POSIX.pm
@@ -4,7 +4,7 @@ use warnings;
our ($AUTOLOAD, %SIGRT);
-our $VERSION = '1.34';
+our $VERSION = '1.35';
require XSLoader;
diff --git a/win32/include/sys/errno2.h b/win32/include/sys/errno2.h
new file mode 100644
index 0000000000..076ed01b30
--- /dev/null
+++ b/win32/include/sys/errno2.h
@@ -0,0 +1,169 @@
+#ifndef _INC_SYS_ERRNO2
+#define _INC_SYS_ERRNO2
+
+#define _WINSOCKAPI_ /* Don't drag in everything */
+#include <winsock.h>
+
+/* Ensure all the Exxx constants required by get_last_socket_error() in
+ * win32/win32sck.c are defined. Many are defined in <errno.h> already (more in
+ * VC++ 2010 and above) so, for the sake of compatibility with third-party code
+ * linked into XS modules, we must be careful not to redefine them; for the
+ * remainder we define our own values, namely the corresponding WSAExxx values.
+ * These definitions are also used as a supplement to the use of <errno.h> in
+ * the Errno and POSIX modules, both of which may be used to test the value of
+ * $!, which may have these values assigned to it (via win32/win32sck.c). It
+ * also provides numerous otherwise missing values in the (hard-coded) list of
+ * Exxx constants exported by POSIX.
+ */
+#ifndef EINTR
+# define EINTR WSAEINTR
+#endif
+#ifndef EBADF
+# define EBADF WSAEBADF
+#endif
+#ifndef EACCES
+# define EACCES WSAEACCES
+#endif
+#ifndef EFAULT
+# define EFAULT WSAEFAULT
+#endif
+#ifndef EINVAL
+# define EINVAL WSAEINVAL
+#endif
+#ifndef EMFILE
+# define EMFILE WSAEMFILE
+#endif
+#ifndef EWOULDBLOCK
+# define EWOULDBLOCK WSAEWOULDBLOCK
+#endif
+#ifndef EINPROGRESS
+# define EINPROGRESS WSAEINPROGRESS
+#endif
+#ifndef EALREADY
+# define EALREADY WSAEALREADY
+#endif
+#ifndef ENOTSOCK
+# define ENOTSOCK WSAENOTSOCK
+#endif
+#ifndef EDESTADDRREQ
+# define EDESTADDRREQ WSAEDESTADDRREQ
+#endif
+#ifndef EMSGSIZE
+# define EMSGSIZE WSAEMSGSIZE
+#endif
+#ifndef EPROTOTYPE
+# define EPROTOTYPE WSAEPROTOTYPE
+#endif
+#ifndef ENOPROTOOPT
+# define ENOPROTOOPT WSAENOPROTOOPT
+#endif
+#ifndef EPROTONOSUPPORT
+# define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#endif
+#ifndef ESOCKTNOSUPPORT
+# define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#endif
+#ifndef EOPNOTSUPP
+# define EOPNOTSUPP WSAEOPNOTSUPP
+#endif
+#ifndef EPFNOSUPPORT
+# define EPFNOSUPPORT WSAEPFNOSUPPORT
+#endif
+#ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT WSAEAFNOSUPPORT
+#endif
+#ifndef EADDRINUSE
+# define EADDRINUSE WSAEADDRINUSE
+#endif
+#ifndef EADDRNOTAVAIL
+# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#endif
+#ifndef ENETDOWN
+# define ENETDOWN WSAENETDOWN
+#endif
+#ifndef ENETUNREACH
+# define ENETUNREACH WSAENETUNREACH
+#endif
+#ifndef ENETRESET
+# define ENETRESET WSAENETRESET
+#endif
+#ifndef ECONNABORTED
+# define ECONNABORTED WSAECONNABORTED
+#endif
+#ifndef ECONNRESET
+# define ECONNRESET WSAECONNRESET
+#endif
+#ifndef ENOBUFS
+# define ENOBUFS WSAENOBUFS
+#endif
+#ifndef EISCONN
+# define EISCONN WSAEISCONN
+#endif
+#ifndef ENOTCONN
+# define ENOTCONN WSAENOTCONN
+#endif
+#ifndef ESHUTDOWN
+# define ESHUTDOWN WSAESHUTDOWN
+#endif
+#ifndef ETOOMANYREFS
+# define ETOOMANYREFS WSAETOOMANYREFS
+#endif
+#ifndef ETIMEDOUT
+# define ETIMEDOUT WSAETIMEDOUT
+#endif
+#ifndef ECONNREFUSED
+# define ECONNREFUSED WSAECONNREFUSED
+#endif
+#ifndef ELOOP
+# define ELOOP WSAELOOP
+#endif
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG WSAENAMETOOLONG
+#endif
+#ifndef EHOSTDOWN
+# define EHOSTDOWN WSAEHOSTDOWN
+#endif
+#ifndef EHOSTUNREACH
+# define EHOSTUNREACH WSAEHOSTUNREACH
+#endif
+#ifndef ENOTEMPTY
+# define ENOTEMPTY WSAENOTEMPTY
+#endif
+#ifndef EPROCLIM
+# define EPROCLIM WSAEPROCLIM
+#endif
+#ifndef EUSERS
+# define EUSERS WSAEUSERS
+#endif
+#ifndef EDQUOT
+# define EDQUOT WSAEDQUOT
+#endif
+#ifndef ESTALE
+# define ESTALE WSAESTALE
+#endif
+#ifndef EREMOTE
+# define EREMOTE WSAEREMOTE
+#endif
+#ifndef EDISCON
+# define EDISCON WSAEDISCON
+#endif
+#ifndef ENOMORE
+# define ENOMORE WSAENOMORE
+#endif
+#ifndef ECANCELLED
+# define ECANCELLED WSAECANCELLED
+#endif
+#ifndef EINVALIDPROCTABLE
+# define EINVALIDPROCTABLE WSAEINVALIDPROCTABLE
+#endif
+#ifndef EINVALIDPROVIDER
+# define EINVALIDPROVIDER WSAEINVALIDPROVIDER
+#endif
+#ifndef EPROVIDERFAILEDINIT
+# define EPROVIDERFAILEDINIT WSAEPROVIDERFAILEDINIT
+#endif
+#ifndef EREFUSED
+# define EREFUSED WSAEREFUSED
+#endif
+
+#endif /* _INC_SYS_ERRNO2 */
diff --git a/win32/include/sys/socket.h b/win32/include/sys/socket.h
index 6009572725..d658913f8b 100644
--- a/win32/include/sys/socket.h
+++ b/win32/include/sys/socket.h
@@ -177,23 +177,11 @@
# define EAI_NODATA WSANO_DATA
#endif
-#include "win32.h"
-
#ifdef __cplusplus
extern "C" {
#endif
-#undef ENOTSOCK
-#define ENOTSOCK WSAENOTSOCK
-
-#undef ECONNABORTED
-#define ECONNABORTED WSAECONNABORTED
-
-#undef ECONNRESET
-#define ECONNRESET WSAECONNRESET
-
-#undef EAFNOSUPPORT
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#include "errno2.h"
#ifndef PERL_FD_SETSIZE
#define PERL_FD_SETSIZE 64
diff --git a/win32/win32.c b/win32/win32.c
index c31e3a2287..1a64f9f2cb 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -2513,7 +2513,7 @@ win32_flock(int fd, int oper)
}
if (i == -1) {
if (GetLastError() == ERROR_LOCK_VIOLATION)
- errno = WSAEWOULDBLOCK;
+ errno = EWOULDBLOCK;
else
errno = EINVAL;
}
diff --git a/win32/win32sck.c b/win32/win32sck.c
index 3773f40189..0b425070a7 100644
--- a/win32/win32sck.c
+++ b/win32/win32sck.c
@@ -42,7 +42,7 @@
STMT_START { \
StartSockets(); \
if((x) == (y)) \
- errno = WSAGetLastError(); \
+ errno = get_last_socket_error(); \
} STMT_END
#define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
@@ -60,6 +60,129 @@ EndSockets(void)
WSACleanup();
}
+int
+get_last_socket_error(void)
+{
+ int err = WSAGetLastError();
+
+ /* Translate WSAExxx values to corresponding Exxx values. Not all WSAExxx
+ * constants have corresponding Exxx constants in <errno.h> (even in VC++
+ * 2010 and above, which have expanded <errno.h> with more values), but any
+ * missing constants are provided by win32/include/sys/errno2.h.
+ * The list of possible WSAExxx values used here comes from the MSDN page
+ * titled "Windows Sockets Error Codes".
+ * (Note: Only the WSAExxx values are handled here; other WSAxxx values are
+ * returned unchanged. The return value normally ends up in errno/$! and at
+ * the Perl code level may be tested against the Exxx constants exported by
+ * the Errno and POSIX modules, which have never handled the other WSAxxx
+ * values themselves, apparently without any ill effect so far.)
+ */
+ switch (err) {
+ case WSAEINTR:
+ return EINTR;
+ case WSAEBADF:
+ return EBADF;
+ case WSAEACCES:
+ return EACCES;
+ case WSAEFAULT:
+ return EFAULT;
+ case WSAEINVAL:
+ return EINVAL;
+ case WSAEMFILE:
+ return EMFILE;
+ case WSAEWOULDBLOCK:
+ return EWOULDBLOCK;
+ case WSAEINPROGRESS:
+ return EINPROGRESS;
+ case WSAEALREADY:
+ return EALREADY;
+ case WSAENOTSOCK:
+ return ENOTSOCK;
+ case WSAEDESTADDRREQ:
+ return EDESTADDRREQ;
+ case WSAEMSGSIZE:
+ return EMSGSIZE;
+ case WSAEPROTOTYPE:
+ return EPROTOTYPE;
+ case WSAENOPROTOOPT:
+ return ENOPROTOOPT;
+ case WSAEPROTONOSUPPORT:
+ return EPROTONOSUPPORT;
+ case WSAESOCKTNOSUPPORT:
+ return ESOCKTNOSUPPORT;
+ case WSAEOPNOTSUPP:
+ return EOPNOTSUPP;
+ case WSAEPFNOSUPPORT:
+ return EPFNOSUPPORT;
+ case WSAEAFNOSUPPORT:
+ return EAFNOSUPPORT;
+ case WSAEADDRINUSE:
+ return EADDRINUSE;
+ case WSAEADDRNOTAVAIL:
+ return EADDRNOTAVAIL;
+ case WSAENETDOWN:
+ return ENETDOWN;
+ case WSAENETUNREACH:
+ return ENETUNREACH;
+ case WSAENETRESET:
+ return ENETRESET;
+ case WSAECONNABORTED:
+ return ECONNABORTED;
+ case WSAECONNRESET:
+ return ECONNRESET;
+ case WSAENOBUFS:
+ return ENOBUFS;
+ case WSAEISCONN:
+ return EISCONN;
+ case WSAENOTCONN:
+ return ENOTCONN;
+ case WSAESHUTDOWN:
+ return ESHUTDOWN;
+ case WSAETOOMANYREFS:
+ return ETOOMANYREFS;
+ case WSAETIMEDOUT:
+ return ETIMEDOUT;
+ case WSAECONNREFUSED:
+ return ECONNREFUSED;
+ case WSAELOOP:
+ return ELOOP;
+ case WSAENAMETOOLONG:
+ return ENAMETOOLONG;
+ case WSAEHOSTDOWN:
+ return EHOSTDOWN;
+ case WSAEHOSTUNREACH:
+ return EHOSTUNREACH;
+ case WSAENOTEMPTY:
+ return ENOTEMPTY;
+ case WSAEPROCLIM:
+ return EPROCLIM;
+ case WSAEUSERS:
+ return EUSERS;
+ case WSAEDQUOT:
+ return EDQUOT;
+ case WSAESTALE:
+ return ESTALE;
+ case WSAEREMOTE:
+ return EREMOTE;
+ case WSAEDISCON:
+ return EDISCON;
+ case WSAENOMORE:
+ return ENOMORE;
+ case WSAECANCELLED:
+ return ECANCELLED;
+ case WSAEINVALIDPROCTABLE:
+ return EINVALIDPROCTABLE;
+ case WSAEINVALIDPROVIDER:
+ return EINVALIDPROVIDER;
+ case WSAEPROVIDERFAILEDINIT:
+ return EPROVIDERFAILEDINIT;
+ case WSAEREFUSED:
+ return EREFUSED;
+ }
+
+ return err;
+}
+
void
start_sockets(void)
{
@@ -401,7 +524,7 @@ win32_socket(int af, int type, int protocol)
StartSockets();
if((s = open_ifs_socket(af, type, protocol)) == INVALID_SOCKET)
- errno = WSAGetLastError();
+ errno = get_last_socket_error();
else
s = OPEN_SOCKET(s);
@@ -429,8 +552,8 @@ int my_close(int fd)
return 0;
}
else if (err == SOCKET_ERROR) {
- err = WSAGetLastError();
- if (err != WSAENOTSOCK) {
+ err = get_last_socket_error();
+ if (err != ENOTSOCK) {
(void)close(fd);
errno = err;
return EOF;
@@ -457,8 +580,8 @@ my_fclose (FILE *pf)
return 0;
}
else if (err == SOCKET_ERROR) {
- err = WSAGetLastError();
- if (err != WSAENOTSOCK) {
+ err = get_last_socket_error();
+ if (err != ENOTSOCK) {
(void)fclose(pf);
errno = err;
return EOF;
@@ -558,11 +681,12 @@ win32_ioctl(int i, unsigned int u, char *data)
memcpy(data, &u_long_arg, sizeof u_long_arg);
if (retval == SOCKET_ERROR) {
- if (WSAGetLastError() == WSAENOTSOCK) {
+ int err = get_last_socket_error();
+ if (err == ENOTSOCK) {
Perl_croak_nocontext("ioctl implemented only on sockets");
/* NOTREACHED */
}
- errno = WSAGetLastError();
+ errno = err;
}
return retval;
}