Considering a scenario where a Parent program (could be a C++ program or a Shell Script) executes a Child shell script, when we hit Control+C (or whatever character is configured to be the INTR character) while the Child Shell Script is executing, a SIGINT is sent to all processes in the foreground process group. This includes the parent process.
Source : POSIX.1-2008 XBD section 11.1.9
Is there a way to override this default behavior? That the CHILD Process alone handles the SIGNAL without it propagating to the parent?
Reference : Stack Overflow Post – Parent Process not Completing when Child is Interrupted (TRAP INT)
Best Answer
(Inspired by Gilles's answer)
With the
ISIG
flag set, the only way for theChild
script to getSIGINT
without its parent gettingSIGINT
is for it to be in its own process group. This can be accomplished with theset -m
option.If you turn on the
-m
option in theChild
shell script, it will perform job control without being interactive. This will cause it to run stuff in a separate process group, preventing the parent from receiving theSIGINT
when theINTR
character is read.Here is the POSIX description of the
-m
option:The
-m
option is similar to-i
, but it doesn't alter the shell's behavior nearly as much as-i
does.Example:
the
Parent
script:the
Child
script:This is what happens when you hit Control+C while
Child
is waiting for input:Notice how the parent's
SIGINT
handler is never executed.Alternatively, if you'd rather modify
Parent
instead ofChild
, you can do this:the
Parent
script:the
Child
script (normal; no need for-m
):Alternative ideas
SIGINT
for the duration ofChild
. This doesn't address your question, but it may get you what you want.Child
to:stty -g
to back up the current terminal settings.stty -isig
to not generate signals with theINTR
,QUIT
, andSUSP
characters.kill -QUIT 0
when Control+\ is read,kill -INT $$
when Control+C is read). This is not trivial, and it may not be possible to get this to work smoothly if theChild
script or anything it runs is meant to be interactive.EXIT
).stty -isig
, wait for the user to hit Enter or some other non-special key before killingChild
.Write your own
setpgid
utility in C, Python, Perl, etc. that you can use to callsetpgid()
. Here's a crude C implementation:Example usage from
Child
: