[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 20:15:51 +0200 |
> Date: Thu, 26 Jan 2023 18:52:46 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> CC: help-gawk@gnu.org
>
> I stand corrected: the OP's script does work on GNU/Linux. So I guess
> this is Windows specific. I will try to look at this when I have
> time.
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.
Fixing that boils down to rearranging the code a bit:
--- io.c~0 2022-11-17 17:43:09.000000000 +0200
+++ io.c 2023-01-26 20:08:07.952496100 +0200
@@ -788,6 +788,7 @@ redirect_string(const char *str, size_t
static struct redirect *save_rp = NULL; /* hold onto rp that should
* be freed for reuse
*/
+ int save_errno;
if (do_sandbox)
fatal(_("redirection not allowed in sandbox mode"));
@@ -966,15 +967,18 @@ redirect_string(const char *str, size_t
case redirect_input:
direction = "from";
fd = (extfd >= 0) ? extfd : devopen(str, binmode("r"));
- if (fd == INVALID_HANDLE && errno == EISDIR) {
- *errflg = EISDIR;
- /* do not free rp, saving it for reuse (save_rp
= rp) */
- return NULL;
- }
+ save_errno = errno;
+ /* don't fail before letting registered
+ parsers a chance to take control */
rp->iop = iop_alloc(fd, str, errno);
find_input_parser(rp->iop);
iop_finish(rp->iop);
if (! rp->iop->valid) {
+ if (fd == INVALID_HANDLE && save_errno ==
EISDIR) {
+ *errflg = EISDIR;
+ /* do not free rp, saving it for reuse
(save_rp = rp) */
+ return NULL;
+ }
if (! do_traditional && rp->iop->errcode != 0)
update_ERRNO_int(rp->iop->errcode);
iop_close(rp->iop);
@@ -3422,6 +3426,13 @@ iop_finish(IOBUF *iop)
if (! iop->valid || iop->public.fd == INVALID_HANDLE)
return iop;
+#ifdef __MINGW32__
+ /* If we wind up here, some extension (readdir?) took control
+ of reading directories, so let that extension DTRT and
+ don't bother with the rest of the initializations below. */
+ if (iop->errcode == EISDIR)
+ return iop;
+#endif
if (os_isatty(iop->public.fd))
iop->flag |= IOP_IS_TTY;
- readdir extension on windows with getline, Jim Dailey, 2023/01/25
- Re: readdir extension on windows with getline, Eli Zaretskii, 2023/01/26
- Re: readdir extension on windows with getline, Jim Dailey, 2023/01/26
- Re: readdir extension on windows with getline, Andrew J. Schorr, 2023/01/26
- Re: readdir extension on windows with getline, Andrew J. Schorr, 2023/01/26
- Re: readdir extension on windows with getline, Eli Zaretskii, 2023/01/26
- Re: readdir extension on windows with getline, Eli Zaretskii, 2023/01/26
- Re: readdir extension on windows with getline,
Eli Zaretskii <=
- Re: readdir extension on windows with getline, Andrew J. Schorr, 2023/01/26
- Re: readdir extension on windows with getline, Eli Zaretskii, 2023/01/26
- Re: readdir extension on windows with getline, Andrew J. Schorr, 2023/01/26
- Re: readdir extension on windows with getline, Eli Zaretskii, 2023/01/27
- Re: readdir extension on windows with getline, Jim Dailey, 2023/01/27
- Re: readdir extension on windows with getline, Andrew J. Schorr, 2023/01/26
- Re: readdir extension on windows with getline, Andrew J. Schorr, 2023/01/26