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