Sort perldiag.
[p5sagit/p5-mst-13.2.git] / lib / Cwd.pm
CommitLineData
a0d0e21e 1package Cwd;
7ada78df 2$VERSION = $VERSION = '2.19';
a0d0e21e 3
f06db76b 4=head1 NAME
5
902bacac 6Cwd - get pathname of current working directory
f06db76b 7
8=head1 SYNOPSIS
9
4633a7c4 10 use Cwd;
04929354 11 my $dir = getcwd;
4633a7c4 12
04929354 13 use Cwd 'abs_path';
14 my $abs_path = abs_path($file);
f06db76b 15
04929354 16=head1 DESCRIPTION
902bacac 17
04929354 18This module provides functions for determining the pathname of the
19current working directory. It is recommended that getcwd (or another
20*cwd() function) be used in I<all> code to ensure portability.
f06db76b 21
04929354 22By default, it exports the functions cwd(), getcwd(), fastcwd(), and
09122b95 23fastgetcwd() (and, on Win32, getdcwd()) into the caller's namespace.
f06db76b 24
20408e3c 25
04929354 26=head2 getcwd and friends
20408e3c 27
04929354 28Each of these functions are called without arguments and return the
29absolute path of the current working directory.
f06db76b 30
04929354 31=over 4
32
33=item getcwd
34
35 my $cwd = getcwd();
36
37Returns the current working directory.
38
39Re-implements the getcwd(3) (or getwd(3)) functions in Perl.
40
41=item cwd
42
43 my $cwd = cwd();
44
45The cwd() is the most natural form for the current architecture. For
46most systems it is identical to `pwd` (but without the trailing line
47terminator).
48
04929354 49=item fastcwd
50
51 my $cwd = fastcwd();
52
53A more dangerous version of getcwd(), but potentially faster.
54
55It might conceivably chdir() you out of a directory that it can't
56chdir() you back into. If fastcwd encounters a problem it will return
57undef but will probably leave you in a different directory. For a
58measure of extra security, if everything appears to have worked, the
59fastcwd() function will check that it leaves you in the same directory
60that it started in. If it has changed it will C<die> with the message
61"Unstable directory path, current directory changed
62unexpectedly". That should never happen.
63
64=item fastgetcwd
65
66 my $cwd = fastgetcwd();
f06db76b 67
902bacac 68The fastgetcwd() function is provided as a synonym for cwd().
fb73857a 69
09122b95 70=item getdcwd
71
72 my $cwd = getdcwd();
73 my $cwd = getdcwd('C:');
74
75The getdcwd() function is also provided on Win32 to get the current working
76directory on the specified drive, since Windows maintains a separate current
77working directory for each drive. If no drive is specified then the current
78drive is assumed.
79
80This function simply calls the Microsoft C library _getdcwd() function.
81
04929354 82=back
83
902bacac 84
04929354 85=head2 abs_path and friends
86
87These functions are exported only on request. They each take a single
3ee63918 88argument and return the absolute pathname for it. If no argument is
89given they'll use the current working directory.
04929354 90
91=over 4
92
93=item abs_path
94
95 my $abs_path = abs_path($file);
96
97Uses the same algorithm as getcwd(). Symbolic links and relative-path
98components ("." and "..") are resolved to return the canonical
99pathname, just like realpath(3).
100
101=item realpath
102
103 my $abs_path = realpath($file);
104
105A synonym for abs_path().
106
107=item fast_abs_path
108
510179aa 109 my $abs_path = fast_abs_path($file);
04929354 110
111A more dangerous, but potentially faster version of abs_path.
112
113=back
114
115=head2 $ENV{PWD}
116
117If you ask to override your chdir() built-in function,
118
119 use Cwd qw(chdir);
120
121then your PWD environment variable will be kept up to date. Note that
122it will only be kept up to date if all packages which use chdir import
123it from Cwd.
4633a7c4 124
4633a7c4 125
4d6b4052 126=head1 NOTES
127
128=over 4
129
130=item *
131
04929354 132Since the path seperators are different on some operating systems ('/'
133on Unix, ':' on MacPerl, etc...) we recommend you use the File::Spec
134modules wherever portability is a concern.
135
04929354 136=item *
4d6b4052 137
138Actually, on Mac OS, the C<getcwd()>, C<fastgetcwd()> and C<fastcwd()>
139functions are all aliases for the C<cwd()> function, which, on Mac OS,
140calls `pwd`. Likewise, the C<abs_path()> function is an alias for
141C<fast_abs_path()>.
142
143=back
144
02cc4877 145=head1 AUTHOR
146
147Originally by the perl5-porters.
148
78321866 149Maintained by Ken Williams <KWILLIAMS@cpan.org>
02cc4877 150
04929354 151=head1 SEE ALSO
152
153L<File::chdir>
154
f06db76b 155=cut
156
b060a406 157use strict;
a9939470 158use Exporter;
ad78113d 159use vars qw(@ISA @EXPORT @EXPORT_OK);
96e4d5b1 160
a9939470 161@ISA = qw/ Exporter /;
162@EXPORT = qw(cwd getcwd fastcwd fastgetcwd);
09122b95 163push @EXPORT, qw(getdcwd) if $^O eq 'MSWin32';
a9939470 164@EXPORT_OK = qw(chdir abs_path fast_abs_path realpath fast_realpath);
a0d0e21e 165
f5f423e4 166# sys_cwd may keep the builtin command
167
168# All the functionality of this module may provided by builtins,
169# there is no sense to process the rest of the file.
170# The best choice may be to have this in BEGIN, but how to return from BEGIN?
171
a9939470 172if ($^O eq 'os2') {
f5f423e4 173 local $^W = 0;
a9939470 174
175 *cwd = defined &sys_cwd ? \&sys_cwd : \&_os2_cwd;
176 *getcwd = \&cwd;
177 *fastgetcwd = \&cwd;
178 *fastcwd = \&cwd;
179
180 *fast_abs_path = \&sys_abspath if defined &sys_abspath;
181 *abs_path = \&fast_abs_path;
182 *realpath = \&fast_abs_path;
183 *fast_realpath = \&fast_abs_path;
184
f5f423e4 185 return 1;
186}
187
f22d8e4b 188eval {
189 require XSLoader;
46ba3155 190 local $^W = 0;
f22d8e4b 191 XSLoader::load('Cwd');
192};
4633a7c4 193
09122b95 194# Big nasty table of function aliases
195my %METHOD_MAP =
196 (
197 VMS =>
198 {
199 cwd => '_vms_cwd',
200 getcwd => '_vms_cwd',
201 fastcwd => '_vms_cwd',
202 fastgetcwd => '_vms_cwd',
203 abs_path => '_vms_abs_path',
204 fast_abs_path => '_vms_abs_path',
205 },
206
207 MSWin32 =>
208 {
209 # We assume that &_NT_cwd is defined as an XSUB or in the core.
210 cwd => '_NT_cwd',
211 getcwd => '_NT_cwd',
212 fastcwd => '_NT_cwd',
213 fastgetcwd => '_NT_cwd',
214 abs_path => 'fast_abs_path',
215 realpath => 'fast_abs_path',
216 },
217
218 dos =>
219 {
220 cwd => '_dos_cwd',
221 getcwd => '_dos_cwd',
222 fastgetcwd => '_dos_cwd',
223 fastcwd => '_dos_cwd',
224 abs_path => 'fast_abs_path',
225 },
226
227 qnx =>
228 {
229 cwd => '_qnx_cwd',
230 getcwd => '_qnx_cwd',
231 fastgetcwd => '_qnx_cwd',
232 fastcwd => '_qnx_cwd',
233 abs_path => '_qnx_abs_path',
234 fast_abs_path => '_qnx_abs_path',
235 },
236
237 cygwin =>
238 {
239 getcwd => 'cwd',
240 fastgetcwd => 'cwd',
241 fastcwd => 'cwd',
242 abs_path => 'fast_abs_path',
243 realpath => 'fast_abs_path',
244 },
245
246 epoc =>
247 {
248 cwd => '_epoc_cwd',
249 getcwd => '_epoc_cwd',
250 fastgetcwd => '_epoc_cwd',
251 fastcwd => '_epoc_cwd',
252 abs_path => 'fast_abs_path',
253 },
254
255 MacOS =>
256 {
257 getcwd => 'cwd',
258 fastgetcwd => 'cwd',
259 fastcwd => 'cwd',
260 abs_path => 'fast_abs_path',
261 },
262 );
263
264$METHOD_MAP{NT} = $METHOD_MAP{MSWin32};
265$METHOD_MAP{nto} = $METHOD_MAP{qnx};
266
96e4d5b1 267
3547aa9a 268# Find the pwd command in the expected locations. We assume these
269# are safe. This prevents _backtick_pwd() consulting $ENV{PATH}
270# so everything works under taint mode.
271my $pwd_cmd;
889f7a4f 272foreach my $try ('/bin/pwd',
273 '/usr/bin/pwd',
274 '/QOpenSys/bin/pwd', # OS/400 PASE.
275 ) {
276
3547aa9a 277 if( -x $try ) {
278 $pwd_cmd = $try;
279 last;
280 }
281}
522b859a 282unless ($pwd_cmd) {
889f7a4f 283 # Isn't this wrong? _backtick_pwd() will fail if somenone has
284 # pwd in their path but it is not /bin/pwd or /usr/bin/pwd?
285 # See [perl #16774]. --jhi
286 $pwd_cmd = 'pwd';
522b859a 287}
3547aa9a 288
a9939470 289# Lazy-load Carp
290sub _carp { require Carp; Carp::carp(@_) }
291sub _croak { require Carp; Carp::croak(@_) }
292
3547aa9a 293# The 'natural and safe form' for UNIX (pwd may be setuid root)
8b88ae92 294sub _backtick_pwd {
db281859 295 local @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)};
3547aa9a 296 my $cwd = `$pwd_cmd`;
ac3b20cb 297 # Belt-and-suspenders in case someone said "undef $/".
5cf6da5f 298 local $/ = "\n";
ac3b20cb 299 # `pwd` may fail e.g. if the disk is full
7e03f963 300 chomp($cwd) if defined $cwd;
4633a7c4 301 $cwd;
8b88ae92 302}
4633a7c4 303
304# Since some ports may predefine cwd internally (e.g., NT)
305# we take care not to override an existing definition for cwd().
306
09122b95 307unless ($METHOD_MAP{$^O}{cwd} or defined &cwd) {
ea54c8bd 308 # The pwd command is not available in some chroot(2)'ed environments
09122b95 309 my $sep = $Config::Config{path_sep} || ':';
310 if( $^O eq 'MacOS' || (defined $ENV{PATH} &&
311 grep { -x "$_/pwd" } split($sep, $ENV{PATH})) )
73b801a6 312 {
ea54c8bd 313 *cwd = \&_backtick_pwd;
314 }
315 else {
316 *cwd = \&getcwd;
317 }
318}
a0d0e21e 319
1f4f94f5 320# set a reasonable (and very safe) default for fastgetcwd, in case it
321# isn't redefined later (20001212 rspier)
322*fastgetcwd = \&cwd;
748a9306 323
a0d0e21e 324# By Brandon S. Allbery
325#
326# Usage: $cwd = getcwd();
327
328sub getcwd
329{
07569ed3 330 abs_path('.');
a0d0e21e 331}
332
a0c9c202 333
334# By John Bazik
335#
336# Usage: $cwd = &fastcwd;
337#
338# This is a faster version of getcwd. It's also more dangerous because
339# you might chdir out of a directory that you can't chdir back into.
340
341sub fastcwd {
342 my($odev, $oino, $cdev, $cino, $tdev, $tino);
343 my(@path, $path);
344 local(*DIR);
345
346 my($orig_cdev, $orig_cino) = stat('.');
347 ($cdev, $cino) = ($orig_cdev, $orig_cino);
348 for (;;) {
349 my $direntry;
350 ($odev, $oino) = ($cdev, $cino);
351 CORE::chdir('..') || return undef;
352 ($cdev, $cino) = stat('.');
353 last if $odev == $cdev && $oino == $cino;
354 opendir(DIR, '.') || return undef;
355 for (;;) {
356 $direntry = readdir(DIR);
357 last unless defined $direntry;
358 next if $direntry eq '.';
359 next if $direntry eq '..';
360
361 ($tdev, $tino) = lstat($direntry);
362 last unless $tdev != $odev || $tino != $oino;
363 }
364 closedir(DIR);
365 return undef unless defined $direntry; # should never happen
366 unshift(@path, $direntry);
367 }
368 $path = '/' . join('/', @path);
369 if ($^O eq 'apollo') { $path = "/".$path; }
370 # At this point $path may be tainted (if tainting) and chdir would fail.
248785eb 371 # Untaint it then check that we landed where we started.
372 $path =~ /^(.*)\z/s # untaint
373 && CORE::chdir($1) or return undef;
a0c9c202 374 ($cdev, $cino) = stat('.');
375 die "Unstable directory path, current directory changed unexpectedly"
376 if $cdev != $orig_cdev || $cino != $orig_cino;
377 $path;
378}
379
380
4633a7c4 381# Keeps track of current working directory in PWD environment var
a0d0e21e 382# Usage:
383# use Cwd 'chdir';
384# chdir $newdir;
385
4633a7c4 386my $chdir_init = 0;
a0d0e21e 387
4633a7c4 388sub chdir_init {
3b8e3443 389 if ($ENV{'PWD'} and $^O ne 'os2' and $^O ne 'dos' and $^O ne 'MSWin32') {
a0d0e21e 390 my($dd,$di) = stat('.');
391 my($pd,$pi) = stat($ENV{'PWD'});
392 if (!defined $dd or !defined $pd or $di != $pi or $dd != $pd) {
4633a7c4 393 $ENV{'PWD'} = cwd();
a0d0e21e 394 }
395 }
396 else {
3b8e3443 397 my $wd = cwd();
398 $wd = Win32::GetFullPathName($wd) if $^O eq 'MSWin32';
399 $ENV{'PWD'} = $wd;
a0d0e21e 400 }
4633a7c4 401 # Strip an automounter prefix (where /tmp_mnt/foo/bar == /foo/bar)
3b8e3443 402 if ($^O ne 'MSWin32' and $ENV{'PWD'} =~ m|(/[^/]+(/[^/]+/[^/]+))(.*)|s) {
a0d0e21e 403 my($pd,$pi) = stat($2);
404 my($dd,$di) = stat($1);
405 if (defined $pd and defined $dd and $di == $pi and $dd == $pd) {
406 $ENV{'PWD'}="$2$3";
407 }
408 }
409 $chdir_init = 1;
410}
411
412sub chdir {
22978713 413 my $newdir = @_ ? shift : ''; # allow for no arg (chdir to HOME dir)
3b8e3443 414 $newdir =~ s|///*|/|g unless $^O eq 'MSWin32';
a0d0e21e 415 chdir_init() unless $chdir_init;
4ffa1610 416 my $newpwd;
417 if ($^O eq 'MSWin32') {
418 # get the full path name *before* the chdir()
419 $newpwd = Win32::GetFullPathName($newdir);
420 }
421
4633a7c4 422 return 0 unless CORE::chdir $newdir;
4ffa1610 423
3b8e3443 424 if ($^O eq 'VMS') {
425 return $ENV{'PWD'} = $ENV{'DEFAULT'}
426 }
4aecb5b5 427 elsif ($^O eq 'MacOS') {
428 return $ENV{'PWD'} = cwd();
429 }
3b8e3443 430 elsif ($^O eq 'MSWin32') {
4ffa1610 431 $ENV{'PWD'} = $newpwd;
3b8e3443 432 return 1;
433 }
748a9306 434
392d8ab8 435 if ($newdir =~ m#^/#s) {
a0d0e21e 436 $ENV{'PWD'} = $newdir;
4633a7c4 437 } else {
438 my @curdir = split(m#/#,$ENV{'PWD'});
439 @curdir = ('') unless @curdir;
440 my $component;
a0d0e21e 441 foreach $component (split(m#/#, $newdir)) {
442 next if $component eq '.';
443 pop(@curdir),next if $component eq '..';
444 push(@curdir,$component);
445 }
446 $ENV{'PWD'} = join('/',@curdir) || '/';
447 }
4633a7c4 448 1;
a0d0e21e 449}
450
a0c9c202 451
452# In case the XS version doesn't load.
453*abs_path = \&_perl_abs_path unless defined &abs_path;
09122b95 454sub _perl_abs_path(;$)
a0c9c202 455{
456 my $start = @_ ? shift : '.';
457 my($dotdots, $cwd, @pst, @cst, $dir, @tst);
458
459 unless (@cst = stat( $start ))
460 {
a9939470 461 _carp("stat($start): $!");
a0c9c202 462 return '';
463 }
09122b95 464
465 unless (-d _) {
466 # Make sure we can be invoked on plain files, not just directories.
467 # NOTE that this routine assumes that '/' is the only directory separator.
468
469 my ($dir, $file) = $start =~ m{^(.*)/(.+)$}
470 or return cwd() . '/' . $start;
471
472 if (-l _) {
473 my $link_target = readlink($start);
474 die "Can't resolve link $start: $!" unless defined $link_target;
475
476 require File::Spec;
477 $link_target = $dir . '/' . $link_target
478 unless File::Spec->file_name_is_absolute($link_target);
479
480 return abs_path($link_target);
481 }
482
483 return abs_path($dir) . '/' . $file;
484 }
485
a0c9c202 486 $cwd = '';
487 $dotdots = $start;
488 do
489 {
490 $dotdots .= '/..';
491 @pst = @cst;
a25ef67d 492 local *PARENT;
a0c9c202 493 unless (opendir(PARENT, $dotdots))
494 {
a9939470 495 _carp("opendir($dotdots): $!");
a0c9c202 496 return '';
497 }
498 unless (@cst = stat($dotdots))
499 {
a9939470 500 _carp("stat($dotdots): $!");
a0c9c202 501 closedir(PARENT);
502 return '';
503 }
504 if ($pst[0] == $cst[0] && $pst[1] == $cst[1])
505 {
506 $dir = undef;
507 }
508 else
509 {
510 do
511 {
512 unless (defined ($dir = readdir(PARENT)))
513 {
a9939470 514 _carp("readdir($dotdots): $!");
a0c9c202 515 closedir(PARENT);
516 return '';
517 }
518 $tst[0] = $pst[0]+1 unless (@tst = lstat("$dotdots/$dir"))
519 }
520 while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] ||
521 $tst[1] != $pst[1]);
522 }
523 $cwd = (defined $dir ? "$dir" : "" ) . "/$cwd" ;
524 closedir(PARENT);
525 } while (defined $dir);
526 chop($cwd) unless $cwd eq '/'; # drop the trailing /
527 $cwd;
528}
529
530
e4c51978 531# added function alias for those of us more
532# used to the libc function. --tchrist 27-Jan-00
533*realpath = \&abs_path;
534
3ee63918 535my $Curdir;
96e4d5b1 536sub fast_abs_path {
537 my $cwd = getcwd();
4d6b4052 538 require File::Spec;
3ee63918 539 my $path = @_ ? shift : ($Curdir ||= File::Spec->curdir);
540
541 # Detaint else we'll explode in taint mode. This is safe because
542 # we're not doing anything dangerous with it.
543 ($path) = $path =~ /(.*)/;
544 ($cwd) = $cwd =~ /(.*)/;
545
09122b95 546 unless (-e $path) {
547 _croak("$path: No such file or directory");
548 }
549
550 unless (-d _) {
551 # Make sure we can be invoked on plain files, not just directories.
552
553 my ($vol, $dir, $file) = File::Spec->splitpath($path);
554 return File::Spec->catfile($cwd, $path) unless length $dir;
555
556 if (-l $path) {
557 my $link_target = readlink($path);
558 die "Can't resolve link $path: $!" unless defined $link_target;
559
560 $link_target = File::Spec->catpath($vol, $dir, $link_target)
561 unless File::Spec->file_name_is_absolute($link_target);
562
563 return fast_abs_path($link_target);
564 }
565
566 return fast_abs_path(File::Spec->catpath($vol, $dir, '')) . '/' . $file;
567 }
568
e2ba406b 569 if (!CORE::chdir($path)) {
a9939470 570 _croak("Cannot chdir to $path: $!");
e2ba406b 571 }
96e4d5b1 572 my $realpath = getcwd();
e2ba406b 573 if (! ((-d $cwd) && (CORE::chdir($cwd)))) {
a9939470 574 _croak("Cannot chdir back to $cwd: $!");
e2ba406b 575 }
96e4d5b1 576 $realpath;
8b88ae92 577}
578
e4c51978 579# added function alias to follow principle of least surprise
580# based on previous aliasing. --tchrist 27-Jan-00
581*fast_realpath = \&fast_abs_path;
582
4633a7c4 583
584# --- PORTING SECTION ---
585
586# VMS: $ENV{'DEFAULT'} points to default directory at all times
bd3fa61c 587# 06-Mar-1996 Charles Bailey bailey@newman.upenn.edu
c6538b72 588# Note: Use of Cwd::chdir() causes the logical name PWD to be defined
8b88ae92 589# in the process logical name table as the default device and directory
590# seen by Perl. This may not be the same as the default device
4633a7c4 591# and directory seen by DCL after Perl exits, since the effects
592# the CRTL chdir() function persist only until Perl exits.
4633a7c4 593
594sub _vms_cwd {
96e4d5b1 595 return $ENV{'DEFAULT'};
596}
597
598sub _vms_abs_path {
599 return $ENV{'DEFAULT'} unless @_;
9d7d9729 600
601 # may need to turn foo.dir into [.foo]
96e4d5b1 602 my $path = VMS::Filespec::pathify($_[0]);
9d7d9729 603 $path = $_[0] unless defined $path;
604
96e4d5b1 605 return VMS::Filespec::rmsexpand($path);
4633a7c4 606}
68dc0745 607
4633a7c4 608sub _os2_cwd {
609 $ENV{'PWD'} = `cmd /c cd`;
39741d73 610 chomp $ENV{'PWD'};
aa6b7957 611 $ENV{'PWD'} =~ s:\\:/:g ;
4633a7c4 612 return $ENV{'PWD'};
613}
614
96e4d5b1 615sub _win32_cwd {
2d7a9237 616 $ENV{'PWD'} = Win32::GetCwd();
aa6b7957 617 $ENV{'PWD'} =~ s:\\:/:g ;
96e4d5b1 618 return $ENV{'PWD'};
619}
620
621*_NT_cwd = \&_win32_cwd if (!defined &_NT_cwd &&
2d7a9237 622 defined &Win32::GetCwd);
96e4d5b1 623
624*_NT_cwd = \&_os2_cwd unless defined &_NT_cwd;
68dc0745 625
39e571d4 626sub _dos_cwd {
627 if (!defined &Dos::GetCwd) {
628 $ENV{'PWD'} = `command /c cd`;
39741d73 629 chomp $ENV{'PWD'};
aa6b7957 630 $ENV{'PWD'} =~ s:\\:/:g ;
39e571d4 631 } else {
632 $ENV{'PWD'} = Dos::GetCwd();
633 }
55497cff 634 return $ENV{'PWD'};
635}
636
7fbf1995 637sub _qnx_cwd {
35b807ef 638 local $ENV{PATH} = '';
639 local $ENV{CDPATH} = '';
640 local $ENV{ENV} = '';
7fbf1995 641 $ENV{'PWD'} = `/usr/bin/fullpath -t`;
39741d73 642 chomp $ENV{'PWD'};
7fbf1995 643 return $ENV{'PWD'};
644}
645
646sub _qnx_abs_path {
35b807ef 647 local $ENV{PATH} = '';
648 local $ENV{CDPATH} = '';
649 local $ENV{ENV} = '';
fa921dc6 650 my $path = @_ ? shift : '.';
39741d73 651 local *REALPATH;
652
653 open(REALPATH, '-|', '/usr/bin/fullpath', '-t', $path) or
654 die "Can't open /usr/bin/fullpath: $!";
655 my $realpath = <REALPATH>;
656 close REALPATH;
657 chomp $realpath;
7fbf1995 658 return $realpath;
659}
660
ed79a026 661sub _epoc_cwd {
662 $ENV{'PWD'} = EPOC::getcwd();
663 return $ENV{'PWD'};
664}
665
4633a7c4 666
09122b95 667# Now that all the base-level functions are set up, alias the
668# user-level functions to the right places
669
670if (exists $METHOD_MAP{$^O}) {
671 my $map = $METHOD_MAP{$^O};
672 foreach my $name (keys %$map) {
673 no warnings; # assignments trigger 'subroutine redefined' warning
674 no strict 'refs';
675 *{$name} = \&{$map->{$name}};
676 }
55497cff 677}
4633a7c4 678
4633a7c4 679
a0d0e21e 6801;