Signal issue when enter Ctrl+C

2019-07-17 11:25发布

问题:

I am a newbie in Linux programming.I copied the code below from a book:

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

void ouch (int sig)
{
    printf("OUCH! - I got signal %d\n", sig);
    (void) signal(SIGINT, SIG_DFL);
}

int main ()
{
    (void) signal(SIGINT, ouch);

    while(1)
    {
        printf("Hello World!\n");
        sleep(1);
    }

}

It was expected to print something when Ctrl+C was entered.But it do nothing but print Hello World!.


EDIT: I am so sorry that I have binded the Ctrl+C as a short-cut key for copy. Sorry for trouble caused.

回答1:

My Suggestion is don't use printf in siginal handler (ouch), it may be undefined behavior. Async-signal-safe functions: The list of safe functions that can be call in signal handler man page.

It is not safe to call all functions, such as printf, from within a signal handler. A useful technique is to use a signal handler to set a flag and then check that flag from the main program and print a message if required.

Reference: Beginning Linux Programming, 4th Edition,In this book exactly your code is explained, Chapter 11: Processes and Signals, page 484

An additional helpful link:
Explanation: Use reentrant functions for safer signal handling



回答2:

Sorry, I can't see a question here... but I can guess what you are interested in.

printf() is a stateful function, thus not reentrant. It uses a FILE structure (variable name is 'stdin') to keep it's state. (It is like calling fprintf(stdin,format,...)).

That means, dependant on implementation and 'luck', calling printf() from a signal handler may print what you expect, but also may print nothing or may even crash or worse, smash your memory! Anything could happen.

So, just don't call functions from within a signal handler that are not explicitely marked 'signal-safe'. You will avoid lot's of headaches in the long term.



回答3:

Put an fflush(stdout) in your signal handler. It was just buffered, then the second SIGINT exited the program before the buffer could be flushed.



标签: c linux signals