Search code examples
clinuxsignalskill

Pass local variable to a signal handler function


I want to send a copy of some data to a signal handler function, take the simplified example:

signal(SIGUSR1, handler);
void handler(int sig){
    
    //...
    _exit(some_variable);
}

The goal is to stop the process and make it return some_variable value to the parent without making it a global variable. Mind that some_variable is local to the project that catches the signal, not the process that raises the signal.

I woud like to be able to both raise the signal in another process (kill) (not the parent btw) and to be able to do it from a console (kill) or using a script, and that's the main reason for using signal(), as it's good for both.

I understand that there are other ways of doing this but would really like to know if this can be done using signal() or a related method.

Other threads on the site suggest that this can't be done like this but they are quite old, perhaps some newer solution exists.


Solution

  • If the signal is sent from the same process, just use a global variable. There is no basis/justification for objecting to using a global variable here, because signal dispositions are already global variables. That is, by committing yourself to installing a handler for SIGUSR1 and choosing a purpose for it, you've already chosen to have a singleton here; adding a variable as part of that singleton is no further sin. However in this case (same process) there's probably no reason to be using a signal handler anyway. There are all sorts of far-less-dangerous ways to communicate between parts of your program.

    If the signal is being sent from a different process, you can pass small amounts of data (one integer) via union sigval queued with sigqueue, but that only works for sigqueue; it doesn't work if you want to be able to just use the kill command. And once you choose to require a special tool to interact, it makes a lot more sense to drop signals and use some better IPC mechanism like unix sockets, named pipes, shared memory with some synchronization primitives (semaphore or mutex+condvar) living inside it, etc.