bug-gawk
[Top][All Lists]
Advanced

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

Re: [bug-gawk] system() should return != 0 when the process is killed


From: Stephane Chazelas
Subject: Re: [bug-gawk] system() should return != 0 when the process is killed
Date: Mon, 7 Mar 2016 12:30:20 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

2016-03-06 19:14:51 +0000, Stephane Chazelas:
> 2016-03-05 20:40:50 +0100, Isabella Parakiss:
> [...]
> > Also worth noting, gawk exits with 0 in this case:
> > $ seq 3 | awk '{ print "<" $0 ">"; system("sleep 2") }'
> > <1>
> > ^C<2>
> > ^C<3>
> > ^C
> [...]

I'll try and remember not to post to MLs when tired. A few
corrections below. Sorry about that.

> 
> Note that it's a different discussion. The initial report was
> about the value returned by system() (which with gawk and
> Solaris' /usr/xpg4/bin/awk is 0 when sleep is called by SIGINT),

s/called/killed/

> the OP wasn't questioning the fact that awk wasn't killed upon
> SIGINT.
> 
> POSIX, says the behaviour of awk's system() should be as if
> system(3) was being used. And system(3) is meant to ignore
> SIGINT in the parent.
> 
> Now, the rationale behind system(3) ignoring SIGINT/SIGQUIT is
> that the application would then check the return status (the
> number returned by SIGINT) and take appropriate action (like

number returned by *system(3)*.


> kill itself with SIGINT if the exit status indicates a death by
> SIGINT, if that's what they want to do (like in a
> non-interactive application) or just report an error (think for
> instance vi calling system() for its "!" ex command).
> 
> awk scripts however are generally non-interactive, most current
> implementations don't let you know if the process died of a
> SIGINT/SIGQUIT, and killing yourself with SIGINT is awkward
> (system("kill -s INT \"$PPID\"") wouldn't work as the parent
> ignores SIGINT if using system(3), so you'd need to use the
> pipeline form).
> 
> So, it's not very clear what's the best thing to do here.
> 
> Note that it's a problem encountered by non-interactive shells
> as well and addressed differently in different shells. Some
> shells like bash and ksh93 implement the recommended behaviour
> described at http://www.cons.org/cracauer/sigint.html:
> the "wait and cooperative exit" (WCE) behaviour whereby the calling
> application (the shell, or awk here) blocks SIGINT/SIGQUIT,
> waits for the termination of the child process and if the
> application ignored/handled the SIGINT, carry on as normal, but
> if the child died of SIGINT, then exit by killing oneself with
> SIGINT so as to report to the parent that you died of SIGINT.
> 
> ATM for system(), mawk implements "IUE" (for "immediate
> unconditional exit") and gawk and traditional awk
> implementations would be doing something like WNE (wait
> and never exits). While for close() on a pipeline, all awk
> implementations do IUE.
> 
> For close(), it's not such a problem of exiting unconditionaly
> as if awk exits, even if the child process ignores/handle SIGINT,
> it would either see eof on stdin or get a sigpipe the next time
> it writes some output. 
> 
> Now the gawk system() behaviour may not seem ideal, but it has
> the merit of allowing you do handle the CTRL-C in your awk
> script, by doing something like:
> 
> awk '
>  {
>    ...
>    ret = system("trap \"exit 3\" INT; trap \"exit 4\" QUIT; cmd")
>    signal = ret == 3 ? "INT" : ret == 4 ? "QUIT" : 0
>    if (signal) exit
>    ...
>  }
>  END {
>    if (signal) {
>      cmd = "kill -s " signal " \"$PPID\""
>      cmd | getline
>      close(cmd)
>      exit(255) # not meant to be reached
>    }
>    ...
>  }'
> 
> Now, who's ever going to do that?
> 
> The thing is, that code above is what you'd like to see happen
> by default most of the time. Either that or the WUE (awk
> terminating on CTRL-C even when the system() command handles the
> SIGINT).
> 
> WCE is probably the best compromise for system(). For getline
> pipeline, I suspect implementing WCE would cause more problem
> than help.
[...]

I'll add that WCE works will everything cooperates and remembers
to kill itself with SIGINT in SIGINT handlers if they want to
report that they've been interrupted.

If not, that leads to annoying and frustrating behaviour.

I'm used to shells that implement WUE (zsh) or IUE (dash) (exit
upon SIGINT even if the waited-for application returns with
exit() like ping, svn, mksh...), and find it deeply annoying
when my CTRL-Cs are being ignored by bash scripts.

-- 
Stephane



reply via email to

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