Send signal to a child process
By default, when the exec.Cmd is used, the child process is assigned the main proces group. As a result, it receives signal sent to the main process too.
In a POSIX-conformant operating system, a process group denotes a collection of one or more processes. Among other things, a process group is used to control the distribution of a signal; when a signal is directed to a process group, the signal is delivered to each process that is a member of the group.
We can change that behavior with setpgid syscall:
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pgid: 0,
}
Other option, is to make the child process aware of a OS signal:
_term() {
echo "child: Ignoring signal for 30 sec"
sleep 30
}
trap _term SIGTERM SIGINT
Testing
-
Same group - signal received:
go run system/signal/assets/child-proc-sig.go -new-group # press ctrl-cOutput:
2022/04/03 01:17:45 Main process PID:39465 in group 39442 2022/04/03 01:17:45 Child process PID 39468 in group 39442 Starting child process - sleep 60s ^Cchild: received signal, ignoring it for 30 sec exit status 2As you can see, child process received signal, and decided to ignore it fo 30sec. If the child did not pick up the signal, it would be shut down too.
-
New child group - signal not received:
go run system/signal/assets/child-proc-sig.go # press ctrl-cOutput:
2022/04/03 01:17:56 Main process PID:39537 in group 39515 2022/04/03 01:17:56 Child process PID 39538 in group 39538 Starting child process - sleep 60s ^Cexit status 2As you can see, child process doesn’t receive signal, and it’s still running. It will be even if did not handle OS signals.