Вы недовольны тем фактом, что пытаетесь рекурсивно обработать сигнал.
При использовании signal()
для регистрации обработчика сигнала этот номер сигнала блокируется до тех пор, пока не будет возвращен обработчик сигнала - фактически ядро / libc блокирует этот номер сигнала при вызове обработчика сигнала и разблокирует его после возврата обработчика сигнала. , Поскольку вы никогда не возвращаетесь из обработчика сигнала (вместо этого вы execl
новый двоичный файл), SIGUSR1
остается заблокированным и поэтому не перехватывается во второй раз.
Это можно увидеть, изучив /proc/</pid>/status
до и после отправки первого SIGUSR1
.
До:
$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000000
SigCgt: 0000000000000200
После того, как:
$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000200
SigCgt: 0000000000000200
Обратите внимание, что SigCgt
указывает, что сигнал 10 зарегистрирован (число является битовым полем; установлен 10-й бит, что соответствует SIGUSR1, цифры * см. man signal(7)
). SigBlk
пусто до того, как SIGUSR
отправлено вашему процессу, но после отправки сигнала оно содержит SIGUSR1
.
У вас есть два способа решить эту проблему:
а). Вручную разблокируйте SIGUSR
перед вызовом execl
в sighandler
:
sigset_t sigs;
sigprocmask(0, 0, &sigs);
sigdelset(&sigs, SIGUSR1);
sigprocmask(SIG_SETMASK, &sigs);
* +1032 * б). Используйте
sigaction
с флагом
SA_NODEFER
вместо
signal
для регистрации обработчика сигнала. Это предотвратит блокировку
SIGUSR1
внутри обработчика сигнала:
struct sigaction act;
act.sa_handler = signalhandler;
act.sa_mask = 0;
act.sa_flags = SA_NODEFER;
sigaction(SIGUSR1, &act, 0);