2

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.

7
  • 1
    You copied this from a book? What kind of book casts an unused return >_< Commented Jan 18, 2013 at 13:32
  • ... and teaches to call printf() from a signal handler. Commented Jan 18, 2013 at 13:36
  • Can you paste the full output, including the commands you used to build and run this code ? Commented Jan 18, 2013 at 13:37
  • @alk Actually,the book has warned that it is not recommended to use printf in a handler.I just want to try it out. Commented Jan 18, 2013 at 13:38
  • 1
    write is async-signal-safe, so you can use write(STDERR_FILENO, ... in ouch. This is un-buffered and won't interact with the buffered FILE *stdout used by printf. Commented Jan 18, 2013 at 13:43

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

3 Comments

What is the linked "Explanation" going to explain in the context of this question and your answer?
It surely doesn't ... ;-). Anyway this doesn't answer my question. Or what am I missing?
The undefined behavior in this case (linux), means you might end up with interleaved output, and that's about it. It doesn't explain the reported behavior.
1

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.

Comments

0

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.

2 Comments

Shouldn't the \n flush stdout's buffer?
@alk if it were in line buffering mode, which it normally is but may not be depending on how this function was tested. Adding an explicit flush should make it unambiguous.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.