From f418f5b26fc19650dc621a94578d9f0492ff138d Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Wed, 19 Feb 2014 15:12:31 +1100 Subject: [PATCH] save errno/$! across Win32.pm autoloads too --- ext/Win32CORE/Win32CORE.c | 5 +++++ ext/Win32CORE/t/win32core.t | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ext/Win32CORE/Win32CORE.c b/ext/Win32CORE/Win32CORE.c index bd9834e..91759e8 100644 --- a/ext/Win32CORE/Win32CORE.c +++ b/ext/Win32CORE/Win32CORE.c @@ -23,6 +23,10 @@ XS(w32_CORE_all){ + /* I'd use dSAVE_ERRNO() here, but it doesn't save the Win32 error code + * under cygwin, if that changes this code should change to use that. + */ + int saved_errno = errno; DWORD err = GetLastError(); /* capture the XSANY value before Perl_load_module, the CV's any member will * be overwritten by Perl_load_module and subsequent newXSes or pure perl @@ -31,6 +35,7 @@ XS(w32_CORE_all){ const char *function = (const char *) XSANY.any_ptr; Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, newSVpvn("Win32",5), newSVnv(0.27)); SetLastError(err); + errno = saved_errno; /* mark and SP from caller are passed through unchanged */ call_pv(function, GIMME_V); } diff --git a/ext/Win32CORE/t/win32core.t b/ext/Win32CORE/t/win32core.t index 64f2e95..8ef8cd0 100644 --- a/ext/Win32CORE/t/win32core.t +++ b/ext/Win32CORE/t/win32core.t @@ -10,7 +10,7 @@ BEGIN { } } - plan tests => 5; + plan tests => 6; }; use_ok( "Win32CORE" ); @@ -19,7 +19,9 @@ ok(!defined &Win32::ExpandEnvironmentStrings, "ensure other Win32::* functions aren't loaded yet"); $^E = 42; +$! = 4; ok(eval { Win32::GetLastError(); 1 }, 'GetLastError() works on the first call'); +my $errno = 0 + $!; my $sys_errno = 0 + $^E; SKIP: { $^O eq "cygwin" @@ -28,6 +30,7 @@ SKIP: { # should not affect the last error being retrieved is($sys_errno, 42, '$^E is preserved across Win32 autoload'); } +is($errno, 4, '$! is preserved across Win32 autoload'); # Now all Win32::* functions should be loaded ok(defined &Win32::ExpandEnvironmentStrings, -- 2.7.4