This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
File-Path: sync in CPAN version 2.17
[perl5.git] / cpan / File-Path / lib / File / Path.pm
CommitLineData
1fc4cb55 1package File::Path;
fed7345c 2
cac619e8
DL
3use 5.005_04;
4use strict;
5
6use Cwd 'getcwd';
7use File::Basename ();
8use File::Spec ();
9
10BEGIN {
139271cd
CBW
11 if ( $] < 5.006 ) {
12
cac619e8
DL
13 # can't say 'opendir my $dh, $dirname'
14 # need to initialise $dh
139271cd 15 eval 'use Symbol';
cac619e8
DL
16 }
17}
18
19use Exporter ();
3f083399 20use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
f4b02d78 21$VERSION = '2.17';
139271cd 22$VERSION = eval $VERSION;
30cf951a
NC
23@ISA = qw(Exporter);
24@EXPORT = qw(mkpath rmtree);
3f083399 25@EXPORT_OK = qw(make_path remove_tree);
cac619e8 26
139271cd
CBW
27BEGIN {
28 for (qw(VMS MacOS MSWin32 os2)) {
29 no strict 'refs';
30 *{"_IS_\U$_"} = $^O eq $_ ? sub () { 1 } : sub () { 0 };
31 }
cac619e8 32
139271cd
CBW
33 # These OSes complain if you want to remove a file that you have no
34 # write permission to:
35 *_FORCE_WRITABLE = (
36 grep { $^O eq $_ } qw(amigaos dos epoc MSWin32 MacOS os2)
37 ) ? sub () { 1 } : sub () { 0 };
cac619e8 38
139271cd
CBW
39 # Unix-like systems need to stat each directory in order to detect
40 # race condition. MS-Windows is immune to this particular attack.
41 *_NEED_STAT_CHECK = !(_IS_MSWIN32()) ? sub () { 1 } : sub () { 0 };
42}
839bc55a 43
cac619e8
DL
44sub _carp {
45 require Carp;
46 goto &Carp::carp;
47}
48
49sub _croak {
50 require Carp;
51 goto &Carp::croak;
52}
53
54sub _error {
55 my $arg = shift;
56 my $message = shift;
57 my $object = shift;
58
139271cd 59 if ( $arg->{error} ) {
cac619e8 60 $object = '' unless defined $object;
3f083399 61 $message .= ": $!" if $!;
139271cd 62 push @{ ${ $arg->{error} } }, { $object => $message };
cac619e8
DL
63 }
64 else {
139271cd 65 _carp( defined($object) ? "$message for $object: $!" : "$message: $!" );
cac619e8
DL
66 }
67}
68
139271cd
CBW
69sub __is_arg {
70 my ($arg) = @_;
71
72 # If client code blessed an array ref to HASH, this will not work
73 # properly. We could have done $arg->isa() wrapped in eval, but
74 # that would be expensive. This implementation should suffice.
75 # We could have also used Scalar::Util:blessed, but we choose not
76 # to add this dependency
77 return ( ref $arg eq 'HASH' );
78}
79
3f083399 80sub make_path {
139271cd 81 push @_, {} unless @_ and __is_arg( $_[-1] );
3f083399
NC
82 goto &mkpath;
83}
84
cac619e8 85sub mkpath {
139271cd 86 my $old_style = !( @_ and __is_arg( $_[-1] ) );
cac619e8 87
cc744934 88 my $data;
cac619e8
DL
89 my $paths;
90
91 if ($old_style) {
139271cd
CBW
92 my ( $verbose, $mode );
93 ( $paths, $verbose, $mode ) = @_;
94 $paths = [$paths] unless UNIVERSAL::isa( $paths, 'ARRAY' );
cc744934
CBW
95 $data->{verbose} = $verbose;
96 $data->{mode} = defined $mode ? $mode : oct '777';
cac619e8
DL
97 }
98 else {
139271cd
CBW
99 my %args_permitted = map { $_ => 1 } ( qw|
100 chmod
101 error
102 group
103 mask
104 mode
105 owner
106 uid
107 user
108 verbose
109 | );
cc744934
CBW
110 my %not_on_win32_args = map { $_ => 1 } ( qw|
111 group
112 owner
113 uid
114 user
115 | );
139271cd 116 my @bad_args = ();
cc744934
CBW
117 my @win32_implausible_args = ();
118 my $arg = pop @_;
139271cd 119 for my $k (sort keys %{$arg}) {
cc744934
CBW
120 if (! $args_permitted{$k}) {
121 push @bad_args, $k;
122 }
123 elsif ($not_on_win32_args{$k} and _IS_MSWIN32) {
124 push @win32_implausible_args, $k;
30eb83e1
RGS
125 }
126 else {
cc744934 127 $data->{$k} = $arg->{$k};
30eb83e1
RGS
128 }
129 }
cc744934
CBW
130 _carp("Unrecognized option(s) passed to mkpath() or make_path(): @bad_args")
131 if @bad_args;
132 _carp("Option(s) implausible on Win32 passed to mkpath() or make_path(): @win32_implausible_args")
133 if @win32_implausible_args;
134 $data->{mode} = delete $data->{mask} if exists $data->{mask};
135 $data->{mode} = oct '777' unless exists $data->{mode};
136 ${ $data->{error} } = [] if exists $data->{error};
137 unless (@win32_implausible_args) {
138 $data->{owner} = delete $data->{user} if exists $data->{user};
139 $data->{owner} = delete $data->{uid} if exists $data->{uid};
140 if ( exists $data->{owner} and $data->{owner} =~ /\D/ ) {
141 my $uid = ( getpwnam $data->{owner} )[2];
142 if ( defined $uid ) {
143 $data->{owner} = $uid;
144 }
145 else {
146 _error( $data,
147 "unable to map $data->{owner} to a uid, ownership not changed"
148 );
149 delete $data->{owner};
150 }
30eb83e1 151 }
cc744934
CBW
152 if ( exists $data->{group} and $data->{group} =~ /\D/ ) {
153 my $gid = ( getgrnam $data->{group} )[2];
154 if ( defined $gid ) {
155 $data->{group} = $gid;
156 }
157 else {
158 _error( $data,
159 "unable to map $data->{group} to a gid, group ownership not changed"
160 );
161 delete $data->{group};
162 }
163 }
164 if ( exists $data->{owner} and not exists $data->{group} ) {
165 $data->{group} = -1; # chown will leave group unchanged
166 }
167 if ( exists $data->{group} and not exists $data->{owner} ) {
168 $data->{owner} = -1; # chown will leave owner unchanged
30eb83e1 169 }
30eb83e1 170 }
cac619e8
DL
171 $paths = [@_];
172 }
cc744934 173 return _mkpath( $data, $paths );
cac619e8
DL
174}
175
176sub _mkpath {
cc744934 177 my $data = shift;
cac619e8
DL
178 my $paths = shift;
179
139271cd
CBW
180 my ( @created );
181 foreach my $path ( @{$paths} ) {
3f083399 182 next unless defined($path) and length($path);
139271cd
CBW
183 $path .= '/' if _IS_OS2 and $path =~ /^\w:\z/s; # feature of CRT
184
cac619e8 185 # Logic wants Unix paths, so go with the flow.
139271cd 186 if (_IS_VMS) {
cac619e8
DL
187 next if $path eq '/';
188 $path = VMS::Filespec::unixify($path);
189 }
190 next if -d $path;
191 my $parent = File::Basename::dirname($path);
cc744934
CBW
192 # Coverage note: It's not clear how we would test the condition:
193 # '-d $parent or $path eq $parent'
139271cd 194 unless ( -d $parent or $path eq $parent ) {
cc744934 195 push( @created, _mkpath( $data, [$parent] ) );
cac619e8 196 }
cc744934
CBW
197 print "mkdir $path\n" if $data->{verbose};
198 if ( mkdir( $path, $data->{mode} ) ) {
139271cd 199 push( @created, $path );
cc744934 200 if ( exists $data->{owner} ) {
139271cd 201
cc744934
CBW
202 # NB: $data->{group} guaranteed to be set during initialisation
203 if ( !chown $data->{owner}, $data->{group}, $path ) {
204 _error( $data,
205 "Cannot change ownership of $path to $data->{owner}:$data->{group}"
139271cd
CBW
206 );
207 }
208 }
cc744934
CBW
209 if ( exists $data->{chmod} ) {
210 # Coverage note: It's not clear how we would trigger the next
211 # 'if' block. Failure of 'chmod' might first result in a
212 # system error: "Permission denied".
213 if ( !chmod $data->{chmod}, $path ) {
214 _error( $data,
215 "Cannot change permissions of $path to $data->{chmod}" );
30eb83e1
RGS
216 }
217 }
cac619e8
DL
218 }
219 else {
220 my $save_bang = $!;
cc744934
CBW
221
222 # From 'perldoc perlvar': $EXTENDED_OS_ERROR ($^E) is documented
223 # as:
224 # Error information specific to the current operating system. At the
225 # moment, this differs from "$!" under only VMS, OS/2, and Win32
226 # (and for MacPerl). On all other platforms, $^E is always just the
227 # same as $!.
228
139271cd 229 my ( $e, $e1 ) = ( $save_bang, $^E );
cac619e8 230 $e .= "; $e1" if $e ne $e1;
139271cd 231
cac619e8 232 # allow for another process to have created it meanwhile
139271cd 233 if ( ! -d $path ) {
cac619e8 234 $! = $save_bang;
cc744934
CBW
235 if ( $data->{error} ) {
236 push @{ ${ $data->{error} } }, { $path => $e };
cac619e8
DL
237 }
238 else {
239 _croak("mkdir $path: $e");
240 }
241 }
242 }
243 }
244 return @created;
245}
246
3f083399 247sub remove_tree {
139271cd 248 push @_, {} unless @_ and __is_arg( $_[-1] );
3f083399
NC
249 goto &rmtree;
250}
251
0e5b5e32 252sub _is_subdir {
139271cd 253 my ( $dir, $test ) = @_;
0e5b5e32 254
139271cd
CBW
255 my ( $dv, $dd ) = File::Spec->splitpath( $dir, 1 );
256 my ( $tv, $td ) = File::Spec->splitpath( $test, 1 );
0e5b5e32
MHM
257
258 # not on same volume
259 return 0 if $dv ne $tv;
260
261 my @d = File::Spec->splitdir($dd);
262 my @t = File::Spec->splitdir($td);
263
264 # @t can't be a subdir if it's shorter than @d
265 return 0 if @t < @d;
266
139271cd 267 return join( '/', @d ) eq join( '/', splice @t, 0, +@d );
0e5b5e32
MHM
268}
269
cac619e8 270sub rmtree {
139271cd 271 my $old_style = !( @_ and __is_arg( $_[-1] ) );
cac619e8 272
cc744934 273 my ($arg, $data, $paths);
cac619e8
DL
274
275 if ($old_style) {
139271cd
CBW
276 my ( $verbose, $safe );
277 ( $paths, $verbose, $safe ) = @_;
cc744934
CBW
278 $data->{verbose} = $verbose;
279 $data->{safe} = defined $safe ? $safe : 0;
cac619e8 280
139271cd
CBW
281 if ( defined($paths) and length($paths) ) {
282 $paths = [$paths] unless UNIVERSAL::isa( $paths, 'ARRAY' );
cac619e8
DL
283 }
284 else {
139271cd 285 _carp("No root path(s) specified\n");
cac619e8
DL
286 return 0;
287 }
288 }
289 else {
139271cd
CBW
290 my %args_permitted = map { $_ => 1 } ( qw|
291 error
292 keep_root
293 result
294 safe
295 verbose
296 | );
297 my @bad_args = ();
cc744934 298 my $arg = pop @_;
139271cd 299 for my $k (sort keys %{$arg}) {
cc744934
CBW
300 if (! $args_permitted{$k}) {
301 push @bad_args, $k;
302 }
303 else {
304 $data->{$k} = $arg->{$k};
305 }
139271cd
CBW
306 }
307 _carp("Unrecognized option(s) passed to remove_tree(): @bad_args")
308 if @bad_args;
cc744934
CBW
309 ${ $data->{error} } = [] if exists $data->{error};
310 ${ $data->{result} } = [] if exists $data->{result};
311
312 # Wouldn't it make sense to do some validation on @_ before assigning
313 # to $paths here?
314 # In the $old_style case we guarantee that each path is both defined
315 # and non-empty. We don't check that here, which means we have to
316 # check it later in the first condition in this line:
317 # if ( $ortho_root_length && _is_subdir( $ortho_root, $ortho_cwd ) ) {
318 # Granted, that would be a change in behavior for the two
319 # non-old-style interfaces.
320
cac619e8
DL
321 $paths = [@_];
322 }
323
cc744934
CBW
324 $data->{prefix} = '';
325 $data->{depth} = 0;
cac619e8 326
3f083399 327 my @clean_path;
cc744934
CBW
328 $data->{cwd} = getcwd() or do {
329 _error( $data, "cannot fetch initial working directory" );
cac619e8
DL
330 return 0;
331 };
cc744934 332 for ( $data->{cwd} ) { /\A(.*)\Z/s; $_ = $1 } # untaint
cac619e8 333
3f083399 334 for my $p (@$paths) {
139271cd 335
c42ebacb 336 # need to fixup case and map \ to / on Windows
139271cd
CBW
337 my $ortho_root = _IS_MSWIN32 ? _slash_lc($p) : $p;
338 my $ortho_cwd =
cc744934 339 _IS_MSWIN32 ? _slash_lc( $data->{cwd} ) : $data->{cwd};
c42ebacb 340 my $ortho_root_length = length($ortho_root);
139271cd
CBW
341 $ortho_root_length-- if _IS_VMS; # don't compare '.' with ']'
342 if ( $ortho_root_length && _is_subdir( $ortho_root, $ortho_cwd ) ) {
c42ebacb 343 local $! = 0;
cc744934 344 _error( $data, "cannot remove path when cwd is $data->{cwd}", $p );
c42ebacb
CB
345 next;
346 }
347
139271cd
CBW
348 if (_IS_MACOS) {
349 $p = ":$p" unless $p =~ /:/;
350 $p .= ":" unless $p =~ /:\z/;
3f083399 351 }
139271cd 352 elsif ( _IS_MSWIN32 ) {
3f083399
NC
353 $p =~ s{[/\\]\z}{};
354 }
355 else {
356 $p =~ s{/\z}{};
357 }
358 push @clean_path, $p;
359 }
360
cc744934
CBW
361 @{$data}{qw(device inode)} = ( lstat $data->{cwd} )[ 0, 1 ] or do {
362 _error( $data, "cannot stat initial working directory", $data->{cwd} );
cac619e8
DL
363 return 0;
364 };
365
cc744934 366 return _rmtree( $data, \@clean_path );
cac619e8
DL
367}
368
369sub _rmtree {
cc744934 370 my $data = shift;
cac619e8
DL
371 my $paths = shift;
372
373 my $count = 0;
374 my $curdir = File::Spec->curdir();
375 my $updir = File::Spec->updir();
376
139271cd
CBW
377 my ( @files, $root );
378 ROOT_DIR:
379 foreach my $root (@$paths) {
380
cac619e8
DL
381 # since we chdir into each directory, it may not be obvious
382 # to figure out where we are if we generate a message about
383 # a file name. We therefore construct a semi-canonical
384 # filename, anchored from the directory being unlinked (as
385 # opposed to being truly canonical, anchored from the root (/).
386
139271cd 387 my $canon =
cc744934
CBW
388 $data->{prefix}
389 ? File::Spec->catfile( $data->{prefix}, $root )
139271cd 390 : $root;
cac619e8 391
139271cd 392 my ( $ldev, $lino, $perm ) = ( lstat $root )[ 0, 1, 2 ]
bfcc9519 393 or next ROOT_DIR;
cac619e8
DL
394
395 if ( -d _ ) {
139271cd
CBW
396 $root = VMS::Filespec::vmspath( VMS::Filespec::pathify($root) )
397 if _IS_VMS;
398
399 if ( !chdir($root) ) {
839bc55a 400
cac619e8
DL
401 # see if we can escalate privileges to get in
402 # (e.g. funny protection mask such as -w- instead of rwx)
cc744934
CBW
403 # This uses fchmod to avoid traversing outside of the proper
404 # location (CVE-2017-6512)
405 my $root_fh;
406 if (open($root_fh, '<', $root)) {
407 my ($fh_dev, $fh_inode) = (stat $root_fh )[0,1];
408 $perm &= oct '7777';
409 my $nperm = $perm | oct '700';
410 local $@;
411 if (
412 !(
413 $data->{safe}
414 or $nperm == $perm
415 or !-d _
416 or $fh_dev ne $ldev
417 or $fh_inode ne $lino
418 or eval { chmod( $nperm, $root_fh ) }
419 )
420 )
421 {
422 _error( $data,
423 "cannot make child directory read-write-exec", $canon );
424 next ROOT_DIR;
425 }
426 close $root_fh;
cac619e8 427 }
cc744934
CBW
428 if ( !chdir($root) ) {
429 _error( $data, "cannot chdir to child", $canon );
cac619e8
DL
430 next ROOT_DIR;
431 }
432 }
433
139271cd
CBW
434 my ( $cur_dev, $cur_inode, $perm ) = ( stat $curdir )[ 0, 1, 2 ]
435 or do {
cc744934 436 _error( $data, "cannot stat current working directory", $canon );
cac619e8 437 next ROOT_DIR;
139271cd 438 };
cac619e8 439
139271cd
CBW
440 if (_NEED_STAT_CHECK) {
441 ( $ldev eq $cur_dev and $lino eq $cur_inode )
442 or _croak(
443"directory $canon changed before chdir, expected dev=$ldev ino=$lino, actual dev=$cur_dev ino=$cur_inode, aborting."
444 );
839bc55a 445 }
cac619e8 446
139271cd
CBW
447 $perm &= oct '7777'; # don't forget setuid, setgid, sticky bits
448 my $nperm = $perm | oct '700';
cac619e8
DL
449
450 # notabene: 0700 is for making readable in the first place,
451 # it's also intended to change it to writable in case we have
139271cd 452 # to recurse in which case we are better than rm -rf for
cac619e8
DL
453 # subtrees with strange permissions
454
139271cd
CBW
455 if (
456 !(
cc744934 457 $data->{safe}
139271cd
CBW
458 or $nperm == $perm
459 or chmod( $nperm, $curdir )
460 )
461 )
462 {
cc744934 463 _error( $data, "cannot make directory read+writeable", $canon );
cac619e8
DL
464 $nperm = $perm;
465 }
466
467 my $d;
468 $d = gensym() if $] < 5.006;
139271cd 469 if ( !opendir $d, $curdir ) {
cc744934 470 _error( $data, "cannot opendir", $canon );
cac619e8
DL
471 @files = ();
472 }
473 else {
139271cd
CBW
474 if ( !defined ${^TAINT} or ${^TAINT} ) {
475 # Blindly untaint dir names if taint mode is active
cac619e8
DL
476 @files = map { /\A(.*)\z/s; $1 } readdir $d;
477 }
478 else {
479 @files = readdir $d;
480 }
481 closedir $d;
482 }
483
139271cd
CBW
484 if (_IS_VMS) {
485
cac619e8
DL
486 # Deleting large numbers of files from VMS Files-11
487 # filesystems is faster if done in reverse ASCIIbetical order.
488 # include '.' to '.;' from blead patch #31775
139271cd 489 @files = map { $_ eq '.' ? '.;' : $_ } reverse @files;
cac619e8 490 }
839bc55a 491
139271cd 492 @files = grep { $_ ne $updir and $_ ne $curdir } @files;
cac619e8
DL
493
494 if (@files) {
139271cd 495
cac619e8 496 # remove the contained files before the directory itself
cc744934 497 my $narg = {%$data};
139271cd 498 @{$narg}{qw(device inode cwd prefix depth)} =
cc744934 499 ( $cur_dev, $cur_inode, $updir, $canon, $data->{depth} + 1 );
139271cd 500 $count += _rmtree( $narg, \@files );
cac619e8
DL
501 }
502
503 # restore directory permissions of required now (in case the rmdir
504 # below fails), while we are still in the directory and may do so
505 # without a race via '.'
139271cd 506 if ( $nperm != $perm and not chmod( $perm, $curdir ) ) {
cc744934 507 _error( $data, "cannot reset chmod", $canon );
cac619e8
DL
508 }
509
510 # don't leave the client code in an unexpected directory
cc744934 511 chdir( $data->{cwd} )
139271cd 512 or
cc744934 513 _croak("cannot chdir to $data->{cwd} from $canon: $!, aborting.");
cac619e8
DL
514
515 # ensure that a chdir upwards didn't take us somewhere other
516 # than we expected (see CVE-2002-0435)
139271cd
CBW
517 ( $cur_dev, $cur_inode ) = ( stat $curdir )[ 0, 1 ]
518 or _croak(
cc744934 519 "cannot stat prior working directory $data->{cwd}: $!, aborting."
139271cd
CBW
520 );
521
522 if (_NEED_STAT_CHECK) {
cc744934
CBW
523 ( $data->{device} eq $cur_dev and $data->{inode} eq $cur_inode )
524 or _croak( "previous directory $data->{cwd} "
139271cd
CBW
525 . "changed before entering $canon, "
526 . "expected dev=$ldev ino=$lino, "
527 . "actual dev=$cur_dev ino=$cur_inode, aborting."
528 );
839bc55a 529 }
cac619e8 530
cc744934
CBW
531 if ( $data->{depth} or !$data->{keep_root} ) {
532 if ( $data->{safe}
139271cd
CBW
533 && ( _IS_VMS
534 ? !&VMS::Filespec::candelete($root)
535 : !-w $root ) )
536 {
cc744934 537 print "skipped $root\n" if $data->{verbose};
cac619e8
DL
538 next ROOT_DIR;
539 }
139271cd 540 if ( _FORCE_WRITABLE and !chmod $perm | oct '700', $root ) {
cc744934 541 _error( $data, "cannot make directory writeable", $canon );
30cf951a 542 }
cc744934 543 print "rmdir $root\n" if $data->{verbose};
139271cd 544 if ( rmdir $root ) {
cc744934 545 push @{ ${ $data->{result} } }, $root if $data->{result};
cac619e8
DL
546 ++$count;
547 }
548 else {
cc744934 549 _error( $data, "cannot remove directory", $canon );
139271cd
CBW
550 if (
551 _FORCE_WRITABLE
552 && !chmod( $perm,
553 ( _IS_VMS ? VMS::Filespec::fileify($root) : $root )
554 )
555 )
556 {
557 _error(
cc744934 558 $data,
139271cd
CBW
559 sprintf( "cannot restore permissions to 0%o",
560 $perm ),
561 $canon
562 );
cac619e8
DL
563 }
564 }
565 }
566 }
567 else {
568 # not a directory
cac619e8 569 $root = VMS::Filespec::vmsify("./$root")
139271cd
CBW
570 if _IS_VMS
571 && !File::Spec->file_name_is_absolute($root)
572 && ( $root !~ m/(?<!\^)[\]>]+/ ); # not already in VMS syntax
573
574 if (
cc744934 575 $data->{safe}
139271cd
CBW
576 && (
577 _IS_VMS
578 ? !&VMS::Filespec::candelete($root)
579 : !( -l $root || -w $root )
580 )
581 )
cac619e8 582 {
cc744934 583 print "skipped $root\n" if $data->{verbose};
cac619e8
DL
584 next ROOT_DIR;
585 }
586
139271cd
CBW
587 my $nperm = $perm & oct '7777' | oct '600';
588 if ( _FORCE_WRITABLE
589 and $nperm != $perm
590 and not chmod $nperm, $root )
591 {
cc744934 592 _error( $data, "cannot make file writeable", $canon );
30cf951a 593 }
cc744934 594 print "unlink $canon\n" if $data->{verbose};
139271cd 595
cac619e8 596 # delete all versions under VMS
139271cd
CBW
597 for ( ; ; ) {
598 if ( unlink $root ) {
cc744934 599 push @{ ${ $data->{result} } }, $root if $data->{result};
cac619e8
DL
600 }
601 else {
cc744934 602 _error( $data, "cannot unlink file", $canon );
139271cd 603 _FORCE_WRITABLE and chmod( $perm, $root )
cc744934 604 or _error( $data,
139271cd
CBW
605 sprintf( "cannot restore permissions to 0%o", $perm ),
606 $canon );
cac619e8
DL
607 last;
608 }
609 ++$count;
139271cd 610 last unless _IS_VMS && lstat $root;
cac619e8
DL
611 }
612 }
613 }
cac619e8
DL
614 return $count;
615}
616
3f083399 617sub _slash_lc {
139271cd 618
3f083399
NC
619 # fix up slashes and case on MSWin32 so that we can determine that
620 # c:\path\to\dir is underneath C:/Path/To
621 my $path = shift;
622 $path =~ tr{\\}{/};
623 return lc($path);
624}
625
cac619e8 6261;
139271cd 627
cac619e8
DL
628__END__
629
fed7345c
AD
630=head1 NAME
631
12c2e016
DL
632File::Path - Create or remove directory trees
633
634=head1 VERSION
635
f4b02d78 6362.17 - released July 18 2020.
fed7345c
AD
637
638=head1 SYNOPSIS
639
cc744934
CBW
640 use File::Path qw(make_path remove_tree);
641
642 @created = make_path('foo/bar/baz', '/zug/zwang');
643 @created = make_path('foo/bar/baz', '/zug/zwang', {
644 verbose => 1,
645 mode => 0711,
646 });
647 make_path('foo/bar/baz', '/zug/zwang', {
648 chmod => 0777,
649 });
650
651 $removed_count = remove_tree('foo/bar/baz', '/zug/zwang', {
652 verbose => 1,
653 error => \my $err_list,
654 safe => 1,
655 });
656
657 # legacy (interface promoted before v2.00)
658 @created = mkpath('/foo/bar/baz');
659 @created = mkpath('/foo/bar/baz', 1, 0711);
660 @created = mkpath(['/foo/bar/baz', 'blurfl/quux'], 1, 0711);
661 $removed_count = rmtree('foo/bar/baz', 1, 1);
662 $removed_count = rmtree(['foo/bar/baz', 'blurfl/quux'], 1, 1);
663
664 # legacy (interface promoted before v2.06)
665 @created = mkpath('foo/bar/baz', '/zug/zwang', { verbose => 1, mode => 0711 });
666 $removed_count = rmtree('foo/bar/baz', '/zug/zwang', { verbose => 1, mode => 0711 });
12c2e016 667
2f9d49b4 668=head1 DESCRIPTION
12c2e016 669
cc744934 670This module provides a convenient way to create directories of
2f9d49b4
NC
671arbitrary depth and to delete an entire directory subtree from the
672filesystem.
3f083399 673
2f9d49b4 674The following functions are provided:
3f083399 675
2f9d49b4 676=over
12c2e016 677
2f9d49b4 678=item make_path( $dir1, $dir2, .... )
12c2e016 679
2f9d49b4 680=item make_path( $dir1, $dir2, ...., \%opts )
3f083399 681
2f9d49b4 682The C<make_path> function creates the given directories if they don't
cc744934 683exist before, much like the Unix command C<mkdir -p>.
3f083399 684
2f9d49b4
NC
685The function accepts a list of directories to be created. Its
686behaviour may be tuned by an optional hashref appearing as the last
687parameter on the call.
12c2e016 688
3f083399 689The function returns the list of directories actually created during
2f9d49b4 690the call; in scalar context the number of directories created.
3f083399 691
2f9d49b4 692The following keys are recognised in the option hash:
3f083399 693
2f9d49b4 694=over
12c2e016 695
2f9d49b4 696=item mode => $num
12c2e016 697
0b3d36bd 698The numeric permissions mode to apply to each created directory
cc744934 699(defaults to C<0777>), to be modified by the current C<umask>. If the
0b3d36bd
DL
700directory already exists (and thus does not need to be created),
701the permissions will not be modified.
702
703C<mask> is recognised as an alias for this parameter.
12c2e016 704
139271cd
CBW
705=item chmod => $num
706
707Takes a numeric mode to apply to each created directory (not
708modified by the current C<umask>). If the directory already exists
709(and thus does not need to be created), the permissions will
710not be modified.
711
2f9d49b4 712=item verbose => $bool
12c2e016 713
30cf951a 714If present, will cause C<make_path> to print the name of each directory
12c2e016
DL
715as it is created. By default nothing is printed.
716
2f9d49b4 717=item error => \$err
12c2e016 718
2f9d49b4
NC
719If present, it should be a reference to a scalar.
720This scalar will be made to reference an array, which will
867b93c3
NC
721be used to store any errors that are encountered. See the L</"ERROR
722HANDLING"> section for more information.
12c2e016 723
0b3d36bd 724If this parameter is not used, certain error conditions may raise
139271cd 725a fatal error that will cause the program to halt, unless trapped
0b3d36bd 726in an C<eval> block.
12c2e016 727
30eb83e1
RGS
728=item owner => $owner
729
730=item user => $owner
731
732=item uid => $owner
733
734If present, will cause any created directory to be owned by C<$owner>.
cc744934
CBW
735If the value is numeric, it will be interpreted as a uid; otherwise a
736username is assumed. An error will be issued if the username cannot be
737mapped to a uid, the uid does not exist or the process lacks the
30eb83e1
RGS
738privileges to change ownership.
739
139271cd 740Ownership of directories that already exist will not be changed.
30eb83e1
RGS
741
742C<user> and C<uid> are aliases of C<owner>.
743
744=item group => $group
745
cc744934
CBW
746If present, will cause any created directory to be owned by the group
747C<$group>. If the value is numeric, it will be interpreted as a gid;
748otherwise a group name is assumed. An error will be issued if the
749group name cannot be mapped to a gid, the gid does not exist or the
750process lacks the privileges to change group ownership.
30eb83e1 751
139271cd 752Group ownership of directories that already exist will not be changed.
30eb83e1
RGS
753
754 make_path '/var/tmp/webcache', {owner=>'nobody', group=>'nogroup'};
755
12c2e016
DL
756=back
757
30cf951a
NC
758=item mkpath( $dir )
759
2f9d49b4 760=item mkpath( $dir, $verbose, $mode )
3f083399 761
2f9d49b4 762=item mkpath( [$dir1, $dir2,...], $verbose, $mode )
3f083399 763
2f9d49b4 764=item mkpath( $dir1, $dir2,..., \%opt )
3f083399 765
cc744934
CBW
766The C<mkpath()> function provide the legacy interface of
767C<make_path()> with a different interpretation of the arguments
768passed. The behaviour and return value of the function is otherwise
769identical to C<make_path()>.
12c2e016 770
2f9d49b4 771=item remove_tree( $dir1, $dir2, .... )
3f083399 772
2f9d49b4 773=item remove_tree( $dir1, $dir2, ...., \%opts )
3f083399 774
2f9d49b4
NC
775The C<remove_tree> function deletes the given directories and any
776files and subdirectories they might contain, much like the Unix
07e6e035 777command C<rm -rf> or the Windows commands C<rmdir /s> and C<rd /s>.
12c2e016 778
07e6e035
CBW
779The function accepts a list of directories to be removed. (In point of fact,
780it will also accept filesystem entries which are not directories, such as
781regular files and symlinks. But, as its name suggests, its intent is to
782remove trees rather than individual files.)
783
784C<remove_tree()>'s behaviour may be tuned by an optional hashref
bfcc9519
SH
785appearing as the last parameter on the call. If an empty string is
786passed to C<remove_tree>, an error will occur.
2f9d49b4 787
cc744934
CBW
788B<NOTE:> For security reasons, we strongly advise use of the
789hashref-as-final-argument syntax -- specifically, with a setting of the C<safe>
790element to a true value.
791
792 remove_tree( $dir1, $dir2, ....,
793 {
794 safe => 1,
795 ... # other key-value pairs
796 },
797 );
798
799The function returns the number of files successfully deleted.
2f9d49b4
NC
800
801The following keys are recognised in the option hash:
802
803=over
804
805=item verbose => $bool
12c2e016 806
30cf951a 807If present, will cause C<remove_tree> to print the name of each file as
12c2e016
DL
808it is unlinked. By default nothing is printed.
809
2f9d49b4 810=item safe => $bool
12c2e016 811
30cf951a 812When set to a true value, will cause C<remove_tree> to skip the files
0b3d36bd 813for which the process lacks the required privileges needed to delete
5808899a
DL
814files, such as delete privileges on VMS. In other words, the code
815will make no attempt to alter file permissions. Thus, if the process
816is interrupted, no filesystem object will be left in a more
817permissive mode.
12c2e016 818
2f9d49b4 819=item keep_root => $bool
12c2e016 820
0b3d36bd
DL
821When set to a true value, will cause all files and subdirectories
822to be removed, except the initially specified directories. This comes
823in handy when cleaning out an application's scratch directory.
12c2e016 824
cc744934 825 remove_tree( '/tmp', {keep_root => 1} );
12c2e016 826
2f9d49b4 827=item result => \$res
12c2e016 828
2f9d49b4
NC
829If present, it should be a reference to a scalar.
830This scalar will be made to reference an array, which will
831be used to store all files and directories unlinked
867b93c3 832during the call. If nothing is unlinked, the array will be empty.
12c2e016 833
cc744934
CBW
834 remove_tree( '/tmp', {result => \my $list} );
835 print "unlinked $_\n" for @$list;
12c2e016 836
0b3d36bd
DL
837This is a useful alternative to the C<verbose> key.
838
2f9d49b4 839=item error => \$err
12c2e016 840
2f9d49b4
NC
841If present, it should be a reference to a scalar.
842This scalar will be made to reference an array, which will
867b93c3
NC
843be used to store any errors that are encountered. See the L</"ERROR
844HANDLING"> section for more information.
12c2e016 845
0b3d36bd
DL
846Removing things is a much more dangerous proposition than
847creating things. As such, there are certain conditions that
30cf951a 848C<remove_tree> may encounter that are so dangerous that the only
0b3d36bd
DL
849sane action left is to kill the program.
850
851Use C<error> to trap all that is reasonable (problems with
852permissions and the like), and let it die if things get out
853of hand. This is the safest course of action.
12c2e016
DL
854
855=back
856
2f9d49b4 857=item rmtree( $dir )
fed7345c 858
2f9d49b4 859=item rmtree( $dir, $verbose, $safe )
fed7345c 860
2f9d49b4 861=item rmtree( [$dir1, $dir2,...], $verbose, $safe )
fed7345c 862
2f9d49b4 863=item rmtree( $dir1, $dir2,..., \%opt )
fed7345c 864
cc744934
CBW
865The C<rmtree()> function provide the legacy interface of
866C<remove_tree()> with a different interpretation of the arguments
867passed. The behaviour and return value of the function is otherwise
868identical to C<remove_tree()>.
869
870B<NOTE:> For security reasons, we strongly advise use of the
871hashref-as-final-argument syntax, specifically with a setting of the C<safe>
872element to a true value.
873
874 rmtree( $dir1, $dir2, ....,
875 {
876 safe => 1,
877 ... # other key-value pairs
878 },
879 );
fed7345c
AD
880
881=back
882
12c2e016
DL
883=head2 ERROR HANDLING
884
30cf951a
NC
885=over 4
886
887=item B<NOTE:>
888
bfcc9519
SH
889The following error handling mechanism is consistent throughout all
890code paths EXCEPT in cases where the ROOT node is nonexistent. In
891version 2.11 the maintainers attempted to rectify this inconsistency
892but too many downstream modules encountered problems. In such case,
893if you require root node evaluation or error checking prior to calling
894C<make_path> or C<remove_tree>, you should take additional precautions.
30cf951a
NC
895
896=back
897
cc744934 898If C<make_path> or C<remove_tree> encounters an error, a diagnostic
30cf951a 899message will be printed to C<STDERR> via C<carp> (for non-fatal
cc744934 900errors) or via C<croak> (for fatal errors).
12c2e016
DL
901
902If this behaviour is not desirable, the C<error> attribute may be
903used to hold a reference to a variable, which will be used to store
867b93c3
NC
904the diagnostics. The variable is made a reference to an array of hash
905references. Each hash contain a single key/value pair where the key
906is the name of the file, and the value is the error message (including
907the contents of C<$!> when appropriate). If a general error is
908encountered the diagnostic key will be empty.
909
910An example usage looks like:
12c2e016 911
3f083399 912 remove_tree( 'foo/bar', 'bar/rat', {error => \my $err} );
cc744934 913 if ($err && @$err) {
867b93c3
NC
914 for my $diag (@$err) {
915 my ($file, $message) = %$diag;
916 if ($file eq '') {
917 print "general error: $message\n";
918 }
919 else {
920 print "problem unlinking $file: $message\n";
921 }
922 }
12c2e016 923 }
867b93c3
NC
924 else {
925 print "No error encountered\n";
12c2e016
DL
926 }
927
867b93c3
NC
928Note that if no errors are encountered, C<$err> will reference an
929empty array. This means that C<$err> will always end up TRUE; so you
139271cd 930need to test C<@$err> to determine if errors occurred.
867b93c3 931
12c2e016
DL
932=head2 NOTES
933
0b3d36bd
DL
934C<File::Path> blindly exports C<mkpath> and C<rmtree> into the
935current namespace. These days, this is considered bad style, but
936to change it now would break too much code. Nonetheless, you are
937invited to specify what it is you are expecting to use:
938
939 use File::Path 'rmtree';
940
3f083399
NC
941The routines C<make_path> and C<remove_tree> are B<not> exported
942by default. You must specify which ones you want to use.
e2ba98a1 943
3f083399 944 use File::Path 'remove_tree';
e2ba98a1 945
3f083399
NC
946Note that a side-effect of the above is that C<mkpath> and C<rmtree>
947are no longer exported at all. This is due to the way the C<Exporter>
948module works. If you are migrating a codebase to use the new
949interface, you will have to list everything explicitly. But that's
950just good practice anyway.
12c2e016 951
3f083399 952 use File::Path qw(remove_tree rmtree);
12c2e016 953
30eb83e1
RGS
954=head3 API CHANGES
955
956The API was changed in the 2.0 branch. For a time, C<mkpath> and
957C<rmtree> tried, unsuccessfully, to deal with the two different
958calling mechanisms. This approach was considered a failure.
959
960The new semantics are now only available with C<make_path> and
961C<remove_tree>. The old semantics are only available through
962C<mkpath> and C<rmtree>. Users are strongly encouraged to upgrade
963to at least 2.08 in order to avoid surprises.
964
0b3d36bd 965=head3 SECURITY CONSIDERATIONS
12c2e016 966
cc744934 967There were race conditions in the 1.x implementations of File::Path's
0b3d36bd
DL
968C<rmtree> function (although sometimes patched depending on the OS
969distribution or platform). The 2.0 version contains code to avoid the
970problem mentioned in CVE-2002-0435.
12c2e016 971
0b3d36bd 972See the following pages for more information:
12c2e016 973
cc744934
CBW
974 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=286905
975 http://www.nntp.perl.org/group/perl.perl5.porters/2005/01/msg97623.html
976 http://www.debian.org/security/2005/dsa-696
12c2e016 977
5808899a 978Additionally, unless the C<safe> parameter is set (or the
37b1cd44 979third parameter in the traditional interface is TRUE), should a
30cf951a 980C<remove_tree> be interrupted, files that were originally in read-only
0b3d36bd
DL
981mode may now have their permissions set to a read-write (or "delete
982OK") mode.
96e4d5b1 983
cc744934
CBW
984The following CVE reports were previously filed against File-Path and are
985believed to have been addressed:
986
987=over 4
988
989=item * L<http://cve.circl.lu/cve/CVE-2004-0452>
990
991=item * L<http://cve.circl.lu/cve/CVE-2005-0448>
992
993=back
994
995In February 2017 the cPanel Security Team reported an additional vulnerability
996in File-Path. The C<chmod()> logic to make directories traversable can be
997abused to set the mode on an attacker-chosen file to an attacker-chosen value.
998This is due to the time-of-check-to-time-of-use (TOCTTOU) race condition
999(L<https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use>) between the
1000C<stat()> that decides the inode is a directory and the C<chmod()> that tries
1001to make it user-rwx. CPAN versions 2.13 and later incorporate a patch
1002provided by John Lightsey to address this problem. This vulnerability has
1003been reported as CVE-2017-6512.
1004
b8d5f521
CW
1005=head1 DIAGNOSTICS
1006
0b3d36bd
DL
1007FATAL errors will cause the program to halt (C<croak>), since the
1008problem is so severe that it would be dangerous to continue. (This
1009can always be trapped with C<eval>, but it's not a good idea. Under
1010the circumstances, dying is the best thing to do).
1011
1012SEVERE errors may be trapped using the modern interface. If the
cc744934 1013they are not trapped, or if the old interface is used, such an error
0b3d36bd
DL
1014will cause the program will halt.
1015
1016All other errors may be trapped using the modern interface, otherwise
1017they will be C<carp>ed about. Program execution will not be halted.
1018
b8d5f521
CW
1019=over 4
1020
37b1cd44 1021=item mkdir [path]: [errmsg] (SEVERE)
0b3d36bd 1022
867b93c3 1023C<make_path> was unable to create the path. Probably some sort of
cc744934 1024permissions error at the point of departure or insufficient resources
0b3d36bd
DL
1025(such as free inodes on Unix).
1026
1027=item No root path(s) specified
1028
867b93c3 1029C<make_path> was not given any paths to create. This message is only
0b3d36bd
DL
1030emitted if the routine is called with the traditional interface.
1031The modern interface will remain silent if given nothing to do.
1032
1033=item No such file or directory
1034
867b93c3 1035On Windows, if C<make_path> gives you this warning, it may mean that
0b3d36bd
DL
1036you have exceeded your filesystem's maximum path length.
1037
1038=item cannot fetch initial working directory: [errmsg]
1039
30cf951a 1040C<remove_tree> attempted to determine the initial directory by calling
0b3d36bd
DL
1041C<Cwd::getcwd>, but the call failed for some reason. No attempt
1042will be made to delete anything.
1043
1044=item cannot stat initial working directory: [errmsg]
1045
30cf951a 1046C<remove_tree> attempted to stat the initial directory (after having
0b3d36bd
DL
1047successfully obtained its name via C<getcwd>), however, the call
1048failed for some reason. No attempt will be made to delete anything.
1049
1050=item cannot chdir to [dir]: [errmsg]
1051
30cf951a 1052C<remove_tree> attempted to set the working directory in order to
0b3d36bd
DL
1053begin deleting the objects therein, but was unsuccessful. This is
1054usually a permissions issue. The routine will continue to delete
1055other things, but this directory will be left intact.
1056
3f083399 1057=item directory [dir] changed before chdir, expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)
0b3d36bd 1058
30cf951a 1059C<remove_tree> recorded the device and inode of a directory, and then
0b3d36bd
DL
1060moved into it. It then performed a C<stat> on the current directory
1061and detected that the device and inode were no longer the same. As
1062this is at the heart of the race condition problem, the program
1063will die at this point.
1064
1065=item cannot make directory [dir] read+writeable: [errmsg]
1066
30cf951a 1067C<remove_tree> attempted to change the permissions on the current directory
0b3d36bd
DL
1068to ensure that subsequent unlinkings would not run into problems,
1069but was unable to do so. The permissions remain as they were, and
1070the program will carry on, doing the best it can.
1071
1072=item cannot read [dir]: [errmsg]
1073
30cf951a 1074C<remove_tree> tried to read the contents of the directory in order
0b3d36bd
DL
1075to acquire the names of the directory entries to be unlinked, but
1076was unsuccessful. This is usually a permissions issue. The
1077program will continue, but the files in this directory will remain
1078after the call.
1079
1080=item cannot reset chmod [dir]: [errmsg]
1081
30cf951a 1082C<remove_tree>, after having deleted everything in a directory, attempted
cac619e8
DL
1083to restore its permissions to the original state but failed. The
1084directory may wind up being left behind.
12c2e016 1085
c42ebacb
CB
1086=item cannot remove [dir] when cwd is [dir]
1087
1088The current working directory of the program is F</some/path/to/here>
1089and you are attempting to remove an ancestor, such as F</some/path>.
1090The directory tree is left untouched.
1091
1092The solution is to C<chdir> out of the child directory to a place
1093outside the directory tree to be removed.
1094
cac619e8 1095=item cannot chdir to [parent-dir] from [child-dir]: [errmsg], aborting. (FATAL)
12c2e016 1096
30cf951a 1097C<remove_tree>, after having deleted everything and restored the permissions
3f083399
NC
1098of a directory, was unable to chdir back to the parent. The program
1099halts to avoid a race condition from occurring.
fed7345c 1100
cac619e8 1101=item cannot stat prior working directory [dir]: [errmsg], aborting. (FATAL)
0b3d36bd 1102
cc744934 1103C<remove_tree> was unable to stat the parent directory after having returned
cac619e8
DL
1104from the child. Since there is no way of knowing if we returned to
1105where we think we should be (by comparing device and inode) the only
1106way out is to C<croak>.
0b3d36bd 1107
3f083399 1108=item previous directory [parent-dir] changed before entering [child-dir], expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)
0b3d36bd 1109
30cf951a 1110When C<remove_tree> returned from deleting files in a child directory, a
cac619e8
DL
1111check revealed that the parent directory it returned to wasn't the one
1112it started out from. This is considered a sign of malicious activity.
0b3d36bd 1113
cac619e8 1114=item cannot make directory [dir] writeable: [errmsg]
ee79a11f 1115
cac619e8 1116Just before removing a directory (after having successfully removed
30cf951a 1117everything it contained), C<remove_tree> attempted to set the permissions
cac619e8
DL
1118on the directory to ensure it could be removed and failed. Program
1119execution continues, but the directory may possibly not be deleted.
0b3d36bd 1120
cac619e8 1121=item cannot remove directory [dir]: [errmsg]
0b3d36bd 1122
cc744934 1123C<remove_tree> attempted to remove a directory, but failed. This may be because
cac619e8 1124some objects that were unable to be removed remain in the directory, or
cc744934 1125it could be a permissions issue. The directory will be left behind.
0b3d36bd 1126
cac619e8 1127=item cannot restore permissions of [dir] to [0nnn]: [errmsg]
0b3d36bd 1128
30cf951a 1129After having failed to remove a directory, C<remove_tree> was unable to
cac619e8
DL
1130restore its permissions from a permissive state back to a possibly
1131more restrictive setting. (Permissions given in octal).
0b3d36bd 1132
cac619e8 1133=item cannot make file [file] writeable: [errmsg]
b5400373 1134
30cf951a 1135C<remove_tree> attempted to force the permissions of a file to ensure it
cac619e8
DL
1136could be deleted, but failed to do so. It will, however, still attempt
1137to unlink the file.
0b3d36bd 1138
cac619e8 1139=item cannot unlink file [file]: [errmsg]
0b3d36bd 1140
30cf951a 1141C<remove_tree> failed to remove a file. Probably a permissions issue.
0b3d36bd 1142
cac619e8 1143=item cannot restore permissions of [file] to [0nnn]: [errmsg]
0b3d36bd 1144
30cf951a 1145After having failed to remove a file, C<remove_tree> was also unable
cac619e8
DL
1146to restore the permissions on the file to a possibly less permissive
1147setting. (Permissions given in octal).
0b3d36bd 1148
30eb83e1
RGS
1149=item unable to map [owner] to a uid, ownership not changed");
1150
1151C<make_path> was instructed to give the ownership of created
1152directories to the symbolic name [owner], but C<getpwnam> did
1153not return the corresponding numeric uid. The directory will
1154be created, but ownership will not be changed.
1155
1156=item unable to map [group] to a gid, group ownership not changed
1157
1158C<make_path> was instructed to give the group ownership of created
1159directories to the symbolic name [group], but C<getgrnam> did
1160not return the corresponding numeric gid. The directory will
1161be created, but group ownership will not be changed.
1162
cac619e8 1163=back
12c2e016 1164
cac619e8 1165=head1 SEE ALSO
037c8c09 1166
cac619e8 1167=over 4
0b3d36bd 1168
cac619e8 1169=item *
0b3d36bd 1170
351a5cfe
DL
1171L<File::Remove>
1172
1173Allows files and directories to be moved to the Trashcan/Recycle
1174Bin (where they may later be restored if necessary) if the operating
1175system supports such functionality. This feature may one day be
1176made available directly in C<File::Path>.
1177
1178=item *
1179
cac619e8 1180L<File::Find::Rule>
0b3d36bd 1181
cac619e8
DL
1182When removing directory trees, if you want to examine each file to
1183decide whether to delete it (and possibly leaving large swathes
1184alone), F<File::Find::Rule> offers a convenient and flexible approach
1185to examining directory trees.
0b3d36bd 1186
cac619e8 1187=back
0b3d36bd 1188
139271cd
CBW
1189=head1 BUGS AND LIMITATIONS
1190
1191The following describes F<File::Path> limitations and how to report bugs.
1192
cc744934 1193=head2 MULTITHREADED APPLICATIONS
139271cd 1194
cc744934
CBW
1195F<File::Path> C<rmtree> and C<remove_tree> will not work with
1196multithreaded applications due to its use of C<chdir>. At this time,
1197no warning or error is generated in this situation. You will
1198certainly encounter unexpected results.
0b3d36bd 1199
cc744934
CBW
1200The implementation that surfaces this limitation will not be changed. See the
1201F<File::Path::Tiny> module for functionality similar to F<File::Path> but which does
1202not C<chdir>.
139271cd
CBW
1203
1204=head2 NFS Mount Points
1205
1206F<File::Path> is not responsible for triggering the automounts, mirror mounts,
1207and the contents of network mounted filesystems. If your NFS implementation
1208requires an action to be performed on the filesystem in order for
1209F<File::Path> to perform operations, it is strongly suggested you assure
1210filesystem availability by reading the root of the mounted filesystem.
1211
1212=head2 REPORTING BUGS
1213
1214Please report all bugs on the RT queue, either via the web interface:
b5400373 1215
cac619e8 1216L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=File-Path>
b5400373 1217
139271cd
CBW
1218or by email:
1219
1220 bug-File-Path@rt.cpan.org
1221
1222In either case, please B<attach> patches to the bug report rather than
1223including them inline in the web post or the body of the email.
1224
8f65b4cd
CBW
1225You can also send pull requests to the Github repository:
1226
139271cd 1227L<https://github.com/rpcme/File-Path>
8f65b4cd 1228
cac619e8 1229=head1 ACKNOWLEDGEMENTS
0b3d36bd 1230
cac619e8
DL
1231Paul Szabo identified the race condition originally, and Brendan
1232O'Dea wrote an implementation for Debian that addressed the problem.
1233That code was used as a basis for the current code. Their efforts
1234are greatly appreciated.
fed7345c 1235
867b93c3
NC
1236Gisle Aas made a number of improvements to the documentation for
12372.07 and his advice and assistance is also greatly appreciated.
1238
cac619e8 1239=head1 AUTHORS
fed7345c 1240
139271cd
CBW
1241Prior authors and maintainers: Tim Bunce, Charles Bailey, and
1242David Landgren <F<david@landgren.net>>.
1243
1244Current maintainers are Richard Elberger <F<riche@cpan.org>> and
1245James (Jim) Keenan <F<jkeenan@cpan.org>>.
1246
1247=head1 CONTRIBUTORS
1248
cc744934 1249Contributors to File::Path, in alphabetical order by first name.
139271cd
CBW
1250
1251=over 1
1252
1253=item <F<bulkdd@cpan.org>>
1254
cc744934
CBW
1255=item Charlie Gonzalez <F<itcharlie@cpan.org>>
1256
bfcc9519
SH
1257=item Craig A. Berry <F<craigberry@mac.com>>
1258
cc744934
CBW
1259=item James E Keenan <F<jkeenan@cpan.org>>
1260
1261=item John Lightsey <F<john@perlsec.org>>
1262
1263=item Nigel Horne <F<njh@bandsman.co.uk>>
1264
139271cd
CBW
1265=item Richard Elberger <F<riche@cpan.org>>
1266
1267=item Ryan Yee <F<ryee@cpan.org>>
1268
1269=item Skye Shaw <F<shaw@cpan.org>>
1270
1271=item Tom Lutz <F<tommylutz@gmail.com>>
1272
cc744934
CBW
1273=item Will Sheppard <F<willsheppard@github>>
1274
139271cd 1275=back
cac619e8
DL
1276
1277=head1 COPYRIGHT
1278
139271cd 1279This module is copyright (C) Charles Bailey, Tim Bunce, David Landgren,
f4b02d78 1280James Keenan and Richard Elberger 1995-2020. All rights reserved.
cac619e8
DL
1281
1282=head1 LICENSE
1283
1284This library is free software; you can redistribute it and/or modify
1285it under the same terms as Perl itself.
1286
1287=cut