6

I'm registering in the main an handler for the SIGTERM like this:

signal(SIGTERM, sigterm_handler);

And the handler is a simple:

void sigterm_handler()
{    exit(1);    }

What if I need to pass to the handler a few arguments like a 2 pointers or anything else? How do I register the handler in the signal function? Or at least... is there anyway to achieve that?

Notice: the process is killed by a third party process, not by itself. But before closing I need to manually free some structures and write them on files.

Damiano Barbati
  • 3,356
  • 8
  • 39
  • 51
  • 1
    FYI, don't call exit() inside a signal handler - it's not async-signal-safe, because it flushes stdio buffers. Use _exit() inside signal handlers. – lightdee Mar 26 '12 at 20:42
  • This is really old and it has no accepted answer, but there is a duplicate which is a little bit newer, just to redirect any readers I marked it as duplicate. – Iharob Al Asimi Jul 30 '15 at 18:47

4 Answers4

5

Where do you intend to pass the arguments from? The only time sending a signal would be a reasonable way to do what you're doing is when the process you're terminating is not the process itself, but in that case, pointers would be meaningless. You can pass a pointer with the sigqueue function and SA_SIGINFO type signal handlers, but it looks to me like you don't understand signals or have any good reason for using them in the first place. Just make a function call when you want to exit rather than raising signals...

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Post edited: the process is killed by a third party process, not by itself. But before closing I need to manually free some structures and write them on files. – Damiano Barbati May 03 '11 at 21:19
  • Then you need to store pointers to that data in global variables, or block the signal and use `sigwait` rather than a signal handler to process it. – R.. GitHub STOP HELPING ICE May 03 '11 at 21:34
3

Simply use a global variable. As others have pointed out, your signal handler will be invoked by a call stack not under your control.

You might consider using setjmp() and longjmp() to transfer control from your signal handler to a previously-executed code path. This old-school approach could be really fun for you.

Heath Hunnicutt
  • 18,667
  • 3
  • 39
  • 62
0

you cannot pass an argument to the handler - since you are not the one calling the handler. The handler will be called from somewhere outside your control.

you register a handler either with a call to signal or sigaction .

hth

Mario

Mario The Spoon
  • 4,799
  • 1
  • 24
  • 36
  • 1
    Perhaps OP just wants some pointers from elsewhere in the program to be available to the signal handler, but not specified by the code generating the signal. If that's the case, global variables are the (ugly) solution. Alternatively, `SIGTERM` could be blocked and handled with `sigwait` instead of asynchronously. – R.. GitHub STOP HELPING ICE May 03 '11 at 20:44
  • true, but then they are not arguments ;-) – Mario The Spoon May 03 '11 at 20:52
0

Signals normally come asynchronously, meaning not from specific spots in the program, and therefore you can't pass arguments normally. If I were to press control-C while the program was running, what pointers should the signal handler get?

You could only pass meaningful arguments (if C would allow that, which it doesn't) if you constructed a signal within your program and deliberately raised it, and in such a case you should call a function instead.

So, if you want to call something in your program, use a function. If you want a function called if there's an external event, which will know nothing of what you're processing, use a signal handler.

David Thornley
  • 56,304
  • 9
  • 91
  • 158
  • Post edited: the process is killed by a third party process, not by itself. But before closing I need to manually free some structures and write them on files. – Damiano Barbati May 03 '11 at 21:19
  • @hysoka44: You still can't pass any pointers. You could leave pointers to the data structures in global variables, if you liked. Then you need to figure out what you can do reliably inside a signal handler. Since it's invoked asynchronously, the process could be in the middle of doing something, like I/O, and that could easily mess up an effort on the part of the signal handler to write the data structures out. Or it could be in the middle of a heap operation, and the heap might not be in a consistent state. Getting a signal handler to do anything useful reliably is difficult. – David Thornley May 03 '11 at 21:34
  • I'll go for global variables. No way to prevent the possible inconsistent state left by the call of the signal handler, right? I was thinking: once the handler is invoked i check whether it was called before (checking a global int): if it wasn't, flag the int and return else do what u need and exit. In my main function I could set some "safe points" which checks whether the handler was invoked, if it so then call it once again (but now it won't return but it wil do what I need since the beginning). So I won't have the inconstistent state. Am I flying to high with the imagination? – Damiano Barbati May 03 '11 at 21:44
  • Setting a flag for later action is something a signal handler can do. What you'd want is a signal handler to set a flag, frequent checks for the flag, and a clean-up-and-write-out function you can call. – David Thornley May 04 '11 at 14:59