develooper Front page | perl.perl5.porters | Postings from May 2008

RE: File::Path::mkpath() incompatiblity in perl-5.10

Thread Previous | Thread Next
Jan Dubois
May 30, 2008 15:39
RE: File::Path::mkpath() incompatiblity in perl-5.10
Message ID:
On Fri, 30 May 2008, David Landgren wrote:
> Jan Dubois wrote:
> > On Thu, 15 May 2008, David Landgren wrote:
> >> There are two other issues I am addressing, the fact that (stat $foo)[1]
> >> (the inode) always returns 0 on Windows (and thus prevents UNC paths
> >> from being removed), and asking to remove the current directory (or
> >> ancestor), for which the code now croaks when it tries to chdir back to
> >> the original directory at the end of the run, and it's been blown away.
> >>
> >> The solution to the first can be solved if Win32::IdentifyFile is available.
> >
> > Note that all the information returned by Win32::IdentifyFile is already
> > available inside our win32_stat() function (unless you set
> > $^WIN32_SLOPPY_STAT to a true value).  So we could cheaply create a fake
> > inode from it.
> C:\temp>perl -e "$^WIN32_SLOPPY_STAT=1"
> Bareword found where operator expected at -e line 1, near
>          (Missing operator before IN32_SLOPPY_STAT?)
> syntax error at -e line 1, near "$^WIN32_SLOPPY_STAT"
> Execution of -e aborted due to compilation errors.
> Oh hang on, I don't have AS Perl on this machine, only Strawberry.

This is a core Perl feature; nothing ActivePerl or StrawberryPerl specific.
You just have to write it as ${^WIN32_SLOPPY_STAT} because '^' is not a
word character.  Note that the file index information is not available
at the Perl level, only at the C level inside win32_stat().  I was only
trying to say that we could fake up our own inode in there if we wanted to.
> > The problem is that the file id can be up to 64 bits (of which only 48
> > are used on NTFS I think, but it is up to the file system driver to
> > implement this), and st_ino is only 16 bits in the standard "struct
> > stat" as defined by MSVCRT.dll. A trivial way to fake an inode would be
> > to just xor the 64 bit file id in 16 bit chunks to fold it, but of
> > course you cannot avoid collisions this way. One advantage of this is
> > that it could be integrated into 5.10 and 5.8 if we wanted to.

I did some experiments with this, and surprisingly noticed that I get
the least number of collisions if I just use the lowest 16 bits of the
file index instead of xor-ing it together (on NTFS).  Maybe there is
some redundancy in the file index, and the xor is therefore canceling
out relevant information.

But I don't think having an inode field with collisions is very useful,
so I don't think we should bother with this approach.

> > Another approach might be to redefine Stat_t to our own definition and
> > use 64 bits for the inode inside Perl.  I'm not sure if this would be
> > a problem for XS code, or for integration into 5.10.

Haven't found time to think about this some more yet.

> > Just for my information, how does the inode field prevent UNC paths from
> > being removed and doesn't affect other paths?
> Getting back to working on this again.
> Actually, it's worse than I thought. The approach doesn't work on local
> drives either. Consider:
> cd \temp # or any non-root directory
> C:\temp>perl -le "$,=' ';print +(stat '.')[0,1];print +(stat '..')[0,1]"
> 2 0
> 2 0
> I would expect the inode value to change. I'm sort of surprised no-one's
> commented on this before.

The inode field is *always* 0 under MSWin32 AFAIK.  Documented in perlport.pod:

|          device and inode are not meaningful. (Win32)

That's why I was wondering how things are different for UNC paths.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About