Why my Linux signal handler has no reaction to the

2019-07-19 07:48发布

问题:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

static void pr_mask(const char * string) {
    sigset_t procmask;

    sigprocmask(SIG_SETMASK, NULL, &procmask);

    printf("%s: ", string);
    if(sigismember(&procmask, SIGINT))
        printf("SIGINT ");
    if(sigismember(&procmask, SIGUSR1))
        printf("SIGUSR1 ");
    if(sigismember(&procmask, SIGUSR2))
        printf("SIGUSR2 ");
    if(sigismember(&procmask, SIGTERM))
        printf("SIGTERM ");
    if(sigismember(&procmask, SIGQUIT))
        printf("SIGQUIT ");
    printf("/n");
}

static void sigusr(int signum)
{
    pr_mask("int sigusr");

    if(signum == SIGUSR1)
        printf("SIGUSR1 received/n");
    else if(signum == SIGUSR2)
        printf("SIGUSR2 received/n");
    else
        printf("signal %d received/n", signum);
}

int main(void)
{
    if(signal(SIGUSR1, sigusr) == SIG_ERR) {
        printf("error catching SIGUSR1/n");
        exit(1);
    }

    if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
        printf("error ignoring SIGUSR2/n");
        exit(1);
    }

    if(signal(SIGINT, SIG_DFL) == SIG_ERR) {
        printf("error setting SIGINT to default/n");
        exit(1);
    }

    while(1)
        pause();

    exit(0);
}

For above code, after compiling it in Linux I start to run it like below.

tomxue@ubuntu:~$ ./a.out &
[2] 5554
[1]   Killed                  ./a.out
tomxue@ubuntu:~$ kill -USR1 5554
tomxue@ubuntu:~$ kill -USR2 5554
tomxue@ubuntu:~$ kill -9 5554
[2]+  Killed                  ./a.out

Why when I issue USR1 and USR2 signal, it has no reaction?

回答1:

As many commented and replied, use \n not /n in a printf format string. Or call fflush(3) e.g. add fflush(NULL); after your printf.

However, calling printf inside a signal handler is wrong. See signal(7) which explains about async-signal-safe functions (printf is not an async-signal-safe function).

In practice, a signal handler should better set some volatile sigatomic_t flag, which should be tested in some important places in your code.

If using some event loop, a trick suggested by Qt is to create some pipe(2) near the beginning of your program, to poll that pipe in your event loop -e.g. by using poll(2), and to write(2) into that pipe (write is async signal safe!) in your signal handler.

See also this answer.



回答2:

You signal handling works fine. It's just that /n is not a new line character. Because you do not print a new line, all the output is kept in a buffer. This buffer is discarded when you kill your process with KILL signal.



标签: c linux signals