Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Providing/passing argument to signal handler

Can I provide/pass any arguments to signal handler?

/* Signal handling */ struct sigaction act; act.sa_handler = signal_handler; /* some more settings */ 

Now, handler looks like this:

void signal_handler(int signo) {     /* some code */ } 

If I want to do something special i.e. delete temp files, can I provide those files as an argument to this handler?

Edit 0: Thanks for the answers. We generally avoid/discourage use of global variables. And in this case, If you have a huge program, things can go wrong at different places and you might need to do a lot of cleanup. Why was the API designed this way?

like image 724
hari Avatar asked Aug 07 '11 01:08

hari


People also ask

Can a signal handler take arguments?

Absolutely. You can pass integers and pointers to signal handlers by using sigqueue() instead of the usual kill().

What is passing an argument?

Unless an argument is passed by value (BYVALUE), a reference to an argument, not its value, is generally passed to a subroutine or function. This is known as passing arguments by reference, or BYADDR.

What can I do in a signal handler?

Signal Handling The process can ignore the signal, can specify a handler function, or accept the default action for that kind of signal. If the specified action for the signal is ignored, then the signal is discarded immediately. The program can register a handler function using function such as signal or sigaction.

Does sigaction call the signal handler?

sigaction() can be called with a NULL second argument to query the current signal handler. It can also be used to check whether a given signal is valid for the current machine by calling it with NULL second and third arguments.


2 Answers

You can't have data of your own passed to the signal handler as parameters. Instead you'll have to store your parameters in global variables. (And be really, really careful if you ever need to change those data after installing the the signal handler).

Response to edit 0: Historical reasons. Signals are a really old and really low-level design. Basically you're just given the kernel a single address to some machine code and asking it to go to this specific address if such and such happens. We're back in the "portable assembler" mindset here, where the kernels provide a no-frills baseline service, and whatever the user process can reasonably be expected to to for itself, it must do itself.

Also, the usual arguments against global variables don't really apply here. The signal handler itself is a global setting, so there is no relevant possibility of having several different sets of user-specified parameters for it around. (Well, actually it is not entirely global but only thread-global. But the threading API will include some mechanism for thread-local storage, which is just what you need in this case).

like image 145
hmakholm left over Monica Avatar answered Oct 12 '22 02:10

hmakholm left over Monica


A signal handler registration is already a global state equivalent to global variables. So it's no greater offense to use global variables to pass arguments to it. However, it's a huge mistake (almost certainly undefined behavior unless you're an expert!) to do anything from a signal handler anyway. If you instead just block signals and poll for them from your main program loop, you can avoid all these issues.

like image 44
R.. GitHub STOP HELPING ICE Avatar answered Oct 12 '22 03:10

R.. GitHub STOP HELPING ICE