3

I have a program developed in C. I added to this program a sigaction handler inorder to execute some C code before quit the program:

void signal_term_handler(int sig)
{
    printf("EXIT :TERM signal Received!\n");
    int rc = flock(pid_file, LOCK_UN | LOCK_NB);
    if(rc) {
        char *piderr = "PID file unlock failed!";
        fprintf(stderr, "%s\n", piderr);
        printf(piderr);
    }
    exit(EXIT_SUCCESS);
}

int main(int argc, char **argv)
{
    struct sigaction sigint_action;

    sigint_action.sa_handler = &signal_term_handler;
    sigemptyset(&sigint_action.sa_mask);

    sigint_action.sa_flags = SA_RESETHAND;
    sigaction(SIGTERM, &sigint_action, NULL);
        ...........
}

Note: My program contains 2 subthreads running

When I execute myprogram and then I call kill -15 <pidnumber> to kill my program. I get the message "EXIT :TERM signal Received!\n" printed in the stdout but the program is not exited.

Am I missing someting in my sigaction code?

MOHAMED
  • 41,599
  • 58
  • 163
  • 268
  • if you took out all the code that is illegal in your signal handler, you'd be left with `if (rc) { char* piderr = "..."; }` – JeremyP Jun 06 '13 at 16:08

3 Answers3

4

exit() is not necessarily async-signal safe.

To end a process directly from a signal handler call either _exit() or abort().


flock() and all members of the printf family of functions aren't async-signal-save either.


For full list of async-signal-safe functions you might like to click here.

alk
  • 69,737
  • 10
  • 105
  • 255
  • are there an alternative of `flock()` for async-signal-save? if not is it possible to make it async-signal-save? – MOHAMED Jun 06 '13 at 16:08
  • 1
    @MOHAMED: No, I do not see a way to make `flock()` async-signal-save, besides hacking `glibc` and/or the OS' kernel. However, from the fact you are triggering on `SIGTERM` if get the impression you might have an XY-problem: To perfom any action on a program's termination, installing an exit-handler using `atexit()` would be the appropriate way to go. – alk Jun 06 '13 at 16:52
  • the answer in the following [topic](http://stackoverflow.com/questions/16967365/how-to-make-a-function-async-signal-save/16968066#16968066) use `atexit ()` as solution. I m not sure that the proposed solution is a saved way. Could you confirm if it's a saved way? – MOHAMED Jun 06 '13 at 17:47
  • @mohamed: The approach you linked will gain you nothing. – alk Jun 06 '13 at 18:01
  • @mohamed: Just to clarify: Is it that your base intend is to perform some action on a process' end? – alk Jun 06 '13 at 18:09
  • exactelly I want to perform some c instruction at the end of my program like call of `flock()`. my program could end with the `kill -15` – MOHAMED Jun 06 '13 at 19:20
  • Some one told me that `flock()` is generally async-signal-safe because it is a system call. It is not in POSIX's list of async-signal-safe functions because it is not in POSIX at all. Could you confirm that please. Can I use it without problems? – MOHAMED Jun 07 '13 at 07:51
  • @MOHAMED: The fact `flock()` isn't in the POSIX list of async-signal-save functions because it's not POSIX does not mean it's safe to call it from a signal handler. And no, I can not confirm what you're asking for, as my expertise does not go deep enough ito the libc and/or the kernel. I'd say this is highly implementation specific. – alk Jun 07 '13 at 09:22
2

I still suspect you have an XY-problem, that is trying to un-flock() a file on receiving SIGTERM.

To achieve this (and with this get around the limitation to only be able to use async-signal-safe functions on signal reception use the following approach:

  • Mask out all signals to be handled by the app in the main thread.
  • Create a thread.
  • Make this thread receive all signals to be handled, by modifing the thread's signal mask.
  • In this thread loop around sigwaitinfo() to receive and dispatch signals.
  • Then depending on the signal received by this thread do what needs to be done without any limitation due to missing async-signal-saftyness of any function.
alk
  • 69,737
  • 10
  • 105
  • 255
  • thank you for the answer(+1). It's interesting as solution, But I want only to unlock a file before exiting that's all. so adding such behaviour looks complicated comparing to what I want – MOHAMED Jun 07 '13 at 09:00
  • @MOHAMED: Although looking a bit complicated, it is the only way to handle responses to signals in a flexible and last not least secure manner, especially to handle shut-down situtations. Also is a quite generic approach to handel signals in a mutlithreaded environment. – alk Jun 07 '13 at 09:13
  • 1
    @MOHAMED: note that locks are automatically released when a process exits; a dead process holds no locks. – Jonathan Leffler Jun 07 '13 at 11:57
1

Most likely this is because you aren't really allowed to do much of anything in a signal handler (and calling library functions is certainly sketchy).

The normal way to handle something like this is for the signal handler to set a variable or queue up an event that the normal main loop will handle and then exit.

Mark B
  • 95,107
  • 10
  • 109
  • 188