A NOTE has been added to this issue. ====================================================================== http://austingroupbugs.net/view.php?id=1212 ====================================================================== Reported By: kre Assigned To: ====================================================================== Project: 1003.1(2016)/Issue7+TC2 Issue ID: 1212 Category: Shell and Utilities Type: Enhancement Request Severity: Objection Priority: normal Status: New Name: Robert Elz Organization: User Reference: Section: XCU 2.14 -- trap special builtin Page Number: 2420 - 2423 Line Number: 77484-5 (and more) Interp Status: --- Final Accepted Text: ====================================================================== Date Submitted: 2018-09-28 02:56 UTC Last Modified: 2019-04-06 07:54 UTC ====================================================================== Summary: Enhance trap command ======================================================================
---------------------------------------------------------------------- (0004357) kre (reporter) - 2019-04-06 07:54 http://austingroupbugs.net/view.php?id=1212#c4357 ---------------------------------------------------------------------- Re http://austingroupbugs.net/view.php?id=1212#c4356 No, certainly nothing is needed as a special case for signals which default to ignored - those are not the same state in any case - explicitly ignoring a signal is a different state from simply doing nothing, which results in the signal being ignored (perhaps a subtle difference, but a difference nevertheless). I wouldn't use SIGCHLD as an example of that however, as while the effect on signal delivery of an ignored (SIG_IGN) SIGCHLD is the same as for SIGCHLD in its default state (SIG_DFL) being ignored can have other ramifications for the application. This does however raise two other interesting questions. First should the trap command (some enhanced trap command as proposed here) report a signal that was ignored upon entry to the shell as being ignored, or simply as being in its default state? I have no particular insightful answer to that one, and either would be reasonable. My gut tells me that the purpose of the command is to discover what earlier manipulations have been made in the script, so a function (or dot script, or whatever) can return the world to its entry state before finishing. If that's the case the signals ignored on entry (which the shell cannot manipulate anyway) would be irrelevant. However having those signals explicitly listed as ignored would not harm that usage, and would allow the script to discover that no matter how much it wants to receive a SIGxxx it cannot, because its parent invoked it with that signal ignored, and hence the script needs to either fail, or use some other method to handle whatever it needed the signal for (if it was just for synchronisation between its sub-shells, then it might simply pick a different signal to use). My implementation of this currently lists signals that were ignored on entry as being in the default state (or actually, whatever state the script attempted to set the signal into - whether or not that was actually effective) - but that could easily be changed if the overall opinion is that that would be better. This also raises an additional sub-issue of whether or not there should be some method to allow a script to trap a signal that was ignored on entry if it really needs to do that. C programs can do it, I see no particular reason why scripts should not have the option .. the only reason that I can see that it isn't done now, is that typical program behaviour used to be if (signal(SIGxxx, SIG_IGN) != SIG_IGN) signal(SIGxxx, xxx_trap); so that a signal which was ignored would stay that way (that's usually what is wanted) and as sh provided no method to do the test explicitly, so only provided that mechanism. But as it was always OK to restore the signal to its entry state (no test like above is done then) sh always explicitly tests the invocation signal state, as it has no other way to know whether a trap command is establishing a new trap or resetting to the earlier state. If we had the testing method, and an option to not do the test, but simply override an existing SIG_IGN (not previously set by the script) I don't see that it would do any harm - the current trap command would need to continue acting the way it always has of course. The second new issue mentioned above is more specific to SIGCHLD (though could also apply to other signals). If a script does trap '' SIGCHLD and the shell from that actually does signal(SIGCHLD, SIG_IGN) then the shell is not likely to work very well (certainly on some systems). So, the question is, is the shell obliged to actually do what the script instructs, or can it merely act as if it had done that (in this case, by not delivering any SIGCHLD traps to the script). Or on systems where it works this way, is it required that "trap '' SIGCHLD" cause the shell to lose the ability to wait() on any of its children, thus making $? useless for anything not built in? And a corollary to that, if a script does do "trap '' SIGCHLD" the shell then invoke sub-processes (other commands) with SIGCHLD ignored (which most do not expect, and sometimes cannot handle) and in particular if that invoked sub-process is a subshell - either a subshell environment of the current shell, or more relevantly here, "/bin/sh -c 'command || other'" - that sub-process would be invoked with SIGCHLD ignored, and if it is a shell, is it permitted to either set SIGCHLD back to SIG_DFL, or catch the signal (depending upon its needs) or must it comply with the restriction that signals ignored upon entry remain ignored throughout the script? FWIW: the NetBSD shell silently ignores attempts by scripts to manipulate SIGCHLD (or should, but I don't remember if I actually committed that change). Everything appears to the script as if SIGCHLD were trapped/ignored, but no signal() sys call is ever made to affect the kernel when the script does that. It is my intention (not yet implemented) to copy the bash mechanism for this (maybe itself copied from elsewhere) to a degree - and implement script level SIGCHLD traps independent of (and more reliably than) kernel delivered SIGCHLD signals - so that one SIGCHLD trap (in the script) is taken for every asynchronous pipeline (command) that completes (not for every command that completes the way bash implements this - that does not seem to be very useful). In the trap handler $! would be redefined to be the pid of the async job that caused this invocation of the trap handler (so, for example: "wait $!" in the trap handler would clean up the job, and set $? to its status). I believe this is safe, as the trap could fire anywhere in the script, so its handler cannot reasonably be depending upon $! being the pid of any particular last async job started ... unless of course there was only one, in which case, it would be). None of this mechanism is relevant to the standard (certainly not yet) but the question of exactly what the shell is permitted/required to do with signals when implementing the trap command is. Issue History Date Modified Username Field Change ====================================================================== 2018-09-28 02:56 kre New Issue 2018-09-28 02:56 kre Name => Robert Elz 2018-09-28 02:56 kre Section => XCU 2.14 -- trap special builtin 2018-09-28 02:56 kre Page Number => 2420 - 2423 2018-09-28 02:56 kre Line Number => 77484-5 (and more) 2019-04-04 17:35 shware_systems Note Added: 0004356 2019-04-06 07:54 kre Note Added: 0004357 ======================================================================