Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Bugs in File::Find on Windows

by jdporter (Paladin)
on Feb 15, 2007 at 22:28 UTC ( [id://600324]=perlquestion: print w/replies, xml ) Need Help??

jdporter has asked for the wisdom of the Perl Monks concerning the following question:

I just got bitten by a veri nåsti bügg in File::Find on Windows.... It goes like this — stop me if you've heard this one before —

use File::Find; find( \&wanted, "C:" ); my @st = stat "C:bar.txt";
Note: no slashes in either path name.

Further conditions:

  • bar.txt exists in the cwd of the C: drive.
  • File::Find is in chdir mode; that is, no_chdir has not be set.
  • The cwd of C: has subdirectories.
  • (Update)The currently logged drive is something other than C:.
What will happen is, find() will recurse into the subdirectories of the cwd on C:, changing the cwd accordingly; When it's done, the cwd will be the last subdirectory find() entered. That is, your idea of cwd on C: no longer corresponds to reality. Therefore the file, bar.txt, will appear to be missing (the stat will fail).

Does anybody have any ideas on how to get around this? I'd sure like to not have to go discover, and then restore, the cwd of all the drives on the Windows machine.

One possibility that should work is to turn on no_chdir for File::Find... but in fact, this is broken on Windows too! It fails to recurse at all.

This is perl, v5.8.8 built for MSWin32-x86-multi-thread Binary build 819 [267479] provided by ActiveState
Thanks in advance...

A word spoken in Mind will reach its own level, in the objective world, by its own weight

Replies are listed 'Best First'.
Re: Bugs in File::Find on Windows
by Steve_p (Priest) on Feb 15, 2007 at 23:40 UTC

    First, can you please post the wanted() sub? Without it, I can't see if you have a problem or not.

    Second, if you have a wanted() sub, could you please open a perlbug on this?


    Test your modules with bleadperl!

      rsync -avz rsync://public.activestate.com/perl-current/ .
      ./Configure -des -Dusedevel -Dprefix=/path/to/test/perl
      make test
      make install
    

    Now, please test you modules! If you have test failures that don't happen with Perl 5.8.8, send a simplified test case to

    perlbug at perl.org

      can you please post the wanted() sub? Without it, I can't see if you have a problem or not.

      It doesn't matter what the wanted sub is, as long as it doesn't prune so as to prevent any recursions. That is not where the problem is.

      could you please open a perlbug on this?

      That is certainly worth considering.

      Update: bug filed.

      A word spoken in Mind will reach its own level, in the objective world, by its own weight
Re: Bugs in File::Find on Windows
by Anonymous Monk on Feb 16, 2007 at 00:02 UTC
    The obvious workaround (untested) should be:
    use Cwd 'chdir';# Explicitly export Cwd::chdir (will maintain $ENV{PW +D} ) my $dir = getcwd();#exported from Cwd by default use File::Find; find( \&wanted, "C:" ); chdir $dir; my @st = stat "C:bar.txt";
    But you say you don't want to do that. Is &wanted doing any directory traversal itself? If it is, I'd suggest making sure you're using the Cwd version of chdir, else perl may have a hard time keeping track of where it is. -Greg

      Thanks. But that won't solve the problem, because getcwd() only tells you the cwd of the current drive, not of any of the other drives.

        getdcwd('C:');


        ___________
        Eric Hodges
Re: Bugs in File::Find on Windows
by davorg (Chancellor) on Feb 16, 2007 at 08:58 UTC
Re: Bugs in File::Find on Windows
by Anonymous Monk on Feb 16, 2007 at 01:16 UTC
    use getdcwd
Re: Bugs in File::Find on Windows
by pKai (Priest) on Feb 16, 2007 at 23:36 UTC
    One possibility that should work is to turn on no_chdir for File::Find... but in fact, this is broken on Windows too! It fails to recurse at all.

    The following works fine for me:

    use strict; use warnings; use File::Find; find( {no_chdir => 1, wanted => sub { local($\)=$/; print if -d} }, 'E +:/windows');

    i. e. prints all the name (paths) of all the subdirectories below and including my E:/Windows

    In fact, I never liked the idea of changing the current directory inside my programs, so I always used File::Find with no_chdir and have never experienced problems with it.

      You haven't reproduced my failure scenario, which requires that the target directory be a drive letter with no other path info. Try this:

      cd /d e:\windows cd /d c:\ find({ no_chdir => 1, wanted => sub { print if -d } }, 'E:' );

      But I've discovered more about this bug. Try this:

      cd /d c:\ mkdir test\windows\foo cd test cd /d e:\ perl -MFile::Find -e "$\=$/; find( sub { print if -d }, 'c:' );"
      Output is just as you'd expect:
      . windows foo
      But if you run
      perl -MFile::Find -e "$\=$/; find({ no_chdir => 1, wanted => sub { pri +nt if -d } }, 'c:' );"
      you get unexpected (erroneous) output:
      . . . c:/windows/$hf_mig$/KB898461/update c:/windows/$MSI31Uninstall_KB893803$ c:/windows/$MSI31Uninstall_KB893803$/spuninst c:/windows/$NtServicePackUninstall$ c:/windows/$NtServicePackUninstall$/spuninst c:/windows/$NtUninstallKB816486$ . . . c:/windows/ADDINS c:/windows/AppPatch c:/windows/assembly c:/windows/assembly/GAC_32 c:/windows/assembly/GAC_32/CustomMarshalers c:/windows/assembly/GAC_32/CustomMarshalers/2.0.0.0__b03f5f7f11d50a3a . . .

      In other words, if it finds a subdirectory of the target directory named X, it searches under C:\X, even if the target directory is not C:\. It's definitely a bug.

      A word spoken in Mind will reach its own level, in the objective world, by its own weight

        I see now.

        I took your "...broken on Windows too! It fails to recurse at all." as an absolute verdict on no_chdir, rather than as an outcome in your special situation, depending on the current directories on both drives and even the top-level directories of C:.

        Tricky stuff.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://600324]
Approved by shmem
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2024-04-19 22:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found