help-bash
[Top][All Lists]
Advanced

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

Re: [Help-bash] too paranoid?


From: Stephane Chazelas
Subject: Re: [Help-bash] too paranoid?
Date: Mon, 14 Mar 2016 04:25:30 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

2016-03-12 20:16:03 -0700, Bob Proulx:
[...]
> > Depending on the version of pdksh/mksh, the "kill" within the
> > trap may not work at all, or if it works, the exit status of the
> > script may be that of the clean-up function.
> 
> Sorry but you have lost me.  Why won't the kill work on these other
> shells?

I was about to offer a guess like the shell ignoring the signal
during its handler, but it turns out it's just kill -s doesn't
work properly in that version I tested on (pdksh 5.2.13), so you
may ignore that part.

Still

mksh -c 'trap : EXIT; trap "trap - INT;kill -s INT $$" INT; sleep 10'

exits with exit code 0, even with -o posix.

[...]
> If the code did actually continue then it is trying to return a signal
> value encoded as 128 plus the signal number.  Sorry but that is
> incorrect.  Worse it will be confusing when observing the return value
> with the shell afterward by looking at $?.  It will appear to be the
> same number due to the way the shell encodes the value for $? and this
> will hide the fact that it isn't returning the correct exit code.
> That is a very bad thing.
[...]
> Sorry but no.  In order to handle signals correctly the process *must*
> kill itself with a signal.  There is no other correct handling.
[...]
> You mentioned mksh and so I tested mksh version 52c on my Debian
> system using #!/bin/mksh.  It does not do exit(128+signum) but returns
> the proper signal.  I don't see any problem.  Which means that mksh is
> resetting the signal handler to the default value properly.
> 
> Perhaps in a different version mksh had problematic behavior?
[...]

Just built from cvs head on Debian:

$ ./mksh -c 'echo $KSH_VERSION'
@(#)MIRBSD KSH R52 2016/03/04
$ strace -e exit_group mksh -c 'kill -s INT $$'
--- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=24833, si_uid=10031} ---
exit_group(130)                         = ?
+++ exited with 130 +++
$ strace -e exit_group ./mksh -c 'kill $$'
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=24839, si_uid=10031} ---
exit_group(143)                         = ?
+++ exited with 143 +++

(I get the same with older versions).

On your code (and mine), the shell would exit with 128+signum
with the Bourne shell or ksh88 (and would with mksh if it
weren't for the exit trap that resets the exit status to 0) so
doing a exit 130 would have had the same effect (at least on
Solaris 10 where I tested this on).

Note that the very reason $? is 128+n (and not 256+n or 65536+n
that would remove the ambiguity) is so that it can be passed in
an exit code.

In all of

sh -ec 'cmd; cmd2'
sh -c 'cmd||exit; cmd2'
sh -c 'if true; then cmd; fi' # except in shells that optimize out the fork
mksh -c 'cmd'

except in ksh93, if cmd is killed, the shell will do an
exit(128+signum). So when doing a system("cmd"), you already
know that to check if cmd was killed by a signal, you need to
check both "status & 63" for the signum if the process was
killed, and code=status>>8, code > 128 && signum = code & 63, if
the shell reports that the command (or itself like in the case
of mksh) was killed.

IOW, exit code 130 is by convention already meant to convey a
death-by-signal2 of a child process.

That's why I say it's marginally useful (when not inneffective
like for Bourne or ksh88 or mksh as mentioned above).

Note that in all those cases above ksh93 will kill itself, with
same signal, possibly generating an  extra core dump (possibly
overwriting the previous one).

In anycase, what matters most here is that the exit status be
non-zero as that's what the caller will likely care about.

For keyboard interrupt signals (SIGINT and SIGQUIT), killing
yourself is desirable on systems that have shells that implement
WCE like bash, as otherwise that would mean that if your script
is called by another bash script, that other bash script
wouldn't be interrupted when you press CTRL-C|\. But again, it's
not always possible.

-- 
Stephane




reply via email to

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