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