1

As I studied something about unix programming with C, I've learned that functions that fails to be reentrant should be avoided inside a signal handler, but if I've something like:

int main(int argc, char** argv){
     ...
    fileFd=open(...) 
    signal(SIGUSR1, signalHandler)
    ...
}


void signalHandler(int signo){
    switch(signo){

    case SIGUSR1:
        myExit(EXIT_FAILURE);   
        break;

    default: 
        break;

    }
}

Where myExit is

void myExit(int ret){

    ...DO STUFF...
    close(fileFd);
    exit(ret);

}

and fileFd is a global variable, and if I remember correctly that makes of myExit a non-reentrant... but it's still a problem to use it in a signal handler even if it will cause the exit of the program ? Thanks, any help is appreciated and sorry if it's a dumb question.

cifz
  • 1,078
  • 7
  • 24
  • It's not about being re-entrant, but about being *async-safe*. Exiting should be fine. – Kerrek SB Sep 10 '12 at 19:08
  • Logically, not. If a program exits, there's no much to worry about after the exit - simply because *there isn't "after the exit"...* –  Sep 10 '12 at 19:09

3 Answers3

4

The only thing you can do safely in a signal handler is to set a volatile sig_atomic_t variable. Please do all your handling in the main loop of your program by checking that a signal has been received (outside of the signal handler). If you do have to start doing non-portable things then consider at least using _Exit() or _exit(). Certain C libraries will guarantee that certain functions are signal-safe but this is not guaranteed to work on different systems obviously.

dmp
  • 439
  • 3
  • 6
0

It might get a problem depending on "...DO STUFF...". If the stuff done there may not be done twice (like freeing the same pointer), it could crash.

In your particular case however this will probably not be a problem, if close(fileFD) is the only thing affecting global state and your file access API allows double-closing of files.

Jost
  • 5,948
  • 8
  • 42
  • 72
  • The UNIX `close` is a tad dangerous -- you cannot safely call it twice with the same fd since the fd might have been reused in the meantime. – nneonneo Sep 10 '12 at 19:13
0

Still not safe if you use any async-unsafe functions. An asynchronous signal like USR1 can occur between any two instructions in your program, including in the middle of a critical section (locked section) in some library code.

So, for example, if the interruption happens in the middle of malloc, calling free in your signal handler (e.g. to clean up) will deadlock.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • 1
    So if I've only async-signal-safe functions (in fact I've only write and close, that are listed in man 7 signal under the async-signal-safe list) I'm ok, right ? – cifz Sep 10 '12 at 19:39