in reply to "readdir() attempted on invalid dirhandle" error?

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).

Replies are listed 'Best First'.
Re^2: "readdir() attempted on invalid dirhandle" error?
by choroba (Cardinal) on Jul 10, 2024 at 21:35 UTC
    > 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.
Re^2: "readdir() attempted on invalid dirhandle" error?
by parv (Parson) on Jul 10, 2024 at 21:12 UTC

    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).

Re^2: "readdir() attempted on invalid dirhandle" error?
by Anonymous Monk on Jul 10, 2024 at 20:39 UTC
    (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.

        File handles and directory handles are stored in different slots of the glob. From Perl's perspective, the problem isn't that the provided handle is the wrong kinda of handle; the problem is that the provided glob didn't contain a dir handle.