Hi. As this Bug is now lying around for more than one month I decided to
look into a fix. It is not a very beautiful one, it is only partially
tested and it only works for systems which can fork, so please look over it
before applying it.

The idea is to fork off a process, change into the directory, make sure the
directory has the same inode which was originally used, and then change
permissions. fchmod would have been much easier.

A diff follows:

-- snip --
--- Path.pm     2005-02-08 13:23:10.000000000 +0100
+++ Path.pm.new 2005-02-08 17:13:04.000000000 +0100
@@ -189,7 +189,7 @@
        } else {
            $root =~ s#/\z##;
        }
-       (undef, undef, my $rp) = lstat $root or next;
+       (undef, my $ino, my $rp) = lstat $root or next;
        $rp &= 07777;   # don't forget setuid, setgid, sticky bits
        if ( -d _ ) {
            # notabene: 0700 is for making readable in the first place,
@@ -239,9 +239,25 @@
            }
            else {
                carp "Can't remove directory $root: $!";
-               chmod($rp, ($Is_VMS ? VMS::Filespec::fileify($root) : $root))
+               # this avoids a race condition which would occur if someone
+               # replaced $root while we were working on it. I would have
+               # preferred to use fchmod, but this seems not to be
+               # supported in perl. -- AW
+               my($fork)=fork;
+               if ($fork<0) {carp("and cannot fork: $!");}
+               elsif ($fork>0) { # parent
+                 waitpid($fork,0);
+               } else { # child
+                 chdir($root) or carp("and cannot change to $root: $!");
+                 (undef,my($rino))=lstat(".");
+                 $rino==$ino or carp(
+                   "and someone replaced $root while I was working on it\n");
+                 $rino==$ino
+                   and chmod($rp,($Is_VMS ? VMS::Filespec::fileify(".") : "."))
                    or carp("and can't restore permissions to "
                            . sprintf("0%o",$rp) . "\n");
+                 exit(0);
+               }
            }
        }
        else { 
-- snip --

I hope this helps.

cu

AW
-- 
<ThePhonk> *tueteKlammernUeberVariableAuskipp* Dereferenzier Dich, Du
+Miststueck!

Attachment: signature.asc
Description: Digital signature

Reply via email to