1 | #!./perl -w
|
---|
2 |
|
---|
3 | BEGIN {
|
---|
4 | # We're not going to chdir() into 't' because we don't know if
|
---|
5 | # chdir() works! Instead, we'll hedge our bets and put both
|
---|
6 | # possibilities into @INC.
|
---|
7 | @INC = qw(t . lib ../lib);
|
---|
8 | }
|
---|
9 |
|
---|
10 | use Config;
|
---|
11 | require "test.pl";
|
---|
12 | plan(tests => 38);
|
---|
13 |
|
---|
14 | my $IsVMS = $^O eq 'VMS';
|
---|
15 | my $IsMacOS = $^O eq 'MacOS';
|
---|
16 |
|
---|
17 | # Might be a little early in the testing process to start using these,
|
---|
18 | # but I can't think of a way to write this test without them.
|
---|
19 | use File::Spec::Functions qw(:DEFAULT splitdir rel2abs splitpath);
|
---|
20 |
|
---|
21 | # Can't use Cwd::abs_path() because it has different ideas about
|
---|
22 | # path separators than File::Spec.
|
---|
23 | sub abs_path {
|
---|
24 | my $d = rel2abs(curdir);
|
---|
25 |
|
---|
26 | $d = uc($d) if $IsVMS;
|
---|
27 | $d = lc($d) if $^O =~ /^uwin/;
|
---|
28 | $d;
|
---|
29 | }
|
---|
30 |
|
---|
31 | my $Cwd = abs_path;
|
---|
32 |
|
---|
33 | # Let's get to a known position
|
---|
34 | SKIP: {
|
---|
35 | my ($vol,$dir) = splitpath(abs_path,1);
|
---|
36 | my $test_dir = $IsVMS ? 'T' : 't';
|
---|
37 | skip("Already in t/", 2) if (splitdir($dir))[-1] eq $test_dir;
|
---|
38 |
|
---|
39 | ok( chdir($test_dir), 'chdir($test_dir)');
|
---|
40 | is( abs_path, catdir($Cwd, $test_dir), ' abs_path() agrees' );
|
---|
41 | }
|
---|
42 |
|
---|
43 | $Cwd = abs_path;
|
---|
44 |
|
---|
45 | SKIP: {
|
---|
46 | skip("no fchdir", 6) unless ($Config{d_fchdir} || "") eq "define";
|
---|
47 | ok(opendir(my $dh, "."), "opendir .");
|
---|
48 | ok(open(my $fh, "<", "op"), "open op");
|
---|
49 | ok(chdir($fh), "fchdir op");
|
---|
50 | ok(-f "chdir.t", "verify that we are in op");
|
---|
51 | if (($Config{d_dirfd} || "") eq "define") {
|
---|
52 | ok(chdir($dh), "fchdir back");
|
---|
53 | }
|
---|
54 | else {
|
---|
55 | eval { chdir($dh); };
|
---|
56 | like($@, qr/^The dirfd function is unimplemented at/, "dirfd is unimplemented");
|
---|
57 | chdir "..";
|
---|
58 | }
|
---|
59 | ok(-d "op", "verify that we are back");
|
---|
60 | }
|
---|
61 |
|
---|
62 | SKIP: {
|
---|
63 | skip("has fchdir", 1) if ($Config{d_fchdir} || "") eq "define";
|
---|
64 | opendir(my $dh, "op");
|
---|
65 | eval { chdir($dh); };
|
---|
66 | like($@, qr/^The fchdir function is unimplemented at/, "fchdir is unimplemented");
|
---|
67 | }
|
---|
68 |
|
---|
69 | # The environment variables chdir() pays attention to.
|
---|
70 | my @magic_envs = qw(HOME LOGDIR SYS$LOGIN);
|
---|
71 |
|
---|
72 | sub check_env {
|
---|
73 | my($key) = @_;
|
---|
74 |
|
---|
75 | # Make sure $ENV{'SYS$LOGIN'} is only honored on VMS.
|
---|
76 | if( $key eq 'SYS$LOGIN' && !$IsVMS && !$IsMacOS ) {
|
---|
77 | ok( !chdir(), "chdir() on $^O ignores only \$ENV{$key} set" );
|
---|
78 | is( abs_path, $Cwd, ' abs_path() did not change' );
|
---|
79 | pass( " no need to test SYS\$LOGIN on $^O" ) for 1..7;
|
---|
80 | }
|
---|
81 | else {
|
---|
82 | ok( chdir(), "chdir() w/ only \$ENV{$key} set" );
|
---|
83 | is( abs_path, $ENV{$key}, ' abs_path() agrees' );
|
---|
84 | chdir($Cwd);
|
---|
85 | is( abs_path, $Cwd, ' and back again' );
|
---|
86 |
|
---|
87 | my $warning = '';
|
---|
88 | local $SIG{__WARN__} = sub { $warning .= join '', @_ };
|
---|
89 |
|
---|
90 |
|
---|
91 | # Check the deprecated chdir(undef) feature.
|
---|
92 | #line 64
|
---|
93 | ok( chdir(undef), "chdir(undef) w/ only \$ENV{$key} set" );
|
---|
94 | is( abs_path, $ENV{$key}, ' abs_path() agrees' );
|
---|
95 | is( $warning, <<WARNING, ' got uninit & deprecation warning' );
|
---|
96 | Use of uninitialized value in chdir at $0 line 64.
|
---|
97 | Use of chdir('') or chdir(undef) as chdir() is deprecated at $0 line 64.
|
---|
98 | WARNING
|
---|
99 |
|
---|
100 | chdir($Cwd);
|
---|
101 |
|
---|
102 | # Ditto chdir('').
|
---|
103 | $warning = '';
|
---|
104 | #line 76
|
---|
105 | ok( chdir(''), "chdir('') w/ only \$ENV{$key} set" );
|
---|
106 | is( abs_path, $ENV{$key}, ' abs_path() agrees' );
|
---|
107 | is( $warning, <<WARNING, ' got deprecation warning' );
|
---|
108 | Use of chdir('') or chdir(undef) as chdir() is deprecated at $0 line 76.
|
---|
109 | WARNING
|
---|
110 |
|
---|
111 | chdir($Cwd);
|
---|
112 | }
|
---|
113 | }
|
---|
114 |
|
---|
115 | my %Saved_Env = ();
|
---|
116 | sub clean_env {
|
---|
117 | foreach my $env (@magic_envs) {
|
---|
118 | $Saved_Env{$env} = $ENV{$env};
|
---|
119 |
|
---|
120 | # Can't actually delete SYS$ stuff on VMS.
|
---|
121 | next if $IsVMS && $env eq 'SYS$LOGIN';
|
---|
122 | next if $IsVMS && $env eq 'HOME' && !$Config{'d_setenv'};
|
---|
123 |
|
---|
124 | unless ($IsMacOS) { # ENV on MacOS is "special" :-)
|
---|
125 | # On VMS, %ENV is many layered.
|
---|
126 | delete $ENV{$env} while exists $ENV{$env};
|
---|
127 | }
|
---|
128 | }
|
---|
129 |
|
---|
130 | # The following means we won't really be testing for non-existence,
|
---|
131 | # but in Perl we can only delete from the process table, not the job
|
---|
132 | # table.
|
---|
133 | $ENV{'SYS$LOGIN'} = '' if $IsVMS;
|
---|
134 | }
|
---|
135 |
|
---|
136 | END {
|
---|
137 | no warnings 'uninitialized';
|
---|
138 |
|
---|
139 | # Restore the environment for VMS (and doesn't hurt for anyone else)
|
---|
140 | @ENV{@magic_envs} = @Saved_Env{@magic_envs};
|
---|
141 | }
|
---|
142 |
|
---|
143 |
|
---|
144 | foreach my $key (@magic_envs) {
|
---|
145 | # We're going to be using undefs a lot here.
|
---|
146 | no warnings 'uninitialized';
|
---|
147 |
|
---|
148 | clean_env;
|
---|
149 | $ENV{$key} = catdir $Cwd, ($IsVMS ? 'OP' : 'op');
|
---|
150 |
|
---|
151 | check_env($key);
|
---|
152 | }
|
---|
153 |
|
---|
154 | {
|
---|
155 | clean_env;
|
---|
156 | if (($IsVMS || $IsMacOS) && !$Config{'d_setenv'}) {
|
---|
157 | pass("Can't reset HOME, so chdir() test meaningless");
|
---|
158 | } else {
|
---|
159 | ok( !chdir(), 'chdir() w/o any ENV set' );
|
---|
160 | }
|
---|
161 | is( abs_path, $Cwd, ' abs_path() agrees' );
|
---|
162 | }
|
---|