xref: /openbsd-src/gnu/usr.bin/perl/dist/PathTools/Cwd.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
1package Cwd;
2use strict;
3use Exporter;
4
5
6our $VERSION = '3.91';
7my $xs_version = $VERSION;
8$VERSION =~ tr/_//d;
9
10our @ISA = qw/ Exporter /;
11our @EXPORT = qw(cwd getcwd fastcwd fastgetcwd);
12push @EXPORT, qw(getdcwd) if $^O eq 'MSWin32';
13our @EXPORT_OK = qw(chdir abs_path fast_abs_path realpath fast_realpath);
14
15# sys_cwd may keep the builtin command
16
17# All the functionality of this module may provided by builtins,
18# there is no sense to process the rest of the file.
19# The best choice may be to have this in BEGIN, but how to return from BEGIN?
20
21if ($^O eq 'os2') {
22    local $^W = 0;
23
24    *cwd                = defined &sys_cwd ? \&sys_cwd : \&_os2_cwd;
25    *getcwd             = \&cwd;
26    *fastgetcwd         = \&cwd;
27    *fastcwd            = \&cwd;
28
29    *fast_abs_path      = \&sys_abspath if defined &sys_abspath;
30    *abs_path           = \&fast_abs_path;
31    *realpath           = \&fast_abs_path;
32    *fast_realpath      = \&fast_abs_path;
33
34    return 1;
35}
36
37# Need to look up the feature settings on VMS.  The preferred way is to use the
38# VMS::Feature module, but that may not be available to dual life modules.
39
40my $use_vms_feature;
41BEGIN {
42    if ($^O eq 'VMS') {
43        if (eval { local $SIG{__DIE__};
44                   local @INC = @INC;
45                   pop @INC if $INC[-1] eq '.';
46                   require VMS::Feature; }) {
47            $use_vms_feature = 1;
48        }
49    }
50}
51
52# Need to look up the UNIX report mode.  This may become a dynamic mode
53# in the future.
54sub _vms_unix_rpt {
55    my $unix_rpt;
56    if ($use_vms_feature) {
57        $unix_rpt = VMS::Feature::current("filename_unix_report");
58    } else {
59        my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
60        $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
61    }
62    return $unix_rpt;
63}
64
65# Need to look up the EFS character set mode.  This may become a dynamic
66# mode in the future.
67sub _vms_efs {
68    my $efs;
69    if ($use_vms_feature) {
70        $efs = VMS::Feature::current("efs_charset");
71    } else {
72        my $env_efs = $ENV{'DECC$EFS_CHARSET'} || '';
73        $efs = $env_efs =~ /^[ET1]/i;
74    }
75    return $efs;
76}
77
78
79# If loading the XS stuff doesn't work, we can fall back to pure perl
80if(! defined &getcwd && defined &DynaLoader::boot_DynaLoader) { # skipped on miniperl
81    require XSLoader;
82    XSLoader::load( __PACKAGE__, $xs_version);
83}
84
85# Big nasty table of function aliases
86my %METHOD_MAP =
87  (
88   VMS =>
89   {
90    cwd			=> '_vms_cwd',
91    getcwd		=> '_vms_cwd',
92    fastcwd		=> '_vms_cwd',
93    fastgetcwd		=> '_vms_cwd',
94    abs_path		=> '_vms_abs_path',
95    fast_abs_path	=> '_vms_abs_path',
96   },
97
98   MSWin32 =>
99   {
100    # We assume that &_NT_cwd is defined as an XSUB or in the core.
101    cwd			=> '_NT_cwd',
102    getcwd		=> '_NT_cwd',
103    fastcwd		=> '_NT_cwd',
104    fastgetcwd		=> '_NT_cwd',
105    abs_path		=> 'fast_abs_path',
106    realpath		=> 'fast_abs_path',
107   },
108
109   dos =>
110   {
111    cwd			=> '_dos_cwd',
112    getcwd		=> '_dos_cwd',
113    fastgetcwd		=> '_dos_cwd',
114    fastcwd		=> '_dos_cwd',
115    abs_path		=> 'fast_abs_path',
116   },
117
118   # QNX4.  QNX6 has a $os of 'nto'.
119   qnx =>
120   {
121    cwd			=> '_qnx_cwd',
122    getcwd		=> '_qnx_cwd',
123    fastgetcwd		=> '_qnx_cwd',
124    fastcwd		=> '_qnx_cwd',
125    abs_path		=> '_qnx_abs_path',
126    fast_abs_path	=> '_qnx_abs_path',
127   },
128
129   cygwin =>
130   {
131    getcwd		=> 'cwd',
132    fastgetcwd		=> 'cwd',
133    fastcwd		=> 'cwd',
134    abs_path		=> 'fast_abs_path',
135    realpath		=> 'fast_abs_path',
136   },
137
138   amigaos =>
139   {
140    getcwd              => '_backtick_pwd',
141    fastgetcwd          => '_backtick_pwd',
142    fastcwd             => '_backtick_pwd',
143    abs_path            => 'fast_abs_path',
144   }
145  );
146
147$METHOD_MAP{NT} = $METHOD_MAP{MSWin32};
148
149
150# Find the pwd command in the expected locations.  We assume these
151# are safe.  This prevents _backtick_pwd() consulting $ENV{PATH}
152# so everything works under taint mode.
153my $pwd_cmd;
154if($^O ne 'MSWin32') {
155    foreach my $try ('/bin/pwd',
156		     '/usr/bin/pwd',
157		     '/QOpenSys/bin/pwd', # OS/400 PASE.
158		    ) {
159	if( -x $try ) {
160	    $pwd_cmd = $try;
161	    last;
162	}
163    }
164}
165
166# Android has a built-in pwd. Using $pwd_cmd will DTRT if
167# this perl was compiled with -Dd_useshellcmds, which is the
168# default for Android, but the block below is needed for the
169# miniperl running on the host when cross-compiling, and
170# potentially for native builds with -Ud_useshellcmds.
171if ($^O =~ /android/) {
172    # If targetsh is executable, then we're either a full
173    # perl, or a miniperl for a native build.
174    if ( exists($Config::Config{targetsh}) && -x $Config::Config{targetsh}) {
175        $pwd_cmd = "$Config::Config{targetsh} -c pwd"
176    }
177    else {
178        my $sh = $Config::Config{sh} || (-x '/system/bin/sh' ? '/system/bin/sh' : 'sh');
179        $pwd_cmd = "$sh -c pwd"
180    }
181}
182
183my $found_pwd_cmd = defined($pwd_cmd);
184
185# Lazy-load Carp
186sub _carp  { require Carp; Carp::carp(@_)  }
187sub _croak { require Carp; Carp::croak(@_) }
188
189# The 'natural and safe form' for UNIX (pwd may be setuid root)
190sub _backtick_pwd {
191
192    # Localize %ENV entries in a way that won't create new hash keys.
193    # Under AmigaOS we don't want to localize as it stops perl from
194    # finding 'sh' in the PATH.
195    my @localize = grep exists $ENV{$_}, qw(IFS CDPATH ENV BASH_ENV) if $^O ne "amigaos";
196    local @ENV{@localize} if @localize;
197    # empty PATH is the same as "." on *nix, so localize it to /something/
198    # we won't *use* the path as code above turns $pwd_cmd into a specific
199    # executable, but it will blow up anyway under taint. We could set it to
200    # anything absolute. Perhaps "/" would be better.
201    local $ENV{PATH}= "/usr/bin"
202        if $^O ne "amigaos";
203
204    my $cwd = `$pwd_cmd`;
205    # Belt-and-suspenders in case someone said "undef $/".
206    local $/ = "\n";
207    # `pwd` may fail e.g. if the disk is full
208    chomp($cwd) if defined $cwd;
209    $cwd;
210}
211
212# Since some ports may predefine cwd internally (e.g., NT)
213# we take care not to override an existing definition for cwd().
214
215unless ($METHOD_MAP{$^O}{cwd} or defined &cwd) {
216    if( $found_pwd_cmd )
217    {
218	*cwd = \&_backtick_pwd;
219    }
220    else {
221        # getcwd() might have an empty prototype
222	*cwd = sub { getcwd(); };
223    }
224}
225
226if ($^O eq 'cygwin') {
227  # We need to make sure cwd() is called with no args, because it's
228  # got an arg-less prototype and will die if args are present.
229  local $^W = 0;
230  my $orig_cwd = \&cwd;
231  *cwd = sub { &$orig_cwd() }
232}
233
234
235# set a reasonable (and very safe) default for fastgetcwd, in case it
236# isn't redefined later (20001212 rspier)
237*fastgetcwd = \&cwd;
238
239# A non-XS version of getcwd() - also used to bootstrap the perl build
240# process, when miniperl is running and no XS loading happens.
241sub _perl_getcwd
242{
243    abs_path('.');
244}
245
246# By John Bazik
247#
248# Usage: $cwd = &fastcwd;
249#
250# This is a faster version of getcwd.  It's also more dangerous because
251# you might chdir out of a directory that you can't chdir back into.
252
253sub fastcwd_ {
254    my($odev, $oino, $cdev, $cino, $tdev, $tino);
255    my(@path, $path);
256    local(*DIR);
257
258    my($orig_cdev, $orig_cino) = stat('.');
259    ($cdev, $cino) = ($orig_cdev, $orig_cino);
260    for (;;) {
261	my $direntry;
262	($odev, $oino) = ($cdev, $cino);
263	CORE::chdir('..') || return undef;
264	($cdev, $cino) = stat('.');
265	last if $odev == $cdev && $oino eq $cino;
266	opendir(DIR, '.') || return undef;
267	for (;;) {
268	    $direntry = readdir(DIR);
269	    last unless defined $direntry;
270	    next if $direntry eq '.';
271	    next if $direntry eq '..';
272
273	    ($tdev, $tino) = lstat($direntry);
274	    last unless $tdev != $odev || $tino ne $oino;
275	}
276	closedir(DIR);
277	return undef unless defined $direntry; # should never happen
278	unshift(@path, $direntry);
279    }
280    $path = '/' . join('/', @path);
281    if ($^O eq 'apollo') { $path = "/".$path; }
282    # At this point $path may be tainted (if tainting) and chdir would fail.
283    # Untaint it then check that we landed where we started.
284    $path =~ /^(.*)\z/s		# untaint
285	&& CORE::chdir($1) or return undef;
286    ($cdev, $cino) = stat('.');
287    die "Unstable directory path, current directory changed unexpectedly"
288	if $cdev != $orig_cdev || $cino ne $orig_cino;
289    $path;
290}
291if (not defined &fastcwd) { *fastcwd = \&fastcwd_ }
292
293
294# Keeps track of current working directory in PWD environment var
295# Usage:
296#	use Cwd 'chdir';
297#	chdir $newdir;
298
299my $chdir_init = 0;
300
301sub chdir_init {
302    if ($ENV{'PWD'} and $^O ne 'os2' and $^O ne 'dos' and $^O ne 'MSWin32') {
303	my($dd,$di) = stat('.');
304	my($pd,$pi) = stat($ENV{'PWD'});
305	if (!defined $dd or !defined $pd or $di ne $pi or $dd != $pd) {
306	    $ENV{'PWD'} = cwd();
307	}
308    }
309    else {
310	my $wd = cwd();
311	$wd = Win32::GetFullPathName($wd) if $^O eq 'MSWin32';
312	$ENV{'PWD'} = $wd;
313    }
314    # Strip an automounter prefix (where /tmp_mnt/foo/bar == /foo/bar)
315    if ($^O ne 'MSWin32' and $ENV{'PWD'} =~ m|(/[^/]+(/[^/]+/[^/]+))(.*)|s) {
316	my($pd,$pi) = stat($2);
317	my($dd,$di) = stat($1);
318	if (defined $pd and defined $dd and $di ne $pi and $dd == $pd) {
319	    $ENV{'PWD'}="$2$3";
320	}
321    }
322    $chdir_init = 1;
323}
324
325sub chdir {
326    my $newdir = @_ ? shift : '';	# allow for no arg (chdir to HOME dir)
327    if ($^O eq "cygwin") {
328      $newdir =~ s|\A///+|//|;
329      $newdir =~ s|(?<=[^/])//+|/|g;
330    }
331    elsif ($^O ne 'MSWin32') {
332      $newdir =~ s|///*|/|g;
333    }
334    chdir_init() unless $chdir_init;
335    my $newpwd;
336    if ($^O eq 'MSWin32') {
337	# get the full path name *before* the chdir()
338	$newpwd = Win32::GetFullPathName($newdir);
339    }
340
341    return 0 unless CORE::chdir $newdir;
342
343    if ($^O eq 'VMS') {
344	return $ENV{'PWD'} = $ENV{'DEFAULT'}
345    }
346    elsif ($^O eq 'MSWin32') {
347	$ENV{'PWD'} = $newpwd;
348	return 1;
349    }
350
351    if (ref $newdir eq 'GLOB') { # in case a file/dir handle is passed in
352	$ENV{'PWD'} = cwd();
353    } elsif ($newdir =~ m#^/#s) {
354	$ENV{'PWD'} = $newdir;
355    } else {
356	my @curdir = split(m#/#,$ENV{'PWD'});
357	@curdir = ('') unless @curdir;
358	my $component;
359	foreach $component (split(m#/#, $newdir)) {
360	    next if $component eq '.';
361	    pop(@curdir),next if $component eq '..';
362	    push(@curdir,$component);
363	}
364	$ENV{'PWD'} = join('/',@curdir) || '/';
365    }
366    1;
367}
368
369
370sub _perl_abs_path
371{
372    my $start = @_ ? shift : '.';
373    my($dotdots, $cwd, @pst, @cst, $dir, @tst);
374
375    unless (@cst = stat( $start ))
376    {
377	return undef;
378    }
379
380    unless (-d _) {
381        # Make sure we can be invoked on plain files, not just directories.
382        # NOTE that this routine assumes that '/' is the only directory separator.
383
384        my ($dir, $file) = $start =~ m{^(.*)/(.+)$}
385	    or return cwd() . '/' . $start;
386
387	# Can't use "-l _" here, because the previous stat was a stat(), not an lstat().
388	if (-l $start) {
389	    my $link_target = readlink($start);
390	    die "Can't resolve link $start: $!" unless defined $link_target;
391
392	    require File::Spec;
393            $link_target = $dir . '/' . $link_target
394                unless File::Spec->file_name_is_absolute($link_target);
395
396	    return abs_path($link_target);
397	}
398
399	return $dir ? abs_path($dir) . "/$file" : "/$file";
400    }
401
402    $cwd = '';
403    $dotdots = $start;
404    do
405    {
406	$dotdots .= '/..';
407	@pst = @cst;
408	local *PARENT;
409	unless (opendir(PARENT, $dotdots))
410	{
411	    return undef;
412	}
413	unless (@cst = stat($dotdots))
414	{
415	    my $e = $!;
416	    closedir(PARENT);
417	    $! = $e;
418	    return undef;
419	}
420	if ($pst[0] == $cst[0] && $pst[1] eq $cst[1])
421	{
422	    $dir = undef;
423	}
424	else
425	{
426	    do
427	    {
428		unless (defined ($dir = readdir(PARENT)))
429	        {
430		    closedir(PARENT);
431		    require Errno;
432		    $! = Errno::ENOENT();
433		    return undef;
434		}
435		$tst[0] = $pst[0]+1 unless (@tst = lstat("$dotdots/$dir"))
436	    }
437	    while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] ||
438		   $tst[1] ne $pst[1]);
439	}
440	$cwd = (defined $dir ? "$dir" : "" ) . "/$cwd" ;
441	closedir(PARENT);
442    } while (defined $dir);
443    chop($cwd) unless $cwd eq '/'; # drop the trailing /
444    $cwd;
445}
446
447
448my $Curdir;
449sub fast_abs_path {
450    local $ENV{PWD} = $ENV{PWD} || ''; # Guard against clobberage
451    my $cwd = getcwd();
452    defined $cwd or return undef;
453    require File::Spec;
454    my $path = @_ ? shift : ($Curdir ||= File::Spec->curdir);
455
456    # Detaint else we'll explode in taint mode.  This is safe because
457    # we're not doing anything dangerous with it.
458    ($path) = $path =~ /(.*)/s;
459    ($cwd)  = $cwd  =~ /(.*)/s;
460
461    unless (-e $path) {
462	require Errno;
463	$! = Errno::ENOENT();
464	return undef;
465    }
466
467    unless (-d _) {
468        # Make sure we can be invoked on plain files, not just directories.
469
470	my ($vol, $dir, $file) = File::Spec->splitpath($path);
471	return File::Spec->catfile($cwd, $path) unless length $dir;
472
473	if (-l $path) {
474	    my $link_target = readlink($path);
475	    defined $link_target or return undef;
476
477	    $link_target = File::Spec->catpath($vol, $dir, $link_target)
478                unless File::Spec->file_name_is_absolute($link_target);
479
480	    return fast_abs_path($link_target);
481	}
482
483	return $dir eq File::Spec->rootdir
484	  ? File::Spec->catpath($vol, $dir, $file)
485	  : fast_abs_path(File::Spec->catpath($vol, $dir, '')) . '/' . $file;
486    }
487
488    if (!CORE::chdir($path)) {
489	return undef;
490    }
491    my $realpath = getcwd();
492    if (! ((-d $cwd) && (CORE::chdir($cwd)))) {
493 	_croak("Cannot chdir back to $cwd: $!");
494    }
495    $realpath;
496}
497
498# added function alias to follow principle of least surprise
499# based on previous aliasing.  --tchrist 27-Jan-00
500*fast_realpath = \&fast_abs_path;
501
502
503# --- PORTING SECTION ---
504
505# VMS: $ENV{'DEFAULT'} points to default directory at all times
506# 06-Mar-1996  Charles Bailey  bailey@newman.upenn.edu
507# Note: Use of Cwd::chdir() causes the logical name PWD to be defined
508#   in the process logical name table as the default device and directory
509#   seen by Perl. This may not be the same as the default device
510#   and directory seen by DCL after Perl exits, since the effects
511#   the CRTL chdir() function persist only until Perl exits.
512
513sub _vms_cwd {
514    return $ENV{'DEFAULT'};
515}
516
517sub _vms_abs_path {
518    return $ENV{'DEFAULT'} unless @_;
519    my $path = shift;
520
521    my $efs = _vms_efs;
522    my $unix_rpt = _vms_unix_rpt;
523
524    if (defined &VMS::Filespec::vmsrealpath) {
525        my $path_unix = 0;
526        my $path_vms = 0;
527
528        $path_unix = 1 if ($path =~ m#(?<=\^)/#);
529        $path_unix = 1 if ($path =~ /^\.\.?$/);
530        $path_vms = 1 if ($path =~ m#[\[<\]]#);
531        $path_vms = 1 if ($path =~ /^--?$/);
532
533        my $unix_mode = $path_unix;
534        if ($efs) {
535            # In case of a tie, the Unix report mode decides.
536            if ($path_vms == $path_unix) {
537                $unix_mode = $unix_rpt;
538            } else {
539                $unix_mode = 0 if $path_vms;
540            }
541        }
542
543        if ($unix_mode) {
544            # Unix format
545            return VMS::Filespec::unixrealpath($path);
546        }
547
548	# VMS format
549
550	my $new_path = VMS::Filespec::vmsrealpath($path);
551
552	# Perl expects directories to be in directory format
553	$new_path = VMS::Filespec::pathify($new_path) if -d $path;
554	return $new_path;
555    }
556
557    # Fallback to older algorithm if correct ones are not
558    # available.
559
560    if (-l $path) {
561        my $link_target = readlink($path);
562        die "Can't resolve link $path: $!" unless defined $link_target;
563
564        return _vms_abs_path($link_target);
565    }
566
567    # may need to turn foo.dir into [.foo]
568    my $pathified = VMS::Filespec::pathify($path);
569    $path = $pathified if defined $pathified;
570
571    return VMS::Filespec::rmsexpand($path);
572}
573
574sub _os2_cwd {
575    my $pwd = `cmd /c cd`;
576    chomp $pwd;
577    $pwd =~ s:\\:/:g ;
578    $ENV{'PWD'} = $pwd;
579    return $pwd;
580}
581
582sub _win32_cwd_simple {
583    my $pwd = `cd`;
584    chomp $pwd;
585    $pwd =~ s:\\:/:g ;
586    $ENV{'PWD'} = $pwd;
587    return $pwd;
588}
589
590sub _win32_cwd {
591    my $pwd;
592    $pwd = Win32::GetCwd();
593    $pwd =~ s:\\:/:g ;
594    $ENV{'PWD'} = $pwd;
595    return $pwd;
596}
597
598*_NT_cwd = defined &Win32::GetCwd ? \&_win32_cwd : \&_win32_cwd_simple;
599
600sub _dos_cwd {
601    my $pwd;
602    if (!defined &Dos::GetCwd) {
603        chomp($pwd = `command /c cd`);
604        $pwd =~ s:\\:/:g ;
605    } else {
606        $pwd = Dos::GetCwd();
607    }
608    $ENV{'PWD'} = $pwd;
609    return $pwd;
610}
611
612sub _qnx_cwd {
613	local $ENV{PATH} = '';
614	local $ENV{CDPATH} = '';
615	local $ENV{ENV} = '';
616    my $pwd = `/usr/bin/fullpath -t`;
617    chomp $pwd;
618    $ENV{'PWD'} = $pwd;
619    return $pwd;
620}
621
622sub _qnx_abs_path {
623	local $ENV{PATH} = '';
624	local $ENV{CDPATH} = '';
625	local $ENV{ENV} = '';
626    my $path = @_ ? shift : '.';
627    local *REALPATH;
628
629    defined( open(REALPATH, '-|') || exec '/usr/bin/fullpath', '-t', $path ) or
630      die "Can't open /usr/bin/fullpath: $!";
631    my $realpath = <REALPATH>;
632    close REALPATH;
633    chomp $realpath;
634    return $realpath;
635}
636
637# Now that all the base-level functions are set up, alias the
638# user-level functions to the right places
639
640if (exists $METHOD_MAP{$^O}) {
641  my $map = $METHOD_MAP{$^O};
642  foreach my $name (keys %$map) {
643    local $^W = 0;  # assignments trigger 'subroutine redefined' warning
644    no strict 'refs';
645    *{$name} = \&{$map->{$name}};
646  }
647}
648
649# built-in from 5.30
650*getcwd = \&Internals::getcwd
651  if !defined &getcwd && defined &Internals::getcwd;
652
653# In case the XS version doesn't load.
654*abs_path = \&_perl_abs_path unless defined &abs_path;
655*getcwd = \&_perl_getcwd unless defined &getcwd;
656
657# added function alias for those of us more
658# used to the libc function.  --tchrist 27-Jan-00
659*realpath = \&abs_path;
660
6611;
662__END__
663
664=head1 NAME
665
666Cwd - get pathname of current working directory
667
668=head1 SYNOPSIS
669
670    use Cwd;
671    my $dir = getcwd;
672
673    use Cwd 'abs_path';
674    my $abs_path = abs_path($file);
675
676=head1 DESCRIPTION
677
678This module provides functions for determining the pathname of the
679current working directory.  It is recommended that getcwd (or another
680*cwd() function) be used in I<all> code to ensure portability.
681
682By default, it exports the functions cwd(), getcwd(), fastcwd(), and
683fastgetcwd() (and, on Win32, getdcwd()) into the caller's namespace.
684
685
686=head2 getcwd and friends
687
688Each of these functions are called without arguments and return the
689absolute path of the current working directory.
690
691=over 4
692
693=item getcwd
694
695    my $cwd = getcwd();
696
697Returns the current working directory.  On error returns C<undef>,
698with C<$!> set to indicate the error.
699
700Exposes the POSIX function getcwd(3) or re-implements it if it's not
701available.
702
703=item cwd
704
705    my $cwd = cwd();
706
707The cwd() is the most natural form for the current architecture.  For
708most systems it is identical to `pwd` (but without the trailing line
709terminator).
710
711=item fastcwd
712
713    my $cwd = fastcwd();
714
715A more dangerous version of getcwd(), but potentially faster.
716
717It might conceivably chdir() you out of a directory that it can't
718chdir() you back into.  If fastcwd encounters a problem it will return
719undef but will probably leave you in a different directory.  For a
720measure of extra security, if everything appears to have worked, the
721fastcwd() function will check that it leaves you in the same directory
722that it started in.  If it has changed it will C<die> with the message
723"Unstable directory path, current directory changed
724unexpectedly".  That should never happen.
725
726=item fastgetcwd
727
728  my $cwd = fastgetcwd();
729
730The fastgetcwd() function is provided as a synonym for cwd().
731
732=item getdcwd
733
734    my $cwd = getdcwd();
735    my $cwd = getdcwd('C:');
736
737The getdcwd() function is also provided on Win32 to get the current working
738directory on the specified drive, since Windows maintains a separate current
739working directory for each drive.  If no drive is specified then the current
740drive is assumed.
741
742This function simply calls the Microsoft C library _getdcwd() function.
743
744=back
745
746
747=head2 abs_path and friends
748
749These functions are exported only on request.  They each take a single
750argument and return the absolute pathname for it.  If no argument is
751given they'll use the current working directory.
752
753=over 4
754
755=item abs_path
756
757  my $abs_path = abs_path($file);
758
759Uses the same algorithm as getcwd().  Symbolic links and relative-path
760components ("." and "..") are resolved to return the canonical
761pathname, just like realpath(3).  On error returns C<undef>, with C<$!>
762set to indicate the error.
763
764=item realpath
765
766  my $abs_path = realpath($file);
767
768A synonym for abs_path().
769
770=item fast_abs_path
771
772  my $abs_path = fast_abs_path($file);
773
774A more dangerous, but potentially faster version of abs_path.
775
776=back
777
778=head2 $ENV{PWD}
779
780If you ask to override your chdir() built-in function,
781
782  use Cwd qw(chdir);
783
784then your PWD environment variable will be kept up to date.  Note that
785it will only be kept up to date if all packages which use chdir import
786it from Cwd.
787
788
789=head1 NOTES
790
791=over 4
792
793=item *
794
795Since the path separators are different on some operating systems ('/'
796on Unix, ':' on MacPerl, etc...) we recommend you use the File::Spec
797modules wherever portability is a concern.
798
799=item *
800
801Actually, on Mac OS, the C<getcwd()>, C<fastgetcwd()> and C<fastcwd()>
802functions are all aliases for the C<cwd()> function, which, on Mac OS,
803calls `pwd`.  Likewise, the C<abs_path()> function is an alias for
804C<fast_abs_path()>.
805
806=back
807
808=head1 AUTHOR
809
810Maintained by perl5-porters <F<perl5-porters@perl.org>>.
811
812=head1 COPYRIGHT
813
814Copyright (c) 2004 by the Perl 5 Porters.  All rights reserved.
815
816This program is free software; you can redistribute it and/or modify
817it under the same terms as Perl itself.
818
819Portions of the C code in this library are copyright (c) 1994 by the
820Regents of the University of California.  All rights reserved.  The
821license on this code is compatible with the licensing of the rest of
822the distribution - please see the source code in F<Cwd.xs> for the
823details.
824
825=head1 SEE ALSO
826
827L<File::chdir>
828
829=cut
830