Mends.One

A function that use global variable but exit, should still be avoided in signal handlers ?

Signals, Signal Handling, C, Reentrancy

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.

1
C
cifz
Jump to: Answer 1 Answer 2 Answer 3

Answers (3)

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.

4
D
dmp

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.

0
J
Jost

Comments:

nneonneo said:
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.

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.

0
N
nneonneo

Comments:

cifz said:
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 ?

Related Questions