help-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: readdir extension on windows with getline


From: Eli Zaretskii
Subject: Re: readdir extension on windows with getline
Date: Thu, 26 Jan 2023 22:50:19 +0200

> Date: Thu, 26 Jan 2023 15:01:28 -0500
> From: "Andrew J. Schorr" <aschorr@telemetry-investments.com>
> Cc: jim.dailey@alumni.utexas.net, help-gawk@gnu.org
> 
> > I found the reason: the code in redirect_string relies on devopen to
> > succeed when passed a directory name, and only _after_ it succeeds,
> > redirect_string tries to find an input parser.  But on Windows,
> > open'ing a directory always fails, and thus the logic in
> > redirect_string doesn't give a chance to registered parsers to try to
> > take control of reading directories.
> 
> Thanks for chasing this down. Just checking -- did you test this patch?

Yes, of course.

> Maybe
> I'm being stupid, but it looks to me as if the readdir extension needs the
> caller to have succeed in opening a file already that passes the S_ISDIR test.
> I don't see how that can work if you're saying that open fails on a directory
> name.  I'm frankly surprised that it can work with the directory on the 
> command
> line. I must be missing something. There does not appear to be any attempt to
> call opendir until after the readdir extension has succeeded in taking charge
> of the input file; I just don't see how we would ever get there if open(<dir>)
> fails.
> 
> >From extension/readdir.c:
> 
> static awk_bool_t
> dir_can_take_file(const awk_input_buf_t *iobuf)
> {
>         if (iobuf == NULL)
>                 return awk_false;
> 
>         return (iobuf->fd != INVALID_HANDLE && S_ISDIR(iobuf->sbuf.st_mode));
> }
> 
> How can that test succeed?

You assume that iobuf->fd is necessarily INVALID_HANDLE when we get to
dir_can_take_file?  But if we disregard the failure to open and call
iop_alloc anyway, then it does this:

        if (fd != INVALID_HANDLE)
                fstat(fd, & iop->public.sbuf);
#if defined(__MINGW32__)
        else if (errno_val == EISDIR) {
                iop->public.sbuf.st_mode = (_S_IFDIR | _S_IRWXU);
                iop->public.fd = FAKE_FD_VALUE;  <<<<<<<<<<<<<<<<<<<
        }
#endif

And FAKE_FD_VALUE just _happens_ to be the "descriptor" that dirfd in
readdir.c returns, see gawkdirfd.h.

This is why readdir works for the command-line arguments: we don't
try to open the file and bail out immediately when we fail.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]