sigprocmask не восстанавливает мой обработчик сигнала
У меня проблема с моим кодом C Unix. Я скопирую важные части: поэтому после первой sigprocmask, которую я посылаю сигнал, после SIG_UNBLOCK, не работает предыдущий дескриптор (gestisciSignalDopoReg), вместо этого стандартный дескриптор управляет моим сигналом, поэтому он просто завершает процесс... Что не так? Спасибо
struct sigaction gestoreSegnale;
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask,SIGTERM);
sigaddset(&mask,SIGINT);
sigaddset(&mask,SIGALRM);
sigaddset(&mask,SIGQUIT);
sigaddset(&mask,SIGHUP);
sigaddset(&mask,SIGSEGV);
sigaddset(&mask,SIGILL);
sigaddset(&mask,SIGPIPE);
void setSegnali(int segn,__sighandler_t handler){
gestoreSegnale.sa_handler=handler;
gestoreSegnale.sa_mask=mask;
sigaction(segn, &gestoreSegnale, NULL);
}
void eseguiSetSegnali(__sighandler_t handler){
setSegnali(SIGQUIT, handler);
setSegnali(SIGSEGV, handler);
setSegnali(SIGILL, handler);
setSegnali(SIGHUP, handler);
setSegnali(SIGTERM, handler);
setSegnali(SIGINT, handler);
}
void main(){
eseguiSetSegnali(gestisciSIGNALDopoReg);
sigprocmask(SIG_BLOCK,&mask,NULL);
.........other part of code.........
sigprocmask(SIG_UNBLOCK,&mask,NULL);
}
пожалуйста! Мне нужна помощь!
1 ответ
Вы не инициализируете sa_flags
поле вашего struct sigaction
, так что он может содержать значения мусора. Возможно, что SA_RESETHAND
бит установлен, который согласно man-странице даст вам такое поведение:
SA_RESETHAND Restore the signal action to the default state once the signal handler has been called. This flag is only meaningful when establishing a signal handler. SA_ONESHOT is an obsolete, non-standard synonym for this flag.
Если ваш обработчик сигнала запустился один раз, это привело бы к его очистке и возврату к значению по умолчанию, поэтому вам может понадобиться просто обнулить флаги, например:
void setSegnali(int segn,__sighandler_t handler){
gestoreSegnale.sa_handler=handler;
gestoreSegnale.sa_mask=mask;
/* Make sure to clear flags */
gestoreSegnale.sa_flags=0;
sigaction(segn, &gestoreSegnale, NULL);
}
Во всяком случае, работает следующий маленький пример:
#include <signal.h>
#include <stdio.h>
void handler(int sig) {
printf("HUP %d\n", sig);
}
void main(){
struct sigaction act;
/* Block SIGHUP while the signal handler is running */
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,SIGHUP);
/* Define handler for signal */
act.sa_handler = handler;
/* Clear flags */
act.sa_flags = 0;
act.sa_restorer = NULL;
/* Install handler for SIGHUP */
sigaction(SIGHUP, &act, NULL);
/* Set mask to block SIGHUP */
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGHUP);
/* Block SIGHUP */
printf("Blocking SIGHUP\n");
sigprocmask(SIG_BLOCK,&mask,NULL);
printf("Sleeping\n");
sleep(60);
/* Unblock SIGHUP */
printf("Unblocking SIGHUP\n");
sigprocmask(SIG_UNBLOCK,&mask,NULL);
printf("Sleeping again\n");
while(1)
sleep(60);
}
Если запустить, вы увидите желаемый результат:
$ ./sigtest
Blocking SIGHUP
Sleeping <-- SIGHUP sent from another terminal here but blocked
Unblocking SIGHUP
HUP 1 <-- Signal sent earlier now delivered and handled
Sleeping again
HUP 1 <-- Further signals sent are all handled
HUP 1
HUP 1
^C