Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Feb 1998 12:06:49 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, cracauer@cons.org
Cc:        freebsd-current@FreeBSD.ORG
Subject:   Re: cvs commit: src/bin/sh jobs.c
Message-ID:  <199802110106.MAA00738@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> 3. If the shell is waiting (via the wait command) for a background
>>    command, then the wait command shall exit immediately on receipt of
>>    a signal, and then the trap shall be executed.  
>> 
>> Notes.  This is very broken in all versions of sh.  Both the command
>> and the wait builtin seem to ignore all keyboard signals.  It works
>> in bash.
>...
>This is one reason more why I wouldn't like a solution that forces a
>user to trap a signal in a script where he uses a signal-catching
>program like emacs.
>
>i.e.:
>#!/bin/sh
>trap '' 2
>trap '' 3
>emacs -nw
>cleanup
>
>where he can't be sure to get his cleanup done without the traps.

I forgot about this when I removed 'echo -n' from my example for PR1206.
Just do nothing in the trap handler instead of ignoring the signal:

#!/bin/sh
trap 'echo -n' 2
...
emacs -nw
cleanup

>> 4. For subshells, traps caught by the shell shall be set to the default
>>    values and traps ignored by the shell shall be ignored by the command.
>>///
>> Examples (where catchint exits normally when killed by SIGINT):
>> 
>> (a) while :; do catchint; done		# interactive
>> 
>> The shell may be killed by a SIGINT.  To ensure the usual handling, you
>> must use "trap '' SIGINT".  It is not an error for the shell to ignore
>> SIGINT. (?)
>
>Sorry, you lost me. Did you mean "The LOOP my be killed by a
>SIGINT". The interactive shell shouldn't exit, no?

Apparently, it _may_ be killed.  The only relevant point in the spec seems
to be: "An interactive shell may reset or catch signals ignored on entry".
Non-interactive shells cannot trap or reset such signals.

>If you do do
>
>  trap '' 2
>  while :; do catchint; done
>
>You'll get completely runaway behaviour, you can't get rid of this
>loop any way. Even SIGSTOP won't work since it will usually be caught
>by the catchint process.

catchint is only supposed to catch SIGINT.  Other signals _may_ kill
either the shell or catchint.

>> (c) #!/bin/sh
>>     (while :; do catchint; done)
>> 
>> Now there is a subshell.  It must be killed by SIGINT. (?)
>
>For me (our sh and bash), the whole script (outer shell, inner shell,
>catchint) is terminated on SIGINT. It's the way it should be, IMHO.

Actually, it doesn't for your version of sh, or bash.  At least for
your version of sh, the subshell waits for catchint, and then doesn't
exit because catchint exits with a normal status.  Exit on SIGQUIT is
broken (if it is correct :-) even when the the command run by the
subshell gets killed, because the subshell waits for the command and
completely ignores SIGQUIT.  For the original sh, the shells get
killed immediately by SIGINT and catchint exits normally; SIGQUIT
kills everything immediately.

>> (PR1206) /bin/sh -c "trap '' SIGINT; emacs"
>> 
>> The command must be written something like this to ensure ignoring of
>> SIGINT.
>
>Is this your conclusion from this?
>> 4. For subshells, traps caught by the shell shall be set to the default
>>    values and traps ignored by the shell shall be ignored by the command.
>
>What exactly do they mean by "command"? Does sh -c count as subshell?

I abbreviated too much.  The above is part of the specification of a
"shell execution environment".  Subshells give the most important
example of such an environment.  The spec says "utility" instead of
"command" and distinguishes between builtins, shell scripts and other
utilities [being executed in the environment].  The above does not
apply to buitlins.  I think only sourced scripts count here - there
is no way to pass shell traps across exec, even if the exec'ed process
is /bin/sh or what is normally called a "shell script" (an executable
file beginning with #!/bin/sh).  A nearby part of the spec says that
traps must be mapped to signals in the obvious way (ignore -> SIG_IGN,
other -> SIG_DFL) for executing utilities that aren't builtins or scripts.
A subshell is a shell created by `()'.  sh -c is certainly not a subshell.

The main point of the above is that traps are not passed to subshells
unless they are ignored.  This is all consistent with signal handling
across exec (SIG_IGN -> SIG_IGN, other -> SIG_DFL).  Traps could be
passed to subshells, but presumably aren't because this would make
subshells too different from sh -c.

Bruce

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802110106.MAA00738>