#endif
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
#define gv_init_sv S_gv_init_sv
+#define require_errno S_require_errno
#endif
#if defined(PERL_IN_HV_C) || defined(PERL_DECL_PROT)
#define hsplit S_hsplit
#endif
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
#define gv_init_sv(a,b) S_gv_init_sv(aTHX_ a,b)
+#define require_errno(a) S_require_errno(aTHX_ a)
#endif
#if defined(PERL_IN_HV_C) || defined(PERL_DECL_PROT)
#define hsplit(a) S_hsplit(aTHX_ a)
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
#define S_gv_init_sv CPerlObj::S_gv_init_sv
#define gv_init_sv S_gv_init_sv
+#define S_require_errno CPerlObj::S_require_errno
+#define require_errno S_require_errno
#endif
#if defined(PERL_IN_HV_C) || defined(PERL_DECL_PROT)
#define S_hsplit CPerlObj::S_hsplit
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
s |void |gv_init_sv |GV *gv|I32 sv_type
+s |void |require_errno |GV *gv
#endif
#if defined(PERL_IN_HV_C) || defined(PERL_DECL_PROT)
return gv;
}
+/* The "gv" parameter should be the glob known to Perl code as *!
+ * The scalar must already have been magicalized.
+ */
+STATIC void
+S_require_errno(pTHX_ GV *gv)
+{
+ HV* stash = gv_stashpvn("Errno",5,FALSE);
+
+ if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) {
+ dSP;
+ PUTBACK;
+ ENTER;
+ save_scalar(gv); /* keep the value of $! */
+ require_pv("Errno.pm");
+ LEAVE;
+ SPAGAIN;
+ stash = gv_stashpvn("Errno",5,FALSE);
+ if (!stash || !(gv_fetchmethod(stash, "TIEHASH")))
+ Perl_croak(aTHX_ "Can't use %%! because Errno.pm is not available");
+ }
+}
+
/*
=for apidoc gv_stashpv
if (add) {
GvMULTI_on(gv);
gv_init_sv(gv, sv_type);
+ if (*name=='!' && sv_type == SVt_PVHV && len==1)
+ require_errno(gv);
}
return gv;
} else if (add & GV_NOINIT) {
case '!':
if (len > 1)
break;
- if (sv_type > SVt_PV && PL_curcop != &PL_compiling) {
- HV* stash = gv_stashpvn("Errno",5,FALSE);
- if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) {
- dSP;
- PUTBACK;
- require_pv("Errno.pm");
- SPAGAIN;
- stash = gv_stashpvn("Errno",5,FALSE);
- if (!stash || !(gv_fetchmethod(stash, "TIEHASH")))
- Perl_croak(aTHX_ "Can't use %%! because Errno.pm is not available");
- }
- }
- goto magicalize;
+
+ /* If %! has been used, automatically load Errno.pm.
+ The require will itself set errno, so in order to
+ preserve its value we have to set up the magic
+ now (rather than going to magicalize)
+ */
+
+ sv_magic(GvSV(gv), (SV*)gv, 0, name, len);
+
+ if (sv_type == SVt_PVHV)
+ require_errno(gv);
+
+ break;
case '-':
if (len > 1)
break;
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
STATIC void S_gv_init_sv(pTHX_ GV *gv, I32 sv_type);
+STATIC void S_require_errno(pTHX_ GV *gv);
#endif
#if defined(PERL_IN_HV_C) || defined(PERL_DECL_PROT)
$Is_Cygwin = $^O eq 'cygwin';
$PERL = ($Is_MSWin32 ? '.\perl' : './perl');
-print "1..35\n";
+print "1..38\n";
eval '$ENV{"FOO"} = "hi there";'; # check that ENV is inited inside eval
if ($Is_MSWin32) { ok 1, `cmd /x /c set FOO` eq "FOO=hi there\n"; }
ok "34 # skipped: no caseless %ENV support",1;
ok "35 # skipped: no caseless %ENV support",1;
}
+
+# Make sure Errno hasn't been prematurely autoloaded
+
+ok 36, !defined %Errno::;
+
+# Test auto-loading of Errno when %! is used
+
+ok 37, scalar eval q{
+ my $errs = %!;
+ defined %Errno::;
+}, $@;
+
+
+# Make sure that Errno loading doesn't clobber $!
+
+undef %Errno::;
+delete $INC{"Errno.pm"};
+
+open(FOO, "nonesuch"); # Generate ENOENT
+my %errs = %{"!"}; # Cause Errno.pm to be loaded at run-time
+ok 38, ${"!"}{ENOENT};