This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make <~> work again under miniperl
authorFather Chrysostomos <sprout@cpan.org>
Mon, 24 Oct 2011 13:14:31 +0000 (06:14 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 24 Oct 2011 13:15:07 +0000 (06:15 -0700)
Commit a3342be368 localised %ENV before calling csh for glob.  But
that causes <~> to stop working.  So this commit clears out %ENV
*except* for $ENV{HOME}.

It relies on the way magic works:  Before localising the %ENV hash, it
retrieves its $ENV{HOME} element, which is a magical scalar.  It calls
get-magic to store the value in the scalar itself, localises %ENV, and
then calls set-magic on the element, to signal (deceitfully) that an assignment has just happened.  So the cached value in the magical sca-
lar is used and assigned to the env var.

doio.c
t/op/glob.t

diff --git a/doio.c b/doio.c
index 06d9bcd..47b60ce 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -2379,7 +2379,13 @@ Perl_vms_start_glob
 #endif
 #endif /* !CSH */
 #endif /* !DOSISH */
-    save_hash(gv_fetchpvs("ENV", 0, SVt_PVHV));
+    {
+       GV * const envgv = gv_fetchpvs("ENV", 0, SVt_PVHV);
+       SV ** const home = hv_fetchs(GvHV(envgv), "HOME", 0);
+       if (home && *home) SvGETMAGIC(*home);
+       save_hash(gv_fetchpvs("ENV", 0, SVt_PVHV));
+       if (home && *home) SvSETMAGIC(*home);
+    }
     (void)do_open(PL_last_in_gv, (char*)SvPVX_const(tmpcmd), SvCUR(tmpcmd),
                  FALSE, O_RDONLY, 0, NULL);
     fp = IoIFP(io);
index 6abcc75..d5ddd9f 100644 (file)
@@ -3,10 +3,10 @@
 BEGIN {
     chdir 't' if -d 't';
     @INC = qw(. ../lib);
+    require 'test.pl';
 }
 
-require 'test.pl';
-plan( tests => 13 );
+plan( tests => 14 );
 
 @oops = @ops = <op/*>;
 
@@ -81,3 +81,9 @@ SKIP: {
 }
 
 cmp_ok(scalar(@oops),'>',0,'glob globbed something');
+
+# This test exists mainly for miniperl, to test that external calls to
+# csh, which clear %ENV first, leave $ENV{HOME}.
+# On Windows, external glob uses File::DosGlob which returns "~", so this
+# should pass anyway.
+ok <~>, '~ works';