clinuxalarmsetjmpsigaction

linux C languang. setjmp longjmp alarm


execute

my code

jmp_buf a;

void sig_handler(int signum) {
        if(signum == SIGINT) exit(0);

        printf("In the handler\n");
        sleep(2);
        alarm(3);
        longjmp(a,1);
}
int main(int argc, char *argv[]) {
    int j=0;
    struct sigaction sa;

    memset(&sa, 0, sizeof(struct sigaction));
    sa.sa_handler = sig_handler;
    sigfillset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);

    alarm(2);
    j = setjmp(a);
    while(1){
       printf("In the main\n");
       pause();
        }
    return 0;
}

I thought the result of this code is

In the main. In the handler. In the main. In the handler. In the main. In the handler. In the main. In the handler. . . .

but It didn't work. The alarm function wasn't set in the handler. when I delete setjmp, longjmp, It works well. But I don't want to delete them. Does setjmp affect setting the alarm function? How to solve this.


Solution

  • The interaction of longjmp and signals is unspecified. Use siglongjmp instead. This code should work:

    #include <stdio.h>
    #include <string.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <setjmp.h>
    
    sigjmp_buf a;
    
    void sig_handler(int signum) {
            if(signum == SIGINT) exit(0);
    
            printf("In the handler\n");
            sleep(2);
            alarm(3);
            siglongjmp(a,1);
    }
    
    int main(int argc, char *argv[])
    {
        int j=0;
        struct sigaction sa;
    
        memset(&sa, 0, sizeof(struct sigaction));
        sa.sa_handler = sig_handler;
        sigfillset(&sa.sa_mask);
        sa.sa_flags = SA_NODEFER;
        sigaction(SIGALRM, &sa, NULL);
    
        alarm(2);
        j = sigsetjmp(a, 1);
        while(1){
           printf("In the main\n");
           pause();
            }
        return 0;
    }