From fc22b3d6507c6745911b9dfcc68f1e665ae13dbc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 21:43:11 +0200 Subject: Adding upstream version 4.22.0. Signed-off-by: Daniel Baumann --- upstream/archlinux/man3/File::Path.3perl | 697 +++++++++++++++++++++++++++++++ 1 file changed, 697 insertions(+) create mode 100644 upstream/archlinux/man3/File::Path.3perl (limited to 'upstream/archlinux/man3/File::Path.3perl') diff --git a/upstream/archlinux/man3/File::Path.3perl b/upstream/archlinux/man3/File::Path.3perl new file mode 100644 index 00000000..e4a78b0f --- /dev/null +++ b/upstream/archlinux/man3/File::Path.3perl @@ -0,0 +1,697 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. +.ie n \{\ +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" ======================================================================== +.\" +.IX Title "File::Path 3perl" +.TH File::Path 3perl 2024-02-11 "perl v5.38.2" "Perl Programmers Reference Guide" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH NAME +File::Path \- Create or remove directory trees +.SH VERSION +.IX Header "VERSION" +2.18 \- released November 4 2020. +.SH SYNOPSIS +.IX Header "SYNOPSIS" +.Vb 1 +\& use File::Path qw(make_path remove_tree); +\& +\& @created = make_path(\*(Aqfoo/bar/baz\*(Aq, \*(Aq/zug/zwang\*(Aq); +\& @created = make_path(\*(Aqfoo/bar/baz\*(Aq, \*(Aq/zug/zwang\*(Aq, { +\& verbose => 1, +\& mode => 0711, +\& }); +\& make_path(\*(Aqfoo/bar/baz\*(Aq, \*(Aq/zug/zwang\*(Aq, { +\& chmod => 0777, +\& }); +\& +\& $removed_count = remove_tree(\*(Aqfoo/bar/baz\*(Aq, \*(Aq/zug/zwang\*(Aq, { +\& verbose => 1, +\& error => \emy $err_list, +\& safe => 1, +\& }); +\& +\& # legacy (interface promoted before v2.00) +\& @created = mkpath(\*(Aq/foo/bar/baz\*(Aq); +\& @created = mkpath(\*(Aq/foo/bar/baz\*(Aq, 1, 0711); +\& @created = mkpath([\*(Aq/foo/bar/baz\*(Aq, \*(Aqblurfl/quux\*(Aq], 1, 0711); +\& $removed_count = rmtree(\*(Aqfoo/bar/baz\*(Aq, 1, 1); +\& $removed_count = rmtree([\*(Aqfoo/bar/baz\*(Aq, \*(Aqblurfl/quux\*(Aq], 1, 1); +\& +\& # legacy (interface promoted before v2.06) +\& @created = mkpath(\*(Aqfoo/bar/baz\*(Aq, \*(Aq/zug/zwang\*(Aq, { verbose => 1, mode => 0711 }); +\& $removed_count = rmtree(\*(Aqfoo/bar/baz\*(Aq, \*(Aq/zug/zwang\*(Aq, { verbose => 1, mode => 0711 }); +.Ve +.SH DESCRIPTION +.IX Header "DESCRIPTION" +This module provides a convenient way to create directories of +arbitrary depth and to delete an entire directory subtree from the +filesystem. +.PP +The following functions are provided: +.ie n .IP "make_path( $dir1, $dir2, .... )" 4 +.el .IP "make_path( \f(CW$dir1\fR, \f(CW$dir2\fR, .... )" 4 +.IX Item "make_path( $dir1, $dir2, .... )" +.PD 0 +.ie n .IP "make_path( $dir1, $dir2, ...., \e%opts )" 4 +.el .IP "make_path( \f(CW$dir1\fR, \f(CW$dir2\fR, ...., \e%opts )" 4 +.IX Item "make_path( $dir1, $dir2, ...., %opts )" +.PD +The \f(CW\*(C`make_path\*(C'\fR function creates the given directories if they don't +exist before, much like the Unix command \f(CW\*(C`mkdir \-p\*(C'\fR. +.Sp +The function accepts a list of directories to be created. Its +behaviour may be tuned by an optional hashref appearing as the last +parameter on the call. +.Sp +The function returns the list of directories actually created during +the call; in scalar context the number of directories created. +.Sp +The following keys are recognised in the option hash: +.RS 4 +.ie n .IP "mode => $num" 4 +.el .IP "mode => \f(CW$num\fR" 4 +.IX Item "mode => $num" +The numeric permissions mode to apply to each created directory +(defaults to \f(CW0777\fR), to be modified by the current \f(CW\*(C`umask\*(C'\fR. If the +directory already exists (and thus does not need to be created), +the permissions will not be modified. +.Sp +\&\f(CW\*(C`mask\*(C'\fR is recognised as an alias for this parameter. +.ie n .IP "chmod => $num" 4 +.el .IP "chmod => \f(CW$num\fR" 4 +.IX Item "chmod => $num" +Takes a numeric mode to apply to each created directory (not +modified by the current \f(CW\*(C`umask\*(C'\fR). If the directory already exists +(and thus does not need to be created), the permissions will +not be modified. +.ie n .IP "verbose => $bool" 4 +.el .IP "verbose => \f(CW$bool\fR" 4 +.IX Item "verbose => $bool" +If present, will cause \f(CW\*(C`make_path\*(C'\fR to print the name of each directory +as it is created. By default nothing is printed. +.IP "error => \e$err" 4 +.IX Item "error => $err" +If present, it should be a reference to a scalar. +This scalar will be made to reference an array, which will +be used to store any errors that are encountered. See the "ERROR +HANDLING" section for more information. +.Sp +If this parameter is not used, certain error conditions may raise +a fatal error that will cause the program to halt, unless trapped +in an \f(CW\*(C`eval\*(C'\fR block. +.ie n .IP "owner => $owner" 4 +.el .IP "owner => \f(CW$owner\fR" 4 +.IX Item "owner => $owner" +.PD 0 +.ie n .IP "user => $owner" 4 +.el .IP "user => \f(CW$owner\fR" 4 +.IX Item "user => $owner" +.ie n .IP "uid => $owner" 4 +.el .IP "uid => \f(CW$owner\fR" 4 +.IX Item "uid => $owner" +.PD +If present, will cause any created directory to be owned by \f(CW$owner\fR. +If the value is numeric, it will be interpreted as a uid; otherwise a +username is assumed. An error will be issued if the username cannot be +mapped to a uid, the uid does not exist or the process lacks the +privileges to change ownership. +.Sp +Ownership of directories that already exist will not be changed. +.Sp +\&\f(CW\*(C`user\*(C'\fR and \f(CW\*(C`uid\*(C'\fR are aliases of \f(CW\*(C`owner\*(C'\fR. +.ie n .IP "group => $group" 4 +.el .IP "group => \f(CW$group\fR" 4 +.IX Item "group => $group" +If present, will cause any created directory to be owned by the group +\&\f(CW$group\fR. If the value is numeric, it will be interpreted as a gid; +otherwise a group name is assumed. An error will be issued if the +group name cannot be mapped to a gid, the gid does not exist or the +process lacks the privileges to change group ownership. +.Sp +Group ownership of directories that already exist will not be changed. +.Sp +.Vb 1 +\& make_path \*(Aq/var/tmp/webcache\*(Aq, {owner=>\*(Aqnobody\*(Aq, group=>\*(Aqnogroup\*(Aq}; +.Ve +.RE +.RS 4 +.RE +.ie n .IP "mkpath( $dir )" 4 +.el .IP "mkpath( \f(CW$dir\fR )" 4 +.IX Item "mkpath( $dir )" +.PD 0 +.ie n .IP "mkpath( $dir, $verbose, $mode )" 4 +.el .IP "mkpath( \f(CW$dir\fR, \f(CW$verbose\fR, \f(CW$mode\fR )" 4 +.IX Item "mkpath( $dir, $verbose, $mode )" +.ie n .IP "mkpath( [$dir1, $dir2,...], $verbose, $mode )" 4 +.el .IP "mkpath( [$dir1, \f(CW$dir2\fR,...], \f(CW$verbose\fR, \f(CW$mode\fR )" 4 +.IX Item "mkpath( [$dir1, $dir2,...], $verbose, $mode )" +.ie n .IP "mkpath( $dir1, $dir2,..., \e%opt )" 4 +.el .IP "mkpath( \f(CW$dir1\fR, \f(CW$dir2\fR,..., \e%opt )" 4 +.IX Item "mkpath( $dir1, $dir2,..., %opt )" +.PD +The \f(CWmkpath()\fR function provide the legacy interface of +\&\f(CWmake_path()\fR with a different interpretation of the arguments +passed. The behaviour and return value of the function is otherwise +identical to \f(CWmake_path()\fR. +.ie n .IP "remove_tree( $dir1, $dir2, .... )" 4 +.el .IP "remove_tree( \f(CW$dir1\fR, \f(CW$dir2\fR, .... )" 4 +.IX Item "remove_tree( $dir1, $dir2, .... )" +.PD 0 +.ie n .IP "remove_tree( $dir1, $dir2, ...., \e%opts )" 4 +.el .IP "remove_tree( \f(CW$dir1\fR, \f(CW$dir2\fR, ...., \e%opts )" 4 +.IX Item "remove_tree( $dir1, $dir2, ...., %opts )" +.PD +The \f(CW\*(C`remove_tree\*(C'\fR function deletes the given directories and any +files and subdirectories they might contain, much like the Unix +command \f(CW\*(C`rm \-rf\*(C'\fR or the Windows commands \f(CW\*(C`rmdir /s\*(C'\fR and \f(CW\*(C`rd /s\*(C'\fR. +.Sp +The function accepts a list of directories to be removed. (In point of fact, +it will also accept filesystem entries which are not directories, such as +regular files and symlinks. But, as its name suggests, its intent is to +remove trees rather than individual files.) +.Sp +\&\f(CWremove_tree()\fR's behaviour may be tuned by an optional hashref +appearing as the last parameter on the call. If an empty string is +passed to \f(CW\*(C`remove_tree\*(C'\fR, an error will occur. +.Sp +\&\fBNOTE:\fR For security reasons, we strongly advise use of the +hashref-as-final-argument syntax \-\- specifically, with a setting of the \f(CW\*(C`safe\*(C'\fR +element to a true value. +.Sp +.Vb 6 +\& remove_tree( $dir1, $dir2, ...., +\& { +\& safe => 1, +\& ... # other key\-value pairs +\& }, +\& ); +.Ve +.Sp +The function returns the number of files successfully deleted. +.Sp +The following keys are recognised in the option hash: +.RS 4 +.ie n .IP "verbose => $bool" 4 +.el .IP "verbose => \f(CW$bool\fR" 4 +.IX Item "verbose => $bool" +If present, will cause \f(CW\*(C`remove_tree\*(C'\fR to print the name of each file as +it is unlinked. By default nothing is printed. +.ie n .IP "safe => $bool" 4 +.el .IP "safe => \f(CW$bool\fR" 4 +.IX Item "safe => $bool" +When set to a true value, will cause \f(CW\*(C`remove_tree\*(C'\fR to skip the files +for which the process lacks the required privileges needed to delete +files, such as delete privileges on VMS. In other words, the code +will make no attempt to alter file permissions. Thus, if the process +is interrupted, no filesystem object will be left in a more +permissive mode. +.ie n .IP "keep_root => $bool" 4 +.el .IP "keep_root => \f(CW$bool\fR" 4 +.IX Item "keep_root => $bool" +When set to a true value, will cause all files and subdirectories +to be removed, except the initially specified directories. This comes +in handy when cleaning out an application's scratch directory. +.Sp +.Vb 1 +\& remove_tree( \*(Aq/tmp\*(Aq, {keep_root => 1} ); +.Ve +.IP "result => \e$res" 4 +.IX Item "result => $res" +If present, it should be a reference to a scalar. +This scalar will be made to reference an array, which will +be used to store all files and directories unlinked +during the call. If nothing is unlinked, the array will be empty. +.Sp +.Vb 2 +\& remove_tree( \*(Aq/tmp\*(Aq, {result => \emy $list} ); +\& print "unlinked $_\en" for @$list; +.Ve +.Sp +This is a useful alternative to the \f(CW\*(C`verbose\*(C'\fR key. +.IP "error => \e$err" 4 +.IX Item "error => $err" +If present, it should be a reference to a scalar. +This scalar will be made to reference an array, which will +be used to store any errors that are encountered. See the "ERROR +HANDLING" section for more information. +.Sp +Removing things is a much more dangerous proposition than +creating things. As such, there are certain conditions that +\&\f(CW\*(C`remove_tree\*(C'\fR may encounter that are so dangerous that the only +sane action left is to kill the program. +.Sp +Use \f(CW\*(C`error\*(C'\fR to trap all that is reasonable (problems with +permissions and the like), and let it die if things get out +of hand. This is the safest course of action. +.RE +.RS 4 +.RE +.ie n .IP "rmtree( $dir )" 4 +.el .IP "rmtree( \f(CW$dir\fR )" 4 +.IX Item "rmtree( $dir )" +.PD 0 +.ie n .IP "rmtree( $dir, $verbose, $safe )" 4 +.el .IP "rmtree( \f(CW$dir\fR, \f(CW$verbose\fR, \f(CW$safe\fR )" 4 +.IX Item "rmtree( $dir, $verbose, $safe )" +.ie n .IP "rmtree( [$dir1, $dir2,...], $verbose, $safe )" 4 +.el .IP "rmtree( [$dir1, \f(CW$dir2\fR,...], \f(CW$verbose\fR, \f(CW$safe\fR )" 4 +.IX Item "rmtree( [$dir1, $dir2,...], $verbose, $safe )" +.ie n .IP "rmtree( $dir1, $dir2,..., \e%opt )" 4 +.el .IP "rmtree( \f(CW$dir1\fR, \f(CW$dir2\fR,..., \e%opt )" 4 +.IX Item "rmtree( $dir1, $dir2,..., %opt )" +.PD +The \f(CWrmtree()\fR function provide the legacy interface of +\&\f(CWremove_tree()\fR with a different interpretation of the arguments +passed. The behaviour and return value of the function is otherwise +identical to \f(CWremove_tree()\fR. +.Sp +\&\fBNOTE:\fR For security reasons, we strongly advise use of the +hashref-as-final-argument syntax, specifically with a setting of the \f(CW\*(C`safe\*(C'\fR +element to a true value. +.Sp +.Vb 6 +\& rmtree( $dir1, $dir2, ...., +\& { +\& safe => 1, +\& ... # other key\-value pairs +\& }, +\& ); +.Ve +.SS "ERROR HANDLING" +.IX Subsection "ERROR HANDLING" +.IP \fBNOTE:\fR 4 +.IX Item "NOTE:" +The following error handling mechanism is consistent throughout all +code paths EXCEPT in cases where the ROOT node is nonexistent. In +version 2.11 the maintainers attempted to rectify this inconsistency +but too many downstream modules encountered problems. In such case, +if you require root node evaluation or error checking prior to calling +\&\f(CW\*(C`make_path\*(C'\fR or \f(CW\*(C`remove_tree\*(C'\fR, you should take additional precautions. +.PP +If \f(CW\*(C`make_path\*(C'\fR or \f(CW\*(C`remove_tree\*(C'\fR encounters an error, a diagnostic +message will be printed to \f(CW\*(C`STDERR\*(C'\fR via \f(CW\*(C`carp\*(C'\fR (for non-fatal +errors) or via \f(CW\*(C`croak\*(C'\fR (for fatal errors). +.PP +If this behaviour is not desirable, the \f(CW\*(C`error\*(C'\fR attribute may be +used to hold a reference to a variable, which will be used to store +the diagnostics. The variable is made a reference to an array of hash +references. Each hash contain a single key/value pair where the key +is the name of the file, and the value is the error message (including +the contents of \f(CW$!\fR when appropriate). If a general error is +encountered the diagnostic key will be empty. +.PP +An example usage looks like: +.PP +.Vb 10 +\& remove_tree( \*(Aqfoo/bar\*(Aq, \*(Aqbar/rat\*(Aq, {error => \emy $err} ); +\& if ($err && @$err) { +\& for my $diag (@$err) { +\& my ($file, $message) = %$diag; +\& if ($file eq \*(Aq\*(Aq) { +\& print "general error: $message\en"; +\& } +\& else { +\& print "problem unlinking $file: $message\en"; +\& } +\& } +\& } +\& else { +\& print "No error encountered\en"; +\& } +.Ve +.PP +Note that if no errors are encountered, \f(CW$err\fR will reference an +empty array. This means that \f(CW$err\fR will always end up TRUE; so you +need to test \f(CW@$err\fR to determine if errors occurred. +.SS NOTES +.IX Subsection "NOTES" +\&\f(CW\*(C`File::Path\*(C'\fR blindly exports \f(CW\*(C`mkpath\*(C'\fR and \f(CW\*(C`rmtree\*(C'\fR into the +current namespace. These days, this is considered bad style, but +to change it now would break too much code. Nonetheless, you are +invited to specify what it is you are expecting to use: +.PP +.Vb 1 +\& use File::Path \*(Aqrmtree\*(Aq; +.Ve +.PP +The routines \f(CW\*(C`make_path\*(C'\fR and \f(CW\*(C`remove_tree\*(C'\fR are \fBnot\fR exported +by default. You must specify which ones you want to use. +.PP +.Vb 1 +\& use File::Path \*(Aqremove_tree\*(Aq; +.Ve +.PP +Note that a side-effect of the above is that \f(CW\*(C`mkpath\*(C'\fR and \f(CW\*(C`rmtree\*(C'\fR +are no longer exported at all. This is due to the way the \f(CW\*(C`Exporter\*(C'\fR +module works. If you are migrating a codebase to use the new +interface, you will have to list everything explicitly. But that's +just good practice anyway. +.PP +.Vb 1 +\& use File::Path qw(remove_tree rmtree); +.Ve +.PP +\fIAPI CHANGES\fR +.IX Subsection "API CHANGES" +.PP +The API was changed in the 2.0 branch. For a time, \f(CW\*(C`mkpath\*(C'\fR and +\&\f(CW\*(C`rmtree\*(C'\fR tried, unsuccessfully, to deal with the two different +calling mechanisms. This approach was considered a failure. +.PP +The new semantics are now only available with \f(CW\*(C`make_path\*(C'\fR and +\&\f(CW\*(C`remove_tree\*(C'\fR. The old semantics are only available through +\&\f(CW\*(C`mkpath\*(C'\fR and \f(CW\*(C`rmtree\*(C'\fR. Users are strongly encouraged to upgrade +to at least 2.08 in order to avoid surprises. +.PP +\fISECURITY CONSIDERATIONS\fR +.IX Subsection "SECURITY CONSIDERATIONS" +.PP +There were race conditions in the 1.x implementations of File::Path's +\&\f(CW\*(C`rmtree\*(C'\fR function (although sometimes patched depending on the OS +distribution or platform). The 2.0 version contains code to avoid the +problem mentioned in CVE\-2002\-0435. +.PP +See the following pages for more information: +.PP +.Vb 3 +\& http://bugs.debian.org/cgi\-bin/bugreport.cgi?bug=286905 +\& http://www.nntp.perl.org/group/perl.perl5.porters/2005/01/msg97623.html +\& http://www.debian.org/security/2005/dsa\-696 +.Ve +.PP +Additionally, unless the \f(CW\*(C`safe\*(C'\fR parameter is set (or the +third parameter in the traditional interface is TRUE), should a +\&\f(CW\*(C`remove_tree\*(C'\fR be interrupted, files that were originally in read-only +mode may now have their permissions set to a read-write (or "delete +OK") mode. +.PP +The following CVE reports were previously filed against File-Path and are +believed to have been addressed: +.IP \(bu 4 + +.IP \(bu 4 + +.PP +In February 2017 the cPanel Security Team reported an additional vulnerability +in File-Path. The \f(CWchmod()\fR logic to make directories traversable can be +abused to set the mode on an attacker-chosen file to an attacker-chosen value. +This is due to the time-of-check-to-time-of-use (TOCTTOU) race condition +() between the +\&\f(CWstat()\fR that decides the inode is a directory and the \f(CWchmod()\fR that tries +to make it user-rwx. CPAN versions 2.13 and later incorporate a patch +provided by John Lightsey to address this problem. This vulnerability has +been reported as CVE\-2017\-6512. +.SH DIAGNOSTICS +.IX Header "DIAGNOSTICS" +FATAL errors will cause the program to halt (\f(CW\*(C`croak\*(C'\fR), since the +problem is so severe that it would be dangerous to continue. (This +can always be trapped with \f(CW\*(C`eval\*(C'\fR, but it's not a good idea. Under +the circumstances, dying is the best thing to do). +.PP +SEVERE errors may be trapped using the modern interface. If the +they are not trapped, or if the old interface is used, such an error +will cause the program will halt. +.PP +All other errors may be trapped using the modern interface, otherwise +they will be \f(CW\*(C`carp\*(C'\fRed about. Program execution will not be halted. +.IP "mkdir [path]: [errmsg] (SEVERE)" 4 +.IX Item "mkdir [path]: [errmsg] (SEVERE)" +\&\f(CW\*(C`make_path\*(C'\fR was unable to create the path. Probably some sort of +permissions error at the point of departure or insufficient resources +(such as free inodes on Unix). +.IP "No root path(s) specified" 4 +.IX Item "No root path(s) specified" +\&\f(CW\*(C`make_path\*(C'\fR was not given any paths to create. This message is only +emitted if the routine is called with the traditional interface. +The modern interface will remain silent if given nothing to do. +.IP "No such file or directory" 4 +.IX Item "No such file or directory" +On Windows, if \f(CW\*(C`make_path\*(C'\fR gives you this warning, it may mean that +you have exceeded your filesystem's maximum path length. +.IP "cannot fetch initial working directory: [errmsg]" 4 +.IX Item "cannot fetch initial working directory: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR attempted to determine the initial directory by calling +\&\f(CW\*(C`Cwd::getcwd\*(C'\fR, but the call failed for some reason. No attempt +will be made to delete anything. +.IP "cannot stat initial working directory: [errmsg]" 4 +.IX Item "cannot stat initial working directory: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR attempted to stat the initial directory (after having +successfully obtained its name via \f(CW\*(C`getcwd\*(C'\fR), however, the call +failed for some reason. No attempt will be made to delete anything. +.IP "cannot chdir to [dir]: [errmsg]" 4 +.IX Item "cannot chdir to [dir]: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR attempted to set the working directory in order to +begin deleting the objects therein, but was unsuccessful. This is +usually a permissions issue. The routine will continue to delete +other things, but this directory will be left intact. +.IP "directory [dir] changed before chdir, expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)" 4 +.IX Item "directory [dir] changed before chdir, expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)" +\&\f(CW\*(C`remove_tree\*(C'\fR recorded the device and inode of a directory, and then +moved into it. It then performed a \f(CW\*(C`stat\*(C'\fR on the current directory +and detected that the device and inode were no longer the same. As +this is at the heart of the race condition problem, the program +will die at this point. +.IP "cannot make directory [dir] read+writeable: [errmsg]" 4 +.IX Item "cannot make directory [dir] read+writeable: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR attempted to change the permissions on the current directory +to ensure that subsequent unlinkings would not run into problems, +but was unable to do so. The permissions remain as they were, and +the program will carry on, doing the best it can. +.IP "cannot read [dir]: [errmsg]" 4 +.IX Item "cannot read [dir]: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR tried to read the contents of the directory in order +to acquire the names of the directory entries to be unlinked, but +was unsuccessful. This is usually a permissions issue. The +program will continue, but the files in this directory will remain +after the call. +.IP "cannot reset chmod [dir]: [errmsg]" 4 +.IX Item "cannot reset chmod [dir]: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR, after having deleted everything in a directory, attempted +to restore its permissions to the original state but failed. The +directory may wind up being left behind. +.IP "cannot remove [dir] when cwd is [dir]" 4 +.IX Item "cannot remove [dir] when cwd is [dir]" +The current working directory of the program is \fI/some/path/to/here\fR +and you are attempting to remove an ancestor, such as \fI/some/path\fR. +The directory tree is left untouched. +.Sp +The solution is to \f(CW\*(C`chdir\*(C'\fR out of the child directory to a place +outside the directory tree to be removed. +.IP "cannot chdir to [parent\-dir] from [child\-dir]: [errmsg], aborting. (FATAL)" 4 +.IX Item "cannot chdir to [parent-dir] from [child-dir]: [errmsg], aborting. (FATAL)" +\&\f(CW\*(C`remove_tree\*(C'\fR, after having deleted everything and restored the permissions +of a directory, was unable to chdir back to the parent. The program +halts to avoid a race condition from occurring. +.IP "cannot stat prior working directory [dir]: [errmsg], aborting. (FATAL)" 4 +.IX Item "cannot stat prior working directory [dir]: [errmsg], aborting. (FATAL)" +\&\f(CW\*(C`remove_tree\*(C'\fR was unable to stat the parent directory after having returned +from the child. Since there is no way of knowing if we returned to +where we think we should be (by comparing device and inode) the only +way out is to \f(CW\*(C`croak\*(C'\fR. +.IP "previous directory [parent\-dir] changed before entering [child\-dir], expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)" 4 +.IX Item "previous directory [parent-dir] changed before entering [child-dir], expected dev=[n] ino=[n], actual dev=[n] ino=[n], aborting. (FATAL)" +When \f(CW\*(C`remove_tree\*(C'\fR returned from deleting files in a child directory, a +check revealed that the parent directory it returned to wasn't the one +it started out from. This is considered a sign of malicious activity. +.IP "cannot make directory [dir] writeable: [errmsg]" 4 +.IX Item "cannot make directory [dir] writeable: [errmsg]" +Just before removing a directory (after having successfully removed +everything it contained), \f(CW\*(C`remove_tree\*(C'\fR attempted to set the permissions +on the directory to ensure it could be removed and failed. Program +execution continues, but the directory may possibly not be deleted. +.IP "cannot remove directory [dir]: [errmsg]" 4 +.IX Item "cannot remove directory [dir]: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR attempted to remove a directory, but failed. This may be because +some objects that were unable to be removed remain in the directory, or +it could be a permissions issue. The directory will be left behind. +.IP "cannot restore permissions of [dir] to [0nnn]: [errmsg]" 4 +.IX Item "cannot restore permissions of [dir] to [0nnn]: [errmsg]" +After having failed to remove a directory, \f(CW\*(C`remove_tree\*(C'\fR was unable to +restore its permissions from a permissive state back to a possibly +more restrictive setting. (Permissions given in octal). +.IP "cannot make file [file] writeable: [errmsg]" 4 +.IX Item "cannot make file [file] writeable: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR attempted to force the permissions of a file to ensure it +could be deleted, but failed to do so. It will, however, still attempt +to unlink the file. +.IP "cannot unlink file [file]: [errmsg]" 4 +.IX Item "cannot unlink file [file]: [errmsg]" +\&\f(CW\*(C`remove_tree\*(C'\fR failed to remove a file. Probably a permissions issue. +.IP "cannot restore permissions of [file] to [0nnn]: [errmsg]" 4 +.IX Item "cannot restore permissions of [file] to [0nnn]: [errmsg]" +After having failed to remove a file, \f(CW\*(C`remove_tree\*(C'\fR was also unable +to restore the permissions on the file to a possibly less permissive +setting. (Permissions given in octal). +.IP "unable to map [owner] to a uid, ownership not changed"");" 4 +.IX Item "unable to map [owner] to a uid, ownership not changed"");" +\&\f(CW\*(C`make_path\*(C'\fR was instructed to give the ownership of created +directories to the symbolic name [owner], but \f(CW\*(C`getpwnam\*(C'\fR did +not return the corresponding numeric uid. The directory will +be created, but ownership will not be changed. +.IP "unable to map [group] to a gid, group ownership not changed" 4 +.IX Item "unable to map [group] to a gid, group ownership not changed" +\&\f(CW\*(C`make_path\*(C'\fR was instructed to give the group ownership of created +directories to the symbolic name [group], but \f(CW\*(C`getgrnam\*(C'\fR did +not return the corresponding numeric gid. The directory will +be created, but group ownership will not be changed. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +.IP \(bu 4 +File::Remove +.Sp +Allows files and directories to be moved to the Trashcan/Recycle +Bin (where they may later be restored if necessary) if the operating +system supports such functionality. This feature may one day be +made available directly in \f(CW\*(C`File::Path\*(C'\fR. +.IP \(bu 4 +File::Find::Rule +.Sp +When removing directory trees, if you want to examine each file to +decide whether to delete it (and possibly leaving large swathes +alone), \fIFile::Find::Rule\fR offers a convenient and flexible approach +to examining directory trees. +.SH "BUGS AND LIMITATIONS" +.IX Header "BUGS AND LIMITATIONS" +The following describes \fIFile::Path\fR limitations and how to report bugs. +.SS "MULTITHREADED APPLICATIONS" +.IX Subsection "MULTITHREADED APPLICATIONS" +\&\fIFile::Path\fR \f(CW\*(C`rmtree\*(C'\fR and \f(CW\*(C`remove_tree\*(C'\fR will not work with +multithreaded applications due to its use of \f(CW\*(C`chdir\*(C'\fR. At this time, +no warning or error is generated in this situation. You will +certainly encounter unexpected results. +.PP +The implementation that surfaces this limitation will not be changed. See the +\&\fIFile::Path::Tiny\fR module for functionality similar to \fIFile::Path\fR but which does +not \f(CW\*(C`chdir\*(C'\fR. +.SS "NFS Mount Points" +.IX Subsection "NFS Mount Points" +\&\fIFile::Path\fR is not responsible for triggering the automounts, mirror mounts, +and the contents of network mounted filesystems. If your NFS implementation +requires an action to be performed on the filesystem in order for +\&\fIFile::Path\fR to perform operations, it is strongly suggested you assure +filesystem availability by reading the root of the mounted filesystem. +.SS "REPORTING BUGS" +.IX Subsection "REPORTING BUGS" +Please report all bugs on the RT queue, either via the web interface: +.PP + +.PP +or by email: +.PP +.Vb 1 +\& bug\-File\-Path@rt.cpan.org +.Ve +.PP +In either case, please \fBattach\fR patches to the bug report rather than +including them inline in the web post or the body of the email. +.PP +You can also send pull requests to the Github repository: +.PP + +.SH ACKNOWLEDGEMENTS +.IX Header "ACKNOWLEDGEMENTS" +Paul Szabo identified the race condition originally, and Brendan +O'Dea wrote an implementation for Debian that addressed the problem. +That code was used as a basis for the current code. Their efforts +are greatly appreciated. +.PP +Gisle Aas made a number of improvements to the documentation for +2.07 and his advice and assistance is also greatly appreciated. +.SH AUTHORS +.IX Header "AUTHORS" +Prior authors and maintainers: Tim Bunce, Charles Bailey, and +David Landgren <\fIdavid@landgren.net\fR>. +.PP +Current maintainers are Richard Elberger <\fIriche@cpan.org\fR> and +James (Jim) Keenan <\fIjkeenan@cpan.org\fR>. +.SH CONTRIBUTORS +.IX Header "CONTRIBUTORS" +Contributors to File::Path, in alphabetical order by first name. +.IP <\fIbulkdd@cpan.org\fR> 1 +.IX Item "" +.PD 0 +.IP "Charlie Gonzalez <\fIitcharlie@cpan.org\fR>" 1 +.IX Item "Charlie Gonzalez " +.IP "Craig A. Berry <\fIcraigberry@mac.com\fR>" 1 +.IX Item "Craig A. Berry " +.IP "James E Keenan <\fIjkeenan@cpan.org\fR>" 1 +.IX Item "James E Keenan " +.IP "John Lightsey <\fIjohn@perlsec.org\fR>" 1 +.IX Item "John Lightsey " +.IP "Nigel Horne <\fInjh@bandsman.co.uk\fR>" 1 +.IX Item "Nigel Horne " +.IP "Richard Elberger <\fIriche@cpan.org\fR>" 1 +.IX Item "Richard Elberger " +.IP "Ryan Yee <\fIryee@cpan.org\fR>" 1 +.IX Item "Ryan Yee " +.IP "Skye Shaw <\fIshaw@cpan.org\fR>" 1 +.IX Item "Skye Shaw " +.IP "Tom Lutz <\fItommylutz@gmail.com\fR>" 1 +.IX Item "Tom Lutz " +.IP "Will Sheppard <\fIwillsheppard@github\fR>" 1 +.IX Item "Will Sheppard " +.PD +.SH COPYRIGHT +.IX Header "COPYRIGHT" +This module is copyright (C) Charles Bailey, Tim Bunce, David Landgren, +James Keenan and Richard Elberger 1995\-2020. All rights reserved. +.SH LICENSE +.IX Header "LICENSE" +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. -- cgit v1.2.3