Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

"readdir() attempted on invalid dirhandle" error?

by Anonymous Monk
on Jul 10, 2024 at 19:12 UTC ( [id://11160526]=perlquestion: print w/replies, xml ) Need Help??

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

I'm tearing my hair out over what should be a Perl 101 issue, and just can't tell what's going on. I have a script that processes some stuff, and then sends a directory over to a separate module for further processing. The module is unable to read the directory, and I don't know why. The code (so far!) is incredibly simple:
sub process_directory { my ($self, $dir) = @_; print "TESTING: dir is [$dir]\n"; open my $dh, $dir or die "Could not open dir [$dir] for reading: $ +!\n"; my @files = readdir $dh; print "FILES: @files\n"; closedir $dh; }
When I run this, I get:
TESTING: dir is [/tmp/testdirectory] readdir() attempted on invalid dirhandle $dh at /path/to/MyModel.pm li +ne 14. FILES: closedir() attempted on invalid dirhandle $dh at /path/to/MyModel.pm l +ine 18.

/tmp/testdirectory exists, it's a directory, and the caller has permissions to read it.

I'm using strict and warnings. I don't get this--the open didn't fail; what's the problem here? I've searched for this, and the usual error is that people try reading a file as a directory or something like that; that's not the case here.

Replies are listed 'Best First'.
Re: "readdir() attempted on invalid dirhandle" error?
by Paladin (Vicar) on Jul 10, 2024 at 20:05 UTC
    opendir, not open. You are doing the opposite, trying to read a directory as a file.
Re: "readdir() attempted on invalid dirhandle" error?
by NERDVANA (Curate) on Jul 10, 2024 at 20:14 UTC
    Well, in building my reply, I just learned something. Linux lets you open a directory as a file without an error, but then you can't do anything with it.

    Anyway, the answer you're looking for is perldoc -f opendir. This corresponds to the C library opendir/readdir/seekdir/telldir/rewinddir/scandir/closedir family of functions which operate on a DIR* struct, which is very different from a file handle. I think the error message tries to convey that with "dirhandle" language instead of "filehandle".

    Meanwhile, I recommend Path::Tiny or Path::Class is you're doing any significant amount of work with browsing file trees. If you can't use modules, there's also the handy 'glob' function with the convenient built-in syntax of my @files= <$dir/*>; Note that that one returns full relative paths instead of just the file names, which is sometimes more useful (and sometimes not).

      > Linux lets you open a directory as a file without an error, but then you can't do anything with it.

      You can do something.

      open my $d, '<', '..' or die $!; # Doesn't die. say -e $d; # 1. say -d $d; # 1. say -f $d; # Nothing. chdir $d or die $!; # Switches to the parent directory ( +read "perldoc -f chdir").

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        From chdir function ...
        ... chdir FILEHANDLE chdir DIRHANDLE ... On systems that support fchdir(2), you may pass a filehandle or dire +ctory handle as the argument. On systems that don't support fchdir(2) +, passing handles raises an exception.

        ... fchdir(2) ought to be present on POSIX-conforming systems, from "fchdir(2)" manual page of FreeBSD 14 ...

        ... STANDARDS The chdir() system call is expected to conform to IEEE Std 1003.1 +-1990 (“POSIX.1”). HISTORY The chdir() system call appeared in Version 1 AT&T UNIX. The fchdir( +) system call appeared in 4.2BSD.

      Interesting. Also, WTAF!

      Same call -- open my $dh, q[<], q[./] or die $! -- also succeeds on FreeBSD 14.

      Thinking bit more, does not make sense: Should Perl call open(2) with O_DIRECTORY flag -- where available -- so that call will fail if path is not a directory? Apparently it already does not (feel free to correct).

      (OP here) God, I knew it was something stupid and obvious like that! But why on earth would Perl not return an error when opening (not opendiring) a directory? Aargh. Thank you (both) for this. This task doesn't require any fancy tree-walking, the directory will just be a flat folder with files in it, so this is pretty much all I need for this purpose.

        But why on earth would Perl not return an error when opening (not opendiring) a directory?

        As others have shown, there's nothing intrinsically invalid about open on a directory. However I think Perl is definitely capable of giving a more informative error message when you try to use a filehandle in a context that requires a directory handle. I'd recommend opening a github issue tagged as 'Wishlist' suggesting that there's an opportunity for improvement here.

        Update: the issue now exists as #22394.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-09-10 21:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    The PerlMonks site front end has:





    Results (9 votes). Check out past polls.

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.