At 7:17 PM -0500 9/11/07, John E. Malmberg wrote: >David Landgren wrote: >>John E. Malmberg wrote:
> >>>not ok 23 - removed directory (old style 2) >>># Failed test 'removed directory (old style 2)' >>># at [-.lib.file]path.t line 105. >>># got: '0' >>># expected: '1' Oops, forgot about the obvious one in my patch. >>>What is happening is that it is checking the permission of a directory using >>>VMS::Filespec::candelete($root) and discovering that it does not have delete >>>permission, so is skipping it. Normally directories on VMS are created with >>>out delete permission granted. >> >>And the code will only escalate privileges to attempt the delete if the >>client code has explicitly switched off the 'safe' attribute. Otherwise if >>the code is interrupted by any external means, filesystem objects may be left >>in a more permissive state than they were previously. >> >>>Previously it had verified that it had write permission, so did not do a >>>chmod() on it to add write permission. >>> >>>Unfortunately on VMS if you want to add delete permission using chmod(), the >>>way to do it is to explicitly add write permission. >> >>Hang on, you've lost me. It verifies that it had write permission... but you >>have to chmod anyway to raise the permissions sufficiently? Actually I don't think it does verify it has write permission; it just assumes it has it because it created the directory. >VMS has a separate delete permission. If you use chmod() to set UNIX >write permission, as a side effect it also sets the delete permission if >it is not already set. > >With out the candelete() code, you can not tell from the UNIX syscalls >if the delete bit is or is not set. And when you create a directory, by >default the delete bit is not set. Right. When you create a directory, the default behavior on both VMS and UNIX is that you have write access. On UNIX, that also implies delete access (though you may also need write access to the parent directory?). On VMS, you don't get delete access to a directory by default, even though you may have delete access to all the files in it. The expectation is that you would always have to explicitly change protection before being able to delete a directory. So rmtree()'s safe mode, where you don't try to delete anything that would require changing protection to do so, runs smack against that expectation. As it is now, the only thing the test verifies is that you can delete a directory you've created without having to change the protection on it, which depends on whatever local expectations are about directory permissions. Ideally there would instead be two tests, one where you create a directory where you don't have whatever access you need to delete it (even if that's not the default) and verify that attempting rmtree() on it under safe mode leaves it there. The other would be adding whatever access you need to delete it, and only then verifying rmtree() can actually delete it. Another thing John said that is quite true but non-intuitive enough to bear further explanation is how to get delete access on VMS with chmod(). Since chmod() knows nothing about the delete bit on VMS, you can't refer to it explicitly. However, when calling chmod() on VMS, setting the write bit is automagically copied to the delete bit. Which leads to the counterintuitive situation of having write access without delete access and the only way to get delete access is to give yourself the write access you already have. Or not use chmod(), which is after all a foreign API. I'm mildly curious (but not enough to do the research) on how this is or could be handled on NTFS under Windows, where you also have delete access separate from write. Most likely the default access is more wide open than on VMS, so the same scenarios could occur, but don't by default. >>>So really the VMS::Filespec::candelete test needs to be done where code is >>>decided if to call chmod() to add write privilege or not. >> >>I see what you mean... I think. I'll try to come up with some pseudo-code >>tonight and post that. One thing that I don't like is how the code unixifies >>at the top and ends up filifying at the end. Seems to me I should just have >>two variables $entry_as_dir and $entry_as_file that are the same on all >>OS'es, but special-cased on VMS. Good point. It's not entirely clear to me just reading through it why that unixify is there or whether we really need it anymore. >Ideally all unixifies should be removed if possible from every bit of >code. They can not translate all possible VMS filespecifications to >UNIX, so will make some files invisible. Well, it might've been nice if 5.10 were the place to make that break, but we're not ready, so that's really a red herring here. For the case of Unicode in filenames, there are a lot of changes needed all over the place. >>I think I shall not escape the need to dust off my testdrive account and go >>and play with this on VMS. Bless you for making the effort. Schwern, Nicholas, and a few others have done so on occasion, but it is rare. >>>Also, on the special case to handle '.' returned by readdir() on VMS, it >>>will always be the first file or $file[0] if it exists, so there is no need >>>to look through the entire array for it. Unless you are anticipating >>>something changing the way that readdir() on VMS may be implemented. >> >>No. Just being paranoid. On the other hand, the '.' -> '.;' remapping could >>be deferred to take place later on, rather than in the slightly obfuscatory >>C<map {...} readdir>. >> >>Since it's all recursive, this just means the top of the foreach $root loop >>of _rmtree() becomes: >> >> if ($Is_MacOS) { >> $root = ":$root" unless $root =~ /:/; >> $root .= ":" unless $root =~ /:\z/; >> } >>+ elsif ($Is_VMS) { >>+ $root = ".;" if $root eq '.'; >>+ } >> else { >> $root =~ s{/\z}{}; >> } >> >>This pleases me greatly, because it puts it the make-work code in one place, >>instead of having it scattered through the routine. Which is the type of >>simplification I'm striving for. > >Carefull, even though readdir() will only return "." when it means ".;", > it is very likely that updir() may return "." instead of "[]" in the >future for VMS. A Hopefully not as long as $^O eq 'VMS' is true. We probably need something more radically different to handle higher levels of UNIX emulation. Remind me to study the differences between the Cygwin port and the Win32 port. -- ________________________________________ Craig A. Berry mailto:[EMAIL PROTECTED] "... getting out of a sonnet is much more difficult than getting in." Brad Leithauser