6 getcwd - get pathname of current working directory
25 The getcwd() function re-implements the getcwd(3) (or getwd(3)) functions
28 The fastcwd() function looks the same as getcwd(), but runs faster.
29 It's also more dangerous because it might conceivably chdir() you out
30 of a directory that it can't chdir() you back into. If fastcwd
31 encounters a problem it will return undef but will probably leave you
32 in a different directory. For a measure of extra security, if
33 everything appears to have worked, the fastcwd() function will check
34 that it leaves you in the same directory that it started in. If it has
35 changed it will C<die> with the message "Unstable directory path,
36 current directory changed unexpectedly". That should never happen.
38 The cwd() function looks the same as getcwd and fastgetcwd but is
39 implemented using the most natural and safe form for the current
40 architecture. For most systems it is identical to `pwd` (but without
41 the trailing line terminator).
43 It is recommended that cwd (or another *cwd() function) is used in
44 I<all> code to ensure portability.
46 If you ask to override your chdir() built-in function, then your PWD
47 environment variable will be kept up to date. (See
48 L<perlsub/Overriding Builtin Functions>.) Note that it will only be
49 kept up to date if all packages which use chdir import it from Cwd.
61 @EXPORT = qw(cwd getcwd fastcwd fastgetcwd);
62 @EXPORT_OK = qw(chdir abs_path fast_abs_path);
65 # The 'natural and safe form' for UNIX (pwd may be setuid root)
73 # Since some ports may predefine cwd internally (e.g., NT)
74 # we take care not to override an existing definition for cwd().
76 *cwd = \&_backtick_pwd unless defined &cwd;
79 # By Brandon S. Allbery
81 # Usage: $cwd = getcwd();
85 my($dotdots, $cwd, @pst, @cst, $dir, @tst);
87 unless (@cst = stat('.'))
96 $dotdots .= '/' if $dotdots;
99 unless (opendir(PARENT, $dotdots))
101 warn "opendir($dotdots): $!";
104 unless (@cst = stat($dotdots))
106 warn "stat($dotdots): $!";
110 if ($pst[0] == $cst[0] && $pst[1] == $cst[1])
118 unless (defined ($dir = readdir(PARENT)))
120 warn "readdir($dotdots): $!";
124 unless (@tst = lstat("$dotdots/$dir"))
126 # warn "lstat($dotdots/$dir): $!";
127 # Just because you can't lstat this directory
128 # doesn't mean you'll never find the right one.
133 while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] ||
136 $cwd = (defined $dir ? "$dir" : "" ) . "/$cwd" ;
138 } while (defined $dir);
139 chop($cwd) unless $cwd eq '/'; # drop the trailing /
147 # Usage: $cwd = &fastcwd;
149 # This is a faster version of getcwd. It's also more dangerous because
150 # you might chdir out of a directory that you can't chdir back into.
152 # List of metachars taken from do_exec() in doio.c
153 my $quoted_shell_meta = quotemeta('$&*(){}[]";\\|?<>~`'."'\n");
156 my($odev, $oino, $cdev, $cino, $tdev, $tino);
160 my($orig_cdev, $orig_cino) = stat('.');
161 ($cdev, $cino) = ($orig_cdev, $orig_cino);
164 ($odev, $oino) = ($cdev, $cino);
165 chdir('..') || return undef;
166 ($cdev, $cino) = stat('.');
167 last if $odev == $cdev && $oino == $cino;
168 opendir(DIR, '.') || return undef;
170 $direntry = readdir(DIR);
171 last unless defined $direntry;
172 next if $direntry eq '.';
173 next if $direntry eq '..';
175 ($tdev, $tino) = lstat($direntry);
176 last unless $tdev != $odev || $tino != $oino;
179 return undef unless defined $direntry; # should never happen
180 unshift(@path, $direntry);
182 $path = '/' . join('/', @path);
183 # At this point $path may be tainted (if tainting) and chdir would fail.
184 # To be more useful we untaint it then check that we landed where we started.
185 $path = $1 if $path =~ /^(.*)$/; # untaint
186 chdir($path) || return undef;
187 ($cdev, $cino) = stat('.');
188 die "Unstable directory path, current directory changed unexpectedly"
189 if $cdev != $orig_cdev || $cino != $orig_cino;
194 # Keeps track of current working directory in PWD environment var
202 if ($ENV{'PWD'} and $^O ne 'os2' and $^O ne 'msdos') {
203 my($dd,$di) = stat('.');
204 my($pd,$pi) = stat($ENV{'PWD'});
205 if (!defined $dd or !defined $pd or $di != $pi or $dd != $pd) {
212 # Strip an automounter prefix (where /tmp_mnt/foo/bar == /foo/bar)
213 if ($ENV{'PWD'} =~ m|(/[^/]+(/[^/]+/[^/]+))(.*)|) {
214 my($pd,$pi) = stat($2);
215 my($dd,$di) = stat($1);
216 if (defined $pd and defined $dd and $di == $pi and $dd == $pd) {
224 my $newdir = shift || ''; # allow for no arg (chdir to HOME dir)
225 $newdir =~ s|///*|/|g;
226 chdir_init() unless $chdir_init;
227 return 0 unless CORE::chdir $newdir;
228 if ($^O eq 'VMS') { return $ENV{'PWD'} = $ENV{'DEFAULT'} }
230 if ($newdir =~ m#^/#) {
231 $ENV{'PWD'} = $newdir;
233 my @curdir = split(m#/#,$ENV{'PWD'});
234 @curdir = ('') unless @curdir;
236 foreach $component (split(m#/#, $newdir)) {
237 next if $component eq '.';
238 pop(@curdir),next if $component eq '..';
239 push(@curdir,$component);
241 $ENV{'PWD'} = join('/',@curdir) || '/';
246 # Taken from Cwd.pm It is really getcwd with an optional
247 # parameter instead of '.'
252 my $start = shift || '.';
253 my($dotdots, $cwd, @pst, @cst, $dir, @tst);
255 unless (@cst = stat( $start ))
257 carp "stat($start): $!";
266 unless (opendir(PARENT, $dotdots))
268 carp "opendir($dotdots): $!";
271 unless (@cst = stat($dotdots))
273 carp "stat($dotdots): $!";
277 if ($pst[0] == $cst[0] && $pst[1] == $cst[1])
285 unless (defined ($dir = readdir(PARENT)))
287 carp "readdir($dotdots): $!";
291 $tst[0] = $pst[0]+1 unless (@tst = lstat("$dotdots/$dir"))
293 while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] ||
299 chop($cwd); # drop the trailing /
305 my $path = shift || '.';
306 chdir($path) || croak "Cannot chdir to $path:$!";
307 my $realpath = getcwd();
308 chdir($cwd) || croak "Cannot chdir back to $cwd:$!";
313 # --- PORTING SECTION ---
315 # VMS: $ENV{'DEFAULT'} points to default directory at all times
316 # 06-Mar-1996 Charles Bailey bailey@genetics.upenn.edu
317 # Note: Use of Cwd::chdir() causes the logical name PWD to be defined
318 # in the process logical name table as the default device and directory
319 # seen by Perl. This may not be the same as the default device
320 # and directory seen by DCL after Perl exits, since the effects
321 # the CRTL chdir() function persist only until Perl exits.
324 return $ENV{'DEFAULT'};
328 return $ENV{'DEFAULT'} unless @_;
329 my $path = VMS::Filespec::pathify($_[0]);
330 croak("Invalid path name $_[0]") unless defined $path;
331 return VMS::Filespec::rmsexpand($path);
335 $ENV{'PWD'} = `cmd /c cd`;
337 $ENV{'PWD'} =~ s:\\:/:g ;
342 $ENV{'PWD'} = Win32::GetCurrentDirectory();
343 $ENV{'PWD'} =~ s:\\:/:g ;
347 *_NT_cwd = \&_win32_cwd if (!defined &_NT_cwd &&
348 defined &Win32::GetCurrentDirectory);
350 *_NT_cwd = \&_os2_cwd unless defined &_NT_cwd;
353 $ENV{'PWD'} = `command /c cd`;
355 $ENV{'PWD'} =~ s:\\:/:g ;
360 local $^W = 0; # assignments trigger 'subroutine redefined' warning
364 *getcwd = \&_vms_cwd;
365 *fastcwd = \&_vms_cwd;
366 *fastgetcwd = \&_vms_cwd;
367 *abs_path = \&_vms_abs_path;
368 *fast_abs_path = \&_vms_abs_path;
370 elsif ($^O eq 'NT' or $^O eq 'MSWin32') {
371 # We assume that &_NT_cwd is defined as an XSUB or in the core.
374 *fastcwd = \&_NT_cwd;
375 *fastgetcwd = \&_NT_cwd;
376 *abs_path = \&fast_abs_path;
378 elsif ($^O eq 'os2') {
379 # sys_cwd may keep the builtin command
380 *cwd = defined &sys_cwd ? \&sys_cwd : \&_os2_cwd;
384 *abs_path = \&fast_abs_path;
386 elsif ($^O eq 'msdos') {
388 *getcwd = \&_msdos_cwd;
389 *fastgetcwd = \&_msdos_cwd;
390 *fastcwd = \&_msdos_cwd;
391 *abs_path = \&fast_abs_path;
395 # package main; eval join('',<DATA>) || die $@; # quick test
400 BEGIN { import Cwd qw(:DEFAULT chdir); }
401 print join("\n", cwd, getcwd, fastcwd, "");
403 print join("\n", cwd, getcwd, fastcwd, "");