summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-06-08 23:01:07 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-06-08 23:25:13 -0700
commit82730d4c29900a581a5c4f6cd8c0cdef16c6e687 (patch)
tree99e30b878e7256fa5942d595f176d15b9665af38
parent483ad8291bb83bb55f59f0ff324af70346c4945a (diff)
downloadperl-82730d4c29900a581a5c4f6cd8c0cdef16c6e687.tar.gz
[perl #89940] File::Spec->tmpdir and env changes
If the environment changes, File::Spec->tmpdir should respect that and recalculate the temp directory. The only objection raised in the ticket was that File::Spec is already accused of being too slow, so removing the cache would not be a good idea. So I put in a check to see whether the relevant environment variables have changed since the last call to tmpdir.
-rw-r--r--dist/Cwd/lib/File/Spec/Cygwin.pm11
-rw-r--r--dist/Cwd/lib/File/Spec/Mac.pm6
-rw-r--r--dist/Cwd/lib/File/Spec/OS2.pm8
-rw-r--r--dist/Cwd/lib/File/Spec/Unix.pm22
-rw-r--r--dist/Cwd/lib/File/Spec/VMS.pm9
-rw-r--r--dist/Cwd/lib/File/Spec/Win32.pm3
-rw-r--r--dist/Cwd/t/tmpdir.t19
7 files changed, 59 insertions, 19 deletions
diff --git a/dist/Cwd/lib/File/Spec/Cygwin.pm b/dist/Cwd/lib/File/Spec/Cygwin.pm
index b27f7b15f1..4eb0347cc4 100644
--- a/dist/Cwd/lib/File/Spec/Cygwin.pm
+++ b/dist/Cwd/lib/File/Spec/Cygwin.pm
@@ -97,10 +97,15 @@ variables are tainted, they are not used.
=cut
-my $tmpdir;
sub tmpdir {
- return $tmpdir if defined $tmpdir;
- $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp", $ENV{'TMP'}, $ENV{'TEMP'}, 'C:/temp' );
+ my $cached = $_[0]->_cached_tmpdir(qw 'TMPDIR TMP TEMP');
+ return $cached if defined $cached;
+ $_[0]->_cache_tmpdir(
+ $_[0]->_tmpdir(
+ $ENV{TMPDIR}, "/tmp", $ENV{'TMP'}, $ENV{'TEMP'}, 'C:/temp'
+ ),
+ qw 'TMPDIR TMP TEMP'
+ );
}
=item case_tolerant
diff --git a/dist/Cwd/lib/File/Spec/Mac.pm b/dist/Cwd/lib/File/Spec/Mac.pm
index 7f42171bc9..aa6a7bf19c 100644
--- a/dist/Cwd/lib/File/Spec/Mac.pm
+++ b/dist/Cwd/lib/File/Spec/Mac.pm
@@ -374,10 +374,10 @@ directory on your startup volume.
=cut
-my $tmpdir;
sub tmpdir {
- return $tmpdir if defined $tmpdir;
- $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR} );
+ my $cached = $_[0]->_cached_tmpdir('TMPDIR');
+ return $cached if defined $cached;
+ $_[0]->_cache_tmpdir($_[0]->_tmpdir( $ENV{TMPDIR} ), 'TMPDIR');
}
=item updir
diff --git a/dist/Cwd/lib/File/Spec/OS2.pm b/dist/Cwd/lib/File/Spec/OS2.pm
index 7f60d68927..f9c6d44453 100644
--- a/dist/Cwd/lib/File/Spec/OS2.pm
+++ b/dist/Cwd/lib/File/Spec/OS2.pm
@@ -35,11 +35,13 @@ sub _cwd {
return Cwd::sys_cwd();
}
-my $tmpdir;
sub tmpdir {
- return $tmpdir if defined $tmpdir;
+ my $cached = $_[0]->_cached_tmpdir(qw 'TMPDIR TEMP TMP');
+ return $cached if defined $cached;
my @d = @ENV{qw(TMPDIR TEMP TMP)}; # function call could autovivivy
- $tmpdir = $_[0]->_tmpdir( @d, '/tmp', '/' );
+ $_[0]->_cache_tmpdir(
+ $_[0]->_tmpdir( @d, '/tmp', '/' ), qw 'TMPDIR TEMP TMP'
+ );
}
sub catdir {
diff --git a/dist/Cwd/lib/File/Spec/Unix.pm b/dist/Cwd/lib/File/Spec/Unix.pm
index a1a91b4260..0eb68b9444 100644
--- a/dist/Cwd/lib/File/Spec/Unix.pm
+++ b/dist/Cwd/lib/File/Spec/Unix.pm
@@ -140,9 +140,22 @@ is tainted, it is not used.
=cut
-my $tmpdir;
+my ($tmpdir, %tmpenv);
+# Cache and return the calculated tmpdir, recording which env vars
+# determined it.
+sub _cache_tmpdir {
+ @tmpenv{@_[2..$#_]} = @ENV{@_[2..$#_]};
+ return $tmpdir = $_[1];
+}
+# Retrieve the cached tmpdir, checking first whether relevant env vars have
+# changed and invalidated the cache.
+sub _cached_tmpdir {
+ shift;
+ local $^W;
+ return if grep $ENV{$_} ne $tmpenv{$_}, @_;
+ return $tmpdir;
+}
sub _tmpdir {
- return $tmpdir if defined $tmpdir;
my $self = shift;
my @dirlist = @_;
{
@@ -166,8 +179,9 @@ sub _tmpdir {
}
sub tmpdir {
- return $tmpdir if defined $tmpdir;
- $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" );
+ my $cached = $_[0]->_cached_tmpdir('TMPDIR');
+ return $cached if defined $cached;
+ $_[0]->_cache_tmpdir($_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" ), 'TMPDIR');
}
=item updir
diff --git a/dist/Cwd/lib/File/Spec/VMS.pm b/dist/Cwd/lib/File/Spec/VMS.pm
index ce0dab763e..16f4789c68 100644
--- a/dist/Cwd/lib/File/Spec/VMS.pm
+++ b/dist/Cwd/lib/File/Spec/VMS.pm
@@ -276,16 +276,17 @@ is tainted, it is not used.
=cut
-my $tmpdir;
sub tmpdir {
my $self = shift @_;
+ my $tmpdir = $self->_cached_tmpdir('TMPDIR');
return $tmpdir if defined $tmpdir;
if ($self->_unix_rpt) {
$tmpdir = $self->_tmpdir('/tmp', '/sys$scratch', $ENV{TMPDIR});
- return $tmpdir;
}
-
- $tmpdir = $self->_tmpdir( 'sys$scratch:', $ENV{TMPDIR} );
+ else {
+ $tmpdir = $self->_tmpdir( 'sys$scratch:', $ENV{TMPDIR} );
+ }
+ $self->_cache_tmpdir($tmpdir, 'TMPDIR');
}
=item updir (override)
diff --git a/dist/Cwd/lib/File/Spec/Win32.pm b/dist/Cwd/lib/File/Spec/Win32.pm
index ae74a26593..b606011bce 100644
--- a/dist/Cwd/lib/File/Spec/Win32.pm
+++ b/dist/Cwd/lib/File/Spec/Win32.pm
@@ -67,8 +67,8 @@ variables are tainted, they are not used.
=cut
-my $tmpdir;
sub tmpdir {
+ my $tmpdir = $_[0]->_cached_tmpdir(qw(TMPDIR TEMP TMP));
return $tmpdir if defined $tmpdir;
$tmpdir = $_[0]->_tmpdir( map( $ENV{$_}, qw(TMPDIR TEMP TMP) ),
'SYS:/temp',
@@ -76,6 +76,7 @@ sub tmpdir {
'C:/temp',
'/tmp',
'/' );
+ $_[0]->_cache_tmpdir($tmpdir, qw(TMPDIR TEMP TMP));
}
=item case_tolerant
diff --git a/dist/Cwd/t/tmpdir.t b/dist/Cwd/t/tmpdir.t
index 6f7f318180..7c13da1fe3 100644
--- a/dist/Cwd/t/tmpdir.t
+++ b/dist/Cwd/t/tmpdir.t
@@ -1,5 +1,5 @@
use strict;
-use Test::More tests => 5;
+use Test::More tests => 7;
# Grab all of the plain routines from File::Spec
use File::Spec;
@@ -29,3 +29,20 @@ SKIP: {
File::Spec::Win32->tmpdir;
is(scalar keys %ENV, $num_keys, "Win32->tmpdir() shouldn't change the contents of %ENV");
+
+# Changing tmpdir dynamically
+for ('File::Spec', "File::Spec::Win32") {
+ SKIP: {
+ skip('sys$scratch: takes precedence over env on vms', 1)
+ if $^O eq 'VMS';
+ local $ENV{TMPDIR} = $_->catfile($_->curdir, 'lib');
+ -d $ENV{TMPDIR} && -w _
+ or skip "Can't create usable TMPDIR env var", 1;
+ my $tmpdir1 = $_->tmpdir;
+ $ENV{TMPDIR} = $_->catfile($_->curdir, 't');
+ -d $ENV{TMPDIR} && -w _
+ or skip "Can't create usable TMPDIR env var", 1;
+ my $tmpdir2 = $_->tmpdir;
+ isn't $tmpdir2, $tmpdir1, "$_->tmpdir works with changing env";
+ }
+}