bug-gawk
[Top][All Lists]
Advanced

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

Re: [bug-gawk] Gawk 4.0.0 Redirection Bug


From: Eli Zaretskii
Subject: Re: [bug-gawk] Gawk 4.0.0 Redirection Bug
Date: Fri, 30 Sep 2011 14:26:12 +0300

> Date: Sun, 25 Sep 2011 19:38:58 -0700 (PDT)
> From: David Millis <address@hidden>
> 
> # Exhausting stdin seems to break redirection in general.
> 
> # echo hello|gawk -f redirect.txt
> # ... fatal: print to "tmp.txt" failed (reason unknown)
> 
> BEGIN {
>   while ((getline tmpLine < "/dev/stdin") > 0);
>   print "hi" > "tmp.txt";
>   close("tmp.txt");
> }
> 
> # 4.0.0 (Windows, http://www.klabaster.com/freeware.htm#dl) has the issue.
> # 4.0.0 (Debian) is fine.
> # 3.1.6 (GnuWin32) was fine.

This happens because Gawk 4.0.0 introduced non-portable code in the
new function remap_std_file, that has no chance of working on any
non-Posix platform that doesn't emulate /dev/null in its C library.

The patch to fix this (relative to stock 4.0.0) is below.

Btw, I think the code of this function, even after the patch, is still
dangerously wrong, in that it closes oldfd right away.  The code
obviously assumes that nothing can go wrong with opening /dev/null.
But if something does go wrong, the effect is that we forcibly close
Gawk's standard input, which will cause the next file to be opened on
file descriptor of zero, and all hell will break lose on it.  IOW, the
exact problem that pre-4.0.0 Gawk was trying to avoid by not closing
the standard handles to begin with.  This will definitely bite some
platform that doesn't support /dev/null, but can also happen on Posix
platforms, I think, at least under some extreme conditions, like
shortage of available file handles.

I therefore think we should restructure the code of this function so
that oldfd is closed only as a side effect of calling `dup2'.


2011-09-30  Eli Zaretskii  <address@hidden>

        * io.c (remap_std_file): Fix non-portable code that caused
        redirected "print" to fail if a previous read from standard input
        returned EOF.  Reported by David Millis <address@hidden>.


--- io.c~0      2011-05-19 00:47:29.000000000 +0300
+++ io.c        2011-09-30 14:10:00.031250000 +0300
@@ -449,9 +449,14 @@ remap_std_file(int oldfd)
        int ret = -1;
 
        close(oldfd);
-       newfd = open("/dev/null", O_RDWR);
+       /*
+        * Give OS-specific routines in gawkmisc.c chance to interpret
+        * "/dev/null" as appropriate for their platforms.
+        */
+       newfd = os_devopen("/dev/null", O_RDWR);
+       if (newfd == INVALID_HANDLE)
+               newfd = open("/dev/null", O_RDWR);
        if (newfd >= 0 && newfd != oldfd) {
-               /* dup2() will close oldfd for us first. */
                ret = dup2(newfd, oldfd);
                if (ret == 0)
                        close(newfd);



reply via email to

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