0

I have SIGINT handler. It sets variable for whole program: errflag. When I do select() and it's interrupted via SIGINT, I check errflag to see if it's SIGINT (have own constant assigned to errflag). However, the handler can be late and errflag isn't yet set. How to defer processing before handler's resolution on errflag? Or how to implement this correctly?

Also, in one code path select() returns -1 on Ctrl-C, errno is EINTR. Here handler is never late. In other path select() returns -1, errno is also EINTR, but handler outputs log message little later and is late, my errflag checks are already performed.

Itzie
  • 65
  • 5
  • As pointed out in the first answer, an interrupt stops the current processing and runs the handler and, if the handler returns, either restarts the system call or interrrupts it with `errno` set to `EINTR`. Are you using `signal()` or `sigaction()`? Without your code, it is going to be hard to see what's going wrong, but your interpretation that the signal handler can be 'deferred' is basically wrong. With `sigaction()`, you can block one signal while another signal is being handled `sa_mask`, but the blocked signal will be delivered when the first handler returns. – Jonathan Leffler Oct 02 '16 at 17:57
  • @JonathanLeffler: yes you are right, the signal is manually deferred by a queue mechanism, and handler early returns, had not debug print before that and interpreted the from-queue call as the first, late, call. – Itzie Oct 02 '16 at 18:08
  • So, you had had a signal handler with two or more exit routes, and one had a diagnostic print in place and the other didn't? Easily done — but also something to watch for. It can lead to serious misinterpretation of the results. One of the (few) merits of 'single entry, single exit' programming is that you don't run into that problem! – Jonathan Leffler Oct 02 '16 at 18:11

1 Answers1

4

However, the handler can be late and errflag isn't yet set.

Er, what? No, it can't be "late". Something else is wrong here.

Signal handlers interrupt normal program flow -- when SIGINT is received, your handler runs, and control flow is only released to the rest of your program when the signal handler exits.

What you do need to make sure of is that errflag is declared as volatile, so that the compiler will not make undue assumptions about when its value can change.

What you also need to keep in mind is that printf() is not safe to use in signal handlers, as it may use global buffers which can be left in an inconsistent state during signal handling. Generally speaking, very few things are safe to do during a signal handler besides setting volatile global variables or exiting. Trying to use printf() in a signal handler may result in inconsistent, confusing results; the output should not be used as a reliable indicator of what actually happened in your program!

Community
  • 1
  • 1
  • Thanks, I've verified and the handler is called instantly, there is only a queueing mechanism and the signal is somehow fired again from the queue later. I had debug message later, after the possible queuing, and didn't see the instant on-signal handler call. – Itzie Oct 02 '16 at 17:54