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!
signature.asc
Description: Digital signature