This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to File::Path 2.06_07. (an e-mail from David)
[perl5.git] / 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 {
11 if ($] < 5.006) {
12 # can't say 'opendir my $dh, $dirname'
13 # need to initialise $dh
14 eval "use Symbol";
15 }
16}
17
18use Exporter ();
3f083399 19use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
2f9d49b4 20$VERSION = '2.06_07';
cac619e8
DL
21@ISA = qw(Exporter);
22@EXPORT = qw(mkpath rmtree);
3f083399 23@EXPORT_OK = qw(make_path remove_tree);
cac619e8
DL
24
25my $Is_VMS = $^O eq 'VMS';
26my $Is_MacOS = $^O eq 'MacOS';
27
28# These OSes complain if you want to remove a file that you have no
29# write permission to:
351a5cfe 30my $Force_Writeable = grep {$^O eq $_} qw(amigaos dos epoc MSWin32 MacOS os2);
cac619e8
DL
31
32sub _carp {
33 require Carp;
34 goto &Carp::carp;
35}
36
37sub _croak {
38 require Carp;
39 goto &Carp::croak;
40}
41
42sub _error {
43 my $arg = shift;
44 my $message = shift;
45 my $object = shift;
46
47 if ($arg->{error}) {
48 $object = '' unless defined $object;
3f083399
NC
49 $message .= ": $!" if $!;
50 push @{${$arg->{error}}}, {$object => $message};
cac619e8
DL
51 }
52 else {
53 _carp(defined($object) ? "$message for $object: $!" : "$message: $!");
54 }
55}
56
3f083399 57sub make_path {
2f9d49b4 58 push @_, {} unless @_ and UNIVERSAL::isa($_[-1],'HASH');
3f083399
NC
59 goto &mkpath;
60}
61
cac619e8 62sub mkpath {
2f9d49b4 63 my $old_style = !(@_ and UNIVERSAL::isa($_[-1],'HASH'));
cac619e8
DL
64
65 my $arg;
66 my $paths;
67
68 if ($old_style) {
69 my ($verbose, $mode);
70 ($paths, $verbose, $mode) = @_;
71 $paths = [$paths] unless UNIVERSAL::isa($paths,'ARRAY');
2f9d49b4 72 $arg->{verbose} = $verbose;
cac619e8
DL
73 $arg->{mode} = defined $mode ? $mode : 0777;
74 }
75 else {
cac619e8 76 $arg = pop @_;
3f083399 77 $arg->{mode} = delete $arg->{mask} if exists $arg->{mask};
cac619e8
DL
78 $arg->{mode} = 0777 unless exists $arg->{mode};
79 ${$arg->{error}} = [] if exists $arg->{error};
cac619e8
DL
80 $paths = [@_];
81 }
82 return _mkpath($arg, $paths);
83}
84
85sub _mkpath {
86 my $arg = shift;
87 my $paths = shift;
88
cac619e8
DL
89 my(@created,$path);
90 foreach $path (@$paths) {
3f083399 91 next unless defined($path) and length($path);
cac619e8
DL
92 $path .= '/' if $^O eq 'os2' and $path =~ /^\w:\z/s; # feature of CRT
93 # Logic wants Unix paths, so go with the flow.
94 if ($Is_VMS) {
95 next if $path eq '/';
96 $path = VMS::Filespec::unixify($path);
97 }
98 next if -d $path;
99 my $parent = File::Basename::dirname($path);
100 unless (-d $parent or $path eq $parent) {
101 push(@created,_mkpath($arg, [$parent]));
102 }
103 print "mkdir $path\n" if $arg->{verbose};
104 if (mkdir($path,$arg->{mode})) {
105 push(@created, $path);
106 }
107 else {
108 my $save_bang = $!;
109 my ($e, $e1) = ($save_bang, $^E);
110 $e .= "; $e1" if $e ne $e1;
111 # allow for another process to have created it meanwhile
112 if (!-d $path) {
113 $! = $save_bang;
114 if ($arg->{error}) {
115 push @{${$arg->{error}}}, {$path => $e};
116 }
117 else {
118 _croak("mkdir $path: $e");
119 }
120 }
121 }
122 }
123 return @created;
124}
125
3f083399 126sub remove_tree {
2f9d49b4 127 push @_, {} unless @_ and UNIVERSAL::isa($_[-1],'HASH');
3f083399
NC
128 goto &rmtree;
129}
130
cac619e8 131sub rmtree {
2f9d49b4 132 my $old_style = !(@_ and UNIVERSAL::isa($_[-1],'HASH'));
cac619e8
DL
133
134 my $arg;
135 my $paths;
136
137 if ($old_style) {
138 my ($verbose, $safe);
139 ($paths, $verbose, $safe) = @_;
2f9d49b4 140 $arg->{verbose} = $verbose;
cac619e8
DL
141 $arg->{safe} = defined $safe ? $safe : 0;
142
143 if (defined($paths) and length($paths)) {
144 $paths = [$paths] unless UNIVERSAL::isa($paths,'ARRAY');
145 }
146 else {
147 _carp ("No root path(s) specified\n");
148 return 0;
149 }
150 }
151 else {
cac619e8
DL
152 $arg = pop @_;
153 ${$arg->{error}} = [] if exists $arg->{error};
154 ${$arg->{result}} = [] if exists $arg->{result};
cac619e8
DL
155 $paths = [@_];
156 }
157
158 $arg->{prefix} = '';
159 $arg->{depth} = 0;
160
3f083399 161 my @clean_path;
cac619e8
DL
162 $arg->{cwd} = getcwd() or do {
163 _error($arg, "cannot fetch initial working directory");
164 return 0;
165 };
166 for ($arg->{cwd}) { /\A(.*)\Z/; $_ = $1 } # untaint
167
3f083399
NC
168 for my $p (@$paths) {
169 # need to fixup case and map \ to / on Windows
170 my $ortho_root = $^O eq 'MSWin32' ? _slash_lc($p) : $p;
171 my $ortho_cwd = $^O eq 'MSWin32' ? _slash_lc($arg->{cwd}) : $arg->{cwd};
172 if ($ortho_root eq substr($ortho_cwd, 0, length($ortho_root))) {
173 local $! = 0;
174 _error($arg, "cannot remove path when cwd is $arg->{cwd}", $p);
175 next;
176 }
177
178 if ($Is_MacOS) {
179 $p = ":$p" unless $p =~ /:/;
180 $p .= ":" unless $p =~ /:\z/;
181 }
182 elsif ($^O eq 'MSWin32') {
183 $p =~ s{[/\\]\z}{};
184 }
185 else {
186 $p =~ s{/\z}{};
187 }
188 push @clean_path, $p;
189 }
190
191 @{$arg}{qw(device inode perm)} = (lstat $arg->{cwd})[0,1] or do {
cac619e8
DL
192 _error($arg, "cannot stat initial working directory", $arg->{cwd});
193 return 0;
194 };
195
3f083399 196 return _rmtree($arg, \@clean_path);
cac619e8
DL
197}
198
199sub _rmtree {
200 my $arg = shift;
201 my $paths = shift;
202
203 my $count = 0;
204 my $curdir = File::Spec->curdir();
205 my $updir = File::Spec->updir();
206
207 my (@files, $root);
208 ROOT_DIR:
209 foreach $root (@$paths) {
cac619e8
DL
210 # since we chdir into each directory, it may not be obvious
211 # to figure out where we are if we generate a message about
212 # a file name. We therefore construct a semi-canonical
213 # filename, anchored from the directory being unlinked (as
214 # opposed to being truly canonical, anchored from the root (/).
215
216 my $canon = $arg->{prefix}
217 ? File::Spec->catfile($arg->{prefix}, $root)
218 : $root
219 ;
220
221 my ($ldev, $lino, $perm) = (lstat $root)[0,1,2] or next ROOT_DIR;
222
223 if ( -d _ ) {
224 $root = VMS::Filespec::pathify($root) if $Is_VMS;
225 if (!chdir($root)) {
226 # see if we can escalate privileges to get in
227 # (e.g. funny protection mask such as -w- instead of rwx)
228 $perm &= 07777;
229 my $nperm = $perm | 0700;
230 if (!($arg->{safe} or $nperm == $perm or chmod($nperm, $root))) {
231 _error($arg, "cannot make child directory read-write-exec", $canon);
232 next ROOT_DIR;
233 }
234 elsif (!chdir($root)) {
235 _error($arg, "cannot chdir to child", $canon);
236 next ROOT_DIR;
237 }
238 }
239
3f083399 240 my ($cur_dev, $cur_inode, $perm) = (stat $curdir)[0,1,2] or do {
cac619e8
DL
241 _error($arg, "cannot stat current working directory", $canon);
242 next ROOT_DIR;
243 };
244
3f083399
NC
245 ($ldev eq $cur_dev and $lino eq $cur_inode)
246 or _croak("directory $canon changed before chdir, expected dev=$ldev ino=$lino, actual dev=$cur_dev ino=$cur_inode, aborting.");
cac619e8
DL
247
248 $perm &= 07777; # don't forget setuid, setgid, sticky bits
249 my $nperm = $perm | 0700;
250
251 # notabene: 0700 is for making readable in the first place,
252 # it's also intended to change it to writable in case we have
253 # to recurse in which case we are better than rm -rf for
254 # subtrees with strange permissions
255
256 if (!($arg->{safe} or $nperm == $perm or chmod($nperm, $curdir))) {
257 _error($arg, "cannot make directory read+writeable", $canon);
258 $nperm = $perm;
259 }
260
261 my $d;
262 $d = gensym() if $] < 5.006;
263 if (!opendir $d, $curdir) {
264 _error($arg, "cannot opendir", $canon);
265 @files = ();
266 }
267 else {
268 no strict 'refs';
269 if (!defined ${"\cTAINT"} or ${"\cTAINT"}) {
270 # Blindly untaint dir names if taint mode is
271 # active, or any perl < 5.006
272 @files = map { /\A(.*)\z/s; $1 } readdir $d;
273 }
274 else {
275 @files = readdir $d;
276 }
277 closedir $d;
278 }
279
280 if ($Is_VMS) {
281 # Deleting large numbers of files from VMS Files-11
282 # filesystems is faster if done in reverse ASCIIbetical order.
283 # include '.' to '.;' from blead patch #31775
284 @files = map {$_ eq '.' ? '.;' : $_} reverse @files;
285 ($root = VMS::Filespec::unixify($root)) =~ s/\.dir\z//;
286 }
287 @files = grep {$_ ne $updir and $_ ne $curdir} @files;
288
289 if (@files) {
290 # remove the contained files before the directory itself
291 my $narg = {%$arg};
292 @{$narg}{qw(device inode cwd prefix depth)}
3f083399 293 = ($cur_dev, $cur_inode, $updir, $canon, $arg->{depth}+1);
cac619e8
DL
294 $count += _rmtree($narg, \@files);
295 }
296
297 # restore directory permissions of required now (in case the rmdir
298 # below fails), while we are still in the directory and may do so
299 # without a race via '.'
300 if ($nperm != $perm and not chmod($perm, $curdir)) {
301 _error($arg, "cannot reset chmod", $canon);
302 }
303
304 # don't leave the client code in an unexpected directory
305 chdir($arg->{cwd})
306 or _croak("cannot chdir to $arg->{cwd} from $canon: $!, aborting.");
307
308 # ensure that a chdir upwards didn't take us somewhere other
309 # than we expected (see CVE-2002-0435)
3f083399 310 ($cur_dev, $cur_inode) = (stat $curdir)[0,1]
cac619e8
DL
311 or _croak("cannot stat prior working directory $arg->{cwd}: $!, aborting.");
312
3f083399
NC
313 ($arg->{device} eq $cur_dev and $arg->{inode} eq $cur_inode)
314 or _croak("previous directory $arg->{cwd} changed before entering $canon, expected dev=$ldev ino=$lino, actual dev=$cur_dev ino=$cur_inode, aborting.");
cac619e8
DL
315
316 if ($arg->{depth} or !$arg->{keep_root}) {
317 if ($arg->{safe} &&
318 ($Is_VMS ? !&VMS::Filespec::candelete($root) : !-w $root)) {
319 print "skipped $root\n" if $arg->{verbose};
320 next ROOT_DIR;
321 }
3f083399 322 if ($Force_Writeable and !chmod $perm | 0700, $root) {
cac619e8
DL
323 _error($arg, "cannot make directory writeable", $canon);
324 }
cac619e8
DL
325 print "rmdir $root\n" if $arg->{verbose};
326 if (rmdir $root) {
327 push @{${$arg->{result}}}, $root if $arg->{result};
328 ++$count;
329 }
330 else {
331 _error($arg, "cannot remove directory", $canon);
332 if (!chmod($perm, ($Is_VMS ? VMS::Filespec::fileify($root) : $root))
333 ) {
334 _error($arg, sprintf("cannot restore permissions to 0%o",$perm), $canon);
335 }
336 }
337 }
338 }
339 else {
340 # not a directory
cac619e8 341 $root = VMS::Filespec::vmsify("./$root")
8b0a9f85
CB
342 if $Is_VMS
343 && !File::Spec->file_name_is_absolute($root)
344 && ($root !~ m/(?<!\^)[\]>]+/); # not already in VMS syntax
cac619e8
DL
345
346 if ($arg->{safe} &&
347 ($Is_VMS ? !&VMS::Filespec::candelete($root)
348 : !(-l $root || -w $root)))
349 {
350 print "skipped $root\n" if $arg->{verbose};
351 next ROOT_DIR;
352 }
353
354 my $nperm = $perm & 07777 | 0600;
3f083399 355 if ($Force_Writeable and $nperm != $perm and not chmod $nperm, $root) {
cac619e8
DL
356 _error($arg, "cannot make file writeable", $canon);
357 }
cac619e8
DL
358 print "unlink $canon\n" if $arg->{verbose};
359 # delete all versions under VMS
360 for (;;) {
361 if (unlink $root) {
362 push @{${$arg->{result}}}, $root if $arg->{result};
363 }
364 else {
365 _error($arg, "cannot unlink file", $canon);
366 $Force_Writeable and chmod($perm, $root) or
367 _error($arg, sprintf("cannot restore permissions to 0%o",$perm), $canon);
368 last;
369 }
370 ++$count;
371 last unless $Is_VMS && lstat $root;
372 }
373 }
374 }
cac619e8
DL
375 return $count;
376}
377
3f083399
NC
378sub _slash_lc {
379 # fix up slashes and case on MSWin32 so that we can determine that
380 # c:\path\to\dir is underneath C:/Path/To
381 my $path = shift;
382 $path =~ tr{\\}{/};
383 return lc($path);
384}
385
cac619e8
DL
3861;
387__END__
388
fed7345c
AD
389=head1 NAME
390
12c2e016
DL
391File::Path - Create or remove directory trees
392
393=head1 VERSION
394
2f9d49b4
NC
395This document describes version 2.06_07 of File::Path, released
3962008-10-29.
fed7345c
AD
397
398=head1 SYNOPSIS
399
2f9d49b4 400 use File::Path qw(make_path remove_tree);
fed7345c 401
2f9d49b4
NC
402 make_path('foo/bar/baz', '/zug/zwang');
403 make_path('foo/bar/baz', '/zug/zwang', {
404 verbose => 1,
405 mode => 0711,
406 });
12c2e016 407
2f9d49b4
NC
408 remove_tree('foo/bar/baz', '/zug/zwang');
409 remove_tree('foo/bar/baz', '/zug/zwang', {
410 verbose => 1,
411 error => \my $err_list,
412 });
12c2e016 413
2f9d49b4
NC
414 # legacy (interface promoted before v2.0)
415 mkpath('/foo/bar/baz');
416 mkpath('/foo/bar/baz', 1, 0711);
8b87c192 417 mkpath(['/foo/bar/baz', 'blurfl/quux'], 1, 0711);
2f9d49b4 418 rmtree('foo/bar/baz', 1, 1);
8b87c192 419 rmtree(['foo/bar/baz', 'blurfl/quux'], 1, 1);
fed7345c 420
2f9d49b4
NC
421 # legacy (interface promoted before v2.6)
422 mkpath('foo/bar/baz', '/zug/zwang', { verbose => 1, mode => 0711 });
423 rmtree('foo/bar/baz', '/zug/zwang', { verbose => 1, mode => 0711 });
12c2e016 424
2f9d49b4 425=head1 DESCRIPTION
12c2e016 426
2f9d49b4
NC
427This module provide a convenient way to create directories of
428arbitrary depth and to delete an entire directory subtree from the
429filesystem.
3f083399 430
2f9d49b4 431The following functions are provided:
3f083399 432
2f9d49b4 433=over
12c2e016 434
2f9d49b4 435=item make_path( $dir1, $dir2, .... )
12c2e016 436
2f9d49b4 437=item make_path( $dir1, $dir2, ...., \%opts )
3f083399 438
2f9d49b4
NC
439The C<make_path> function creates the given directories if they don't
440exists before, much like the Unix command C<mkdir -p>.
3f083399 441
2f9d49b4
NC
442The function accepts a list of directories to be created. Its
443behaviour may be tuned by an optional hashref appearing as the last
444parameter on the call.
12c2e016 445
3f083399 446The function returns the list of directories actually created during
2f9d49b4 447the call; in scalar context the number of directories created.
3f083399 448
2f9d49b4 449The following keys are recognised in the option hash:
3f083399 450
2f9d49b4 451=over
12c2e016 452
2f9d49b4 453=item mode => $num
12c2e016 454
0b3d36bd
DL
455The numeric permissions mode to apply to each created directory
456(defaults to 0777), to be modified by the current C<umask>. If the
457directory already exists (and thus does not need to be created),
458the permissions will not be modified.
459
460C<mask> is recognised as an alias for this parameter.
12c2e016 461
2f9d49b4 462=item verbose => $bool
12c2e016
DL
463
464If present, will cause C<mkpath> to print the name of each directory
465as it is created. By default nothing is printed.
466
2f9d49b4 467=item error => \$err
12c2e016 468
2f9d49b4
NC
469If present, it should be a reference to a scalar.
470This scalar will be made to reference an array, which will
12c2e016 471be used to store any errors that are encountered. See the ERROR
0b3d36bd 472HANDLING section for more information.
12c2e016 473
0b3d36bd
DL
474If this parameter is not used, certain error conditions may raise
475a fatal error that will cause the program will halt, unless trapped
476in an C<eval> block.
12c2e016
DL
477
478=back
479
2f9d49b4 480=item mkpath( $dir, $verbose, $mode )
3f083399 481
2f9d49b4 482=item mkpath( [$dir1, $dir2,...], $verbose, $mode )
3f083399 483
2f9d49b4 484=item mkpath( $dir1, $dir2,..., \%opt )
3f083399 485
2f9d49b4
NC
486The mkpath() function provide the legacy interface with a different
487interpretation of the arguments passed. This function also returns
488the list of directories actually created during the call.
12c2e016 489
2f9d49b4 490=item remove_tree( $dir1, $dir2, .... )
3f083399 491
2f9d49b4 492=item remove_tree( $dir1, $dir2, ...., \%opts )
3f083399 493
2f9d49b4
NC
494The C<remove_tree> function deletes the given directories and any
495files and subdirectories they might contain, much like the Unix
496command C<rm -r> or C<del /s> on Windows.
12c2e016 497
2f9d49b4
NC
498The function accepts a list of directories to be
499removed. Its behaviour may be tuned by an optional hashref
500appearing as the last parameter on the call.
501
502The functions returns the number of files successfully deleted.
503
504The following keys are recognised in the option hash:
505
506=over
507
508=item verbose => $bool
12c2e016
DL
509
510If present, will cause C<rmtree> to print the name of each file as
511it is unlinked. By default nothing is printed.
512
2f9d49b4 513=item safe => $bool
12c2e016 514
0b3d36bd
DL
515When set to a true value, will cause C<rmtree> to skip the files
516for which the process lacks the required privileges needed to delete
5808899a
DL
517files, such as delete privileges on VMS. In other words, the code
518will make no attempt to alter file permissions. Thus, if the process
519is interrupted, no filesystem object will be left in a more
520permissive mode.
12c2e016 521
2f9d49b4 522=item keep_root => $bool
12c2e016 523
0b3d36bd
DL
524When set to a true value, will cause all files and subdirectories
525to be removed, except the initially specified directories. This comes
526in handy when cleaning out an application's scratch directory.
12c2e016 527
3f083399 528 remove_tree( '/tmp', {keep_root => 1} );
12c2e016 529
2f9d49b4 530=item result => \$res
12c2e016 531
2f9d49b4
NC
532If present, it should be a reference to a scalar.
533This scalar will be made to reference an array, which will
534be used to store all files and directories unlinked
535during the call. If nothing is unlinked, a the array will be empty.
12c2e016 536
3f083399 537 remove_tree( '/tmp', {result => \my $list} );
12c2e016
DL
538 print "unlinked $_\n" for @$list;
539
0b3d36bd
DL
540This is a useful alternative to the C<verbose> key.
541
2f9d49b4 542=item error => \$err
12c2e016 543
2f9d49b4
NC
544If present, it should be a reference to a scalar.
545This scalar will be made to reference an array, which will
546be used to store any errors that are encountered. See the ERROR
547HANDLING section for more information.
12c2e016 548
0b3d36bd
DL
549Removing things is a much more dangerous proposition than
550creating things. As such, there are certain conditions that
551C<rmtree> may encounter that are so dangerous that the only
552sane action left is to kill the program.
553
554Use C<error> to trap all that is reasonable (problems with
555permissions and the like), and let it die if things get out
556of hand. This is the safest course of action.
12c2e016
DL
557
558=back
559
2f9d49b4 560=item rmtree( $dir )
fed7345c 561
2f9d49b4 562=item rmtree( $dir, $verbose, $safe )
fed7345c 563
2f9d49b4 564=item rmtree( [$dir1, $dir2,...], $verbose, $safe )
fed7345c 565
2f9d49b4 566=item rmtree( $dir1, $dir2,..., \%opt )
fed7345c 567
2f9d49b4
NC
568The rmtree() function provide the legacy interface with a different
569interpretation of the arguments passed.
fed7345c
AD
570
571=back
572
12c2e016
DL
573=head2 ERROR HANDLING
574
575If C<mkpath> or C<rmtree> encounter an error, a diagnostic message
576will be printed to C<STDERR> via C<carp> (for non-fatal errors),
577or via C<croak> (for fatal errors).
578
579If this behaviour is not desirable, the C<error> attribute may be
580used to hold a reference to a variable, which will be used to store
581the diagnostics. The result is a reference to a list of hash
582references. For each hash reference, the key is the name of the
583file, and the value is the error message (usually the contents of
584C<$!>). An example usage looks like:
585
3f083399 586 remove_tree( 'foo/bar', 'bar/rat', {error => \my $err} );
12c2e016
DL
587 for my $diag (@$err) {
588 my ($file, $message) = each %$diag;
589 print "problem unlinking $file: $message\n";
590 }
591
592If no errors are encountered, C<$err> will point to an empty list
593(thus there is no need to test for C<undef>). If a general error
594is encountered (for instance, C<rmtree> attempts to remove a directory
595tree that does not exist), the diagnostic key will be empty, only
596the value will be set:
597
3f083399 598 remove_tree( '/no/such/path', {error => \my $err} );
12c2e016
DL
599 for my $diag (@$err) {
600 my ($file, $message) = each %$diag;
601 if ($file eq '') {
602 print "general error: $message\n";
603 }
604 }
605
606=head2 NOTES
607
0b3d36bd
DL
608C<File::Path> blindly exports C<mkpath> and C<rmtree> into the
609current namespace. These days, this is considered bad style, but
610to change it now would break too much code. Nonetheless, you are
611invited to specify what it is you are expecting to use:
612
613 use File::Path 'rmtree';
614
3f083399
NC
615The routines C<make_path> and C<remove_tree> are B<not> exported
616by default. You must specify which ones you want to use.
e2ba98a1 617
3f083399 618 use File::Path 'remove_tree';
e2ba98a1 619
3f083399
NC
620Note that a side-effect of the above is that C<mkpath> and C<rmtree>
621are no longer exported at all. This is due to the way the C<Exporter>
622module works. If you are migrating a codebase to use the new
623interface, you will have to list everything explicitly. But that's
624just good practice anyway.
12c2e016 625
3f083399 626 use File::Path qw(remove_tree rmtree);
12c2e016 627
0b3d36bd 628=head3 SECURITY CONSIDERATIONS
12c2e016 629
0b3d36bd
DL
630There were race conditions 1.x implementations of File::Path's
631C<rmtree> function (although sometimes patched depending on the OS
632distribution or platform). The 2.0 version contains code to avoid the
633problem mentioned in CVE-2002-0435.
12c2e016 634
0b3d36bd 635See the following pages for more information:
12c2e016 636
0b3d36bd
DL
637 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=286905
638 http://www.nntp.perl.org/group/perl.perl5.porters/2005/01/msg97623.html
639 http://www.debian.org/security/2005/dsa-696
12c2e016 640
5808899a 641Additionally, unless the C<safe> parameter is set (or the
37b1cd44 642third parameter in the traditional interface is TRUE), should a
0b3d36bd
DL
643C<rmtree> be interrupted, files that were originally in read-only
644mode may now have their permissions set to a read-write (or "delete
645OK") mode.
96e4d5b1 646
b8d5f521
CW
647=head1 DIAGNOSTICS
648
0b3d36bd
DL
649FATAL errors will cause the program to halt (C<croak>), since the
650problem is so severe that it would be dangerous to continue. (This
651can always be trapped with C<eval>, but it's not a good idea. Under
652the circumstances, dying is the best thing to do).
653
654SEVERE errors may be trapped using the modern interface. If the
655they are not trapped, or the old interface is used, such an error
656will cause the program will halt.
657
658All other errors may be trapped using the modern interface, otherwise
659they will be C<carp>ed about. Program execution will not be halted.
660
b8d5f521
CW
661=over 4
662
37b1cd44 663=item mkdir [path]: [errmsg] (SEVERE)
0b3d36bd
DL
664
665C<mkpath> was unable to create the path. Probably some sort of
666permissions error at the point of departure, or insufficient resources
667(such as free inodes on Unix).
668
669=item No root path(s) specified
670
671C<mkpath> was not given any paths to create. This message is only
672emitted if the routine is called with the traditional interface.
673The modern interface will remain silent if given nothing to do.
674
675=item No such file or directory
676
677On Windows, if C<mkpath> gives you this warning, it may mean that
678you have exceeded your filesystem's maximum path length.
679
680=item cannot fetch initial working directory: [errmsg]
681
682C<rmtree> attempted to determine the initial directory by calling
683C<Cwd::getcwd>, but the call failed for some reason. No attempt
684will be made to delete anything.
685
686=item cannot stat initial working directory: [errmsg]
687
688C<rmtree> attempted to stat the initial directory (after having
689successfully obtained its name via C<getcwd>), however, the call
690failed for some reason. No attempt will be made to delete anything.
691
692=item cannot chdir to [dir]: [errmsg]
693
694C<rmtree> attempted to set the working directory in order to
695begin deleting the objects therein, but was unsuccessful. This is
696usually a permissions issue. The routine will continue to delete
697other things, but this directory will be left intact.
698
3f083399 699=item directory [dir] changed before chdir, expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)
0b3d36bd
DL
700
701C<rmtree> recorded the device and inode of a directory, and then
702moved into it. It then performed a C<stat> on the current directory
703and detected that the device and inode were no longer the same. As
704this is at the heart of the race condition problem, the program
705will die at this point.
706
707=item cannot make directory [dir] read+writeable: [errmsg]
708
709C<rmtree> attempted to change the permissions on the current directory
710to ensure that subsequent unlinkings would not run into problems,
711but was unable to do so. The permissions remain as they were, and
712the program will carry on, doing the best it can.
713
714=item cannot read [dir]: [errmsg]
715
716C<rmtree> tried to read the contents of the directory in order
717to acquire the names of the directory entries to be unlinked, but
718was unsuccessful. This is usually a permissions issue. The
719program will continue, but the files in this directory will remain
720after the call.
721
722=item cannot reset chmod [dir]: [errmsg]
723
cac619e8
DL
724C<rmtree>, after having deleted everything in a directory, attempted
725to restore its permissions to the original state but failed. The
726directory may wind up being left behind.
12c2e016 727
3f083399
NC
728=item cannot remove [dir] when cwd is [dir]
729
730The current working directory of the program is F</some/path/to/here>
731and you are attempting to remove an ancestor, such as F</some/path>.
732The directory tree is left untouched.
733
734The solution is to C<chdir> out of the child directory to a place
735outside the directory tree to be removed.
736
cac619e8 737=item cannot chdir to [parent-dir] from [child-dir]: [errmsg], aborting. (FATAL)
12c2e016 738
cac619e8 739C<rmtree>, after having deleted everything and restored the permissions
3f083399
NC
740of a directory, was unable to chdir back to the parent. The program
741halts to avoid a race condition from occurring.
fed7345c 742
cac619e8 743=item cannot stat prior working directory [dir]: [errmsg], aborting. (FATAL)
0b3d36bd 744
cac619e8
DL
745C<rmtree> was unable to stat the parent directory after have returned
746from the child. Since there is no way of knowing if we returned to
747where we think we should be (by comparing device and inode) the only
748way out is to C<croak>.
0b3d36bd 749
3f083399 750=item previous directory [parent-dir] changed before entering [child-dir], expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)
0b3d36bd 751
cac619e8
DL
752When C<rmtree> returned from deleting files in a child directory, a
753check revealed that the parent directory it returned to wasn't the one
754it started out from. This is considered a sign of malicious activity.
0b3d36bd 755
cac619e8 756=item cannot make directory [dir] writeable: [errmsg]
ee79a11f 757
cac619e8
DL
758Just before removing a directory (after having successfully removed
759everything it contained), C<rmtree> attempted to set the permissions
760on the directory to ensure it could be removed and failed. Program
761execution continues, but the directory may possibly not be deleted.
0b3d36bd 762
cac619e8 763=item cannot remove directory [dir]: [errmsg]
0b3d36bd 764
cac619e8
DL
765C<rmtree> attempted to remove a directory, but failed. This may because
766some objects that were unable to be removed remain in the directory, or
767a permissions issue. The directory will be left behind.
0b3d36bd 768
cac619e8 769=item cannot restore permissions of [dir] to [0nnn]: [errmsg]
0b3d36bd 770
cac619e8
DL
771After having failed to remove a directory, C<rmtree> was unable to
772restore its permissions from a permissive state back to a possibly
773more restrictive setting. (Permissions given in octal).
0b3d36bd 774
cac619e8 775=item cannot make file [file] writeable: [errmsg]
b5400373 776
cac619e8
DL
777C<rmtree> attempted to force the permissions of a file to ensure it
778could be deleted, but failed to do so. It will, however, still attempt
779to unlink the file.
0b3d36bd 780
cac619e8 781=item cannot unlink file [file]: [errmsg]
0b3d36bd 782
cac619e8 783C<rmtree> failed to remove a file. Probably a permissions issue.
0b3d36bd 784
cac619e8 785=item cannot restore permissions of [file] to [0nnn]: [errmsg]
0b3d36bd 786
cac619e8
DL
787After having failed to remove a file, C<rmtree> was also unable
788to restore the permissions on the file to a possibly less permissive
789setting. (Permissions given in octal).
0b3d36bd 790
cac619e8 791=back
12c2e016 792
cac619e8 793=head1 SEE ALSO
037c8c09 794
cac619e8 795=over 4
0b3d36bd 796
cac619e8 797=item *
0b3d36bd 798
351a5cfe
DL
799L<File::Remove>
800
801Allows files and directories to be moved to the Trashcan/Recycle
802Bin (where they may later be restored if necessary) if the operating
803system supports such functionality. This feature may one day be
804made available directly in C<File::Path>.
805
806=item *
807
cac619e8 808L<File::Find::Rule>
0b3d36bd 809
cac619e8
DL
810When removing directory trees, if you want to examine each file to
811decide whether to delete it (and possibly leaving large swathes
812alone), F<File::Find::Rule> offers a convenient and flexible approach
813to examining directory trees.
0b3d36bd 814
cac619e8 815=back
0b3d36bd 816
cac619e8 817=head1 BUGS
0b3d36bd 818
cac619e8 819Please report all bugs on the RT queue:
b5400373 820
cac619e8 821L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=File-Path>
b5400373 822
cac619e8 823=head1 ACKNOWLEDGEMENTS
0b3d36bd 824
cac619e8
DL
825Paul Szabo identified the race condition originally, and Brendan
826O'Dea wrote an implementation for Debian that addressed the problem.
827That code was used as a basis for the current code. Their efforts
828are greatly appreciated.
fed7345c 829
cac619e8 830=head1 AUTHORS
fed7345c 831
3f083399 832Tim Bunce and Charles Bailey. Currently maintained by David Landgren
cac619e8
DL
833<F<david@landgren.net>>.
834
835=head1 COPYRIGHT
836
837This module is copyright (C) Charles Bailey, Tim Bunce and
3f083399 838David Landgren 1995-2008. All rights reserved.
cac619e8
DL
839
840=head1 LICENSE
841
842This library is free software; you can redistribute it and/or modify
843it under the same terms as Perl itself.
844
845=cut