hkjaaaip
hkjaaaip

Reputation: 123

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.

Upvotes: 2

Views: 322

Answers (1)

David Schwartz
David Schwartz

Reputation: 182847

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

Upvotes: 3

Related Questions