Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Why does zsh un-ignores SIGQUIT?



2019-04-24 17:13:51 +0100, Peter Stephenson:
> On Wed, 2019-04-24 at 09:13 +0100, Stephane Chazelas wrote:
> > $ (trap '' QUIT; grep SigIgn /proc/self/status; ./Src/zsh -c 'grep SigIgn /proc/self/status')
> > SigIgn: 0000000000000004
> > SigIgn: 0000000000000000
> > 
> > That only seems to be happening for SIGQUIT.
> > 
> > (that's from the current git HEAD)
> 
> SIGQUIT is ignored internally within the shell, visible below the patched
> code.  The shell knows if you've explicitly ignored SIGQUIT, but not if
> it's ignored by inheritance when the shell starts.  The flag is tested
> in entersubsh().
[...patch skipped...]


Thanks,

that change seems to introduce a new inconsistency though. See
below.

POSIX does require that signals that were ignored upon startup
of the shell remain ignored.

POSIX> Signals that were ignored on entry to a non-interactive
POSIX> shell cannot be trapped or reset, although no error need
POSIX> be reported when attempting to do so. An interactive
POSIX> shell may reset or catch signals ignored on entry.

zsh, thankfully ignores that requirement. That's an annoying
requirement that probably has its origin on systems that didn't
have terminal job control (tcsetpgrp()...) and is usually a
nuisance today.

In zsh

   trap handler INT

Installs the "handler" on SIGINT even if SIGINT was ignored on
startup.

What I found out recently though
(https://unix.stackexchange.com/questions/513781/regain-ability-to-use-c-to-close-backgrounded-then-effectively-foregrounded-p/515159#515159)
is that it does seem to honour the POSIX requirement when it
comes to "resetting" the signal disposition (to its default).

In zsh

   trap - INT

Does not reset the default signal disposition of SIGINT if
SIGINT was ignored upon startup.

$ (trap "" INT; zsh -c 'trap - INT; grep SigIgn /proc/self/status')
SigIgn: 0000000000000002

One can work around that by setting a trap first:

$ (trap "" INT; zsh -c 'trap : INT; trap - INT; grep SigIgn /proc/self/status')
SigIgn: 0000000000000000

Even explicitely ignoring it will do:

$ (trap "" INT; zsh -c 'trap "" INT; trap - INT; grep SigIgn /proc/self/status')
SigIgn: 0000000000000000


Which brings us to this change, which means SIGQUIT is now
treated specially in this regard:

$ (trap "" INT QUIT; ./Src/zsh -c 'trap - INT QUIT; grep SigIgn /proc/self/status')
SigIgn: 0000000000000002

(with the diff applied)

I was able to reset the default handler for SIGQUIT but not for
SIGINT.

I wonder what the rationale is for why zsh will happily install a
handler on an ignored signal but not reset to default.

I can understand where the POSIX requirement is coming from.

When you do

myscript &

on a system that doesn't have job control, you don't want
processes started by the script to be killed when you press ^C.

Or when you do:

nohup myscript

You want myscript and all the processes it spawns to be immune
to hang-ups.

But I don't understand why zsh would let me set a handler but
not reset to default. It would make more sense to me if it was the
reverse. If I want to reset the default handler without having
set one in the first place, surely I know what I'm doing and
what I ask should be honoured.

Here, unless someone can think of a good reason why zsh behaves
the way it does, I'd suggest zsh ignore the POSIX requirement
altogether and honours what the user wants: apply the traps as
requested regardless of whether the signal was ignored on
startup or not, at least in zsh emulation.

Maybe honour the POSIX requirements in sh emulation.

While I'm at it, there's another related POSIX requirement that
I often find annoying:

In non-interactive shells.

cmd &

is meant to run cmd with SIGINT and SIGQUIT ignored (some form
of crude and ancient uncalled for job control).

That's actually more annoying than the other POSIX requirement
mentioned earlier.

When you do:

(cmd1 & cmd2) | cmd3


There's no reason cmd1 should not also be killed by SIGINT when
you press ^C.

That's where being able to cancel that ignoring of SIGINT can
come handy.

zsh does honour that latter requirement though.

What's the sentiment of zsh developer about potentially ignoring
that POSIX requirement as well? What can that break?

-- 
Stephane



Messages sorted by: Reverse Date, Date, Thread, Author