Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trap a signal to a process group

Tags:

linux

bash

Is there any way to trap a signal sent to a process group so that any of subprocesses do not get hit by the signal?

My issue is that I've got an app that terminates nicely on SIGTERM but breaks un-cleanly on SIGUSR1 and so I would like to protect it from SIGUSR1. I thought about writing a simple bash script:

#!/bin/bash

runapp &
childspid=$!

trap "kill -TERM $childspid ; exit" USR1

while true ; do
    sleep 10 ;
done

Unfortunately, the killer is cunning and sends SIGUSR1 to the whole process group not just the leader.

Many thanks,

like image 410
Jacek Avatar asked Oct 22 '22 18:10

Jacek


1 Answers

You can set SIGIGN disposition on any app by leveraging a little bit of perl:

perl -e '$SIG{"USR1"} = "IGNORE"; exec(@ARGV)' realprogram realargs...

as long as realprogram does not modify the signals, then it is kept safe from them.

The reason this works is that the signal mask is inherited by child processes automatically, whether they are launched by fork(), exec() or just exec() on it's own.

Note: I had tried this using bash builtins, but the signal handler was restored before the subprocess was executed (GAH!) which is not what I wanted.

No Mask:

natsu:~$ grep SigIgn /proc/$$/status
SigIgn: 0000000000384004

Adding mask:

natsu:~$ trap '' USR1
natsu:~$ grep SigIgn /proc/$$/status
SigIgn: 0000000000384204

Subprocess loses mask :(

natsu:~$ bash
natsu:~$ grep SigIgn /proc/$$/status
SigIgn: 0000000000384004
natsu:~$ kill -USR1 $$
User defined signal 1

Now with perl:

natsu:~$ perl -e '$SIG{"USR1"} = "IGNORE"; exec(@_)' bash
natsu:~$ grep SigIgn /proc/$$/status
SigIgn: 0000000000384204
natsu:~$ kill -USR1 $$
natsu:~$
like image 89
Petesh Avatar answered Oct 24 '22 16:10

Petesh