简体   繁体   中英

sigprocmask doesn't restore my signal handler

I have a problem with my code C Unix. I'll copy crucial parts: So after the first sigprocmask I send a signal, after the SIG_UNBLOCK, doesn't work the previous handle(gestisciSignalDopoReg) instead the standard handle manage my signal, so it simply terminate the process... What's wrong? Thanks

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);
}

please! I need help!

You do not initialize the sa_flags field of your struct sigaction , so it may contain garbage values. It is possible that the SA_RESETHAND bit is set, which according to the man page will give you this behavior:

  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. 

If your signal handler has run once, that would cause it to be cleared and return to the default, so you may just need to zero out the flags like:

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);
}

At any rate, the following little example works:

#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);
}

If run, you see the desired result:

$ ./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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM