github.com/benhoyt/goawk@v1.8.1/testdata/gawk/iobug1.awk (about)

     1  # From arnold@f7.net  Fri Nov 26 11:53:12 2004
     2  # X-Envelope-From: james@nocrew.org
     3  # X-Envelope-To: <arnold@skeeve.com>
     4  # To: bug-gawk@gnu.org
     5  # Subject: gawk 3.1.4: reproducible hang, regression from 3.1.3
     6  # From: James Troup <james@nocrew.org>
     7  # Date: Fri, 26 Nov 2004 03:14:05 +0000
     8  # Message-ID: <877jo9qp36.fsf@shiri.gloaming.local>
     9  # User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)
    10  # MIME-Version: 1.0
    11  # Content-Type: text/plain; charset=us-ascii
    12  # 
    13  # 
    14  # Hi,
    15  # 
    16  # A Debian user reported[0] gawk 3.1.4 broke a (relatively) complex
    17  # program that makes extensive use of awk, called 'apt-move'.  I finally
    18  # managed to reduced the problem down to a 3 line test case, enclosed
    19  # below[1].
    20  # 
    21  # I believe the problem comes from the following code, introduced in
    22  # 3.1.4:
    23  # 
    24  # [io.c, line 560]
    25  # | 	for (rp = red_head; rp != NULL; rp = rp->next) {
    26  # | 		if ((rp->flag & RED_EOF) && tree->type == Node_redirect_pipein) {
    27  # | 			if (rp->pid != -1)
    28  # | 				wait_any(0);
    29  # | 		}
    30  # 
    31  # The problem is that, if we have an existing redirect which is a simple
    32  # file redirect[b] and it's hit EOF and we try to create a new '|'
    33  # redirect[c], this new code will try to wait(2) and if there are any
    34  # other redirects which _did_ spawn a child (like [a]) the wait() will
    35  # hang indefinitely waiting for it to exit.
    36  # 
    37  # Hope that makes sense :)
    38  # 
    39  # -- 
    40  # James
    41  # 
    42  # [0] http://bugs.debian.org/263964
    43  # 
    44  # [1] 
    45  # ================================================================================
    46  #!/usr/bin/gawk -f
    47  
    48  BEGIN {
    49  	printf "" | "cat"             # [a]
    50  	getline line < "/dev/null"    # [b]
    51  	"true" | getline line         # [c]
    52  }
    53  # ================================================================================