summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorSteve Hay <steve.m.hay@googlemail.com>2013-09-04 18:20:03 +0100
committerSteve Hay <steve.m.hay@googlemail.com>2013-09-16 15:37:31 +0100
commitc9beaf974d06db3d9c7faecba5bb3e9e2a91767d (patch)
tree5f2b0168225ee392642f4996e97e679ac1ad1c61 /mg.c
parent80d2c56d79ef25871e30e4edd302eefe95af4b7f (diff)
downloadperl-c9beaf974d06db3d9c7faecba5bb3e9e2a91767d.tar.gz
Intercept assignment to $! to translate WSAExxx values to Exxx values on Windows
Since perl previously assigned WSAExxx values to $! on Windows it is quite possible that (Perl-level) user code may also manually make similar assignments, which will now cause breakage if the value put in $! is subsequently compared to Errno/POSIX constants because the latter are now the corresponding Exxx values where possible. An example of this is in Net::Ping::tcp_connect(), which does the following to fetch a socket-level error code: unpack("i", getsockopt($self->{"fh"}, SOL_SOCKET, SO_ERROR)) and assigns the result (a WSAExxx value such as 10061) to $! and then goes wrong in the subsequent test (in ping_tcp()) for $! == ECONNREFUSED (which is now 107 rather than 10061 if perl is built with VC10 or higher). To avoid this we now intercept assignment to $! and convert any WSAExxx values to Exxx values first. This causes a minor oddity in that this: perl -le "$! = 10061; print 0+$!" will now output 107 (for VC10+ perls) but this is surely preferable to the alternative breakage described above.
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/mg.c b/mg.c
index d0fbd47438..93048ecfda 100644
--- a/mg.c
+++ b/mg.c
@@ -2755,8 +2755,13 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
#else
# define PERL_VMS_BANG 0
#endif
+#ifdef WIN32
+ SETERRNO(win32_get_errno(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0),
+ (SvIV(sv) == EVMSERR) ? 4 : PERL_VMS_BANG);
+#else
SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
(SvIV(sv) == EVMSERR) ? 4 : PERL_VMS_BANG);
+#endif
}
break;
case '<':