-3

I'm supposed to install a signal handler to call the function stopContinue() when I receive SIGINT. Here is my code snippet in C, but I'm not sure if this correct. Please let me know where I'm going wrong.

struct sigaction act;

memset(&act, '\0', sizeof(act));
action.sa_flags = 0; 
action.sa_handler = stopContinue;
sigaction(SIGINT, &act, NULL);

Does this look roughly correct?

There is a discussion on using sigaction vs. action, and the use of flags here that is different than another question, this is not a dupe.

J. Don
  • 1
  • 2
  • What happened when you tried to run it? – dbush Mar 13 '17 at 19:39
  • 1
    Possible duplicate of [Catch Ctrl-C in C](http://stackoverflow.com/questions/4217037/catch-ctrl-c-in-c) – MD XF Mar 13 '17 at 19:42
  • 1
    https://www.google.com/#q=c+signal+handler – MD XF Mar 13 '17 at 19:43
  • You also need to clear the set of blocked signals, using e.g. `sigemptyset(&act.sa_mask);` after the `memset()`. – Nominal Animal Mar 13 '17 at 19:57
  • You haven't checked whether the code is currently ignoring interrupts; if it is, you probably shouldn't re-enable interrupt handling. This is a standard issue. With `sigaction()`, you can use `sigaction(SIGINT, NULL, &act)` to find the current signal handling state — you could then modify that and set a new state more or less as shown. – Jonathan Leffler Mar 13 '17 at 21:21

1 Answers1

0

Why use sigaction if you're not even going to use the struct's sa_flags member? To call stopContinue when Ctrl+C is pressed, you can use:

signal(SIGINT, stopContinue);

If you simply want to ignore Ctrl+C, you can make it even easier:

signal(SIGINT, SIG_IGN);

SIG_IGN is a macro to ignore signals.

Community
  • 1
  • 1
MD XF
  • 7,860
  • 7
  • 40
  • 71
  • Because [`signal()`](http://man7.org/linux/man-pages/man2/signal.2.html) is only portable if used with `SIG_DFL` or `SIG_IGN`, whereas [`sigaction()`](http://man7.org/linux/man-pages/man2/sigaction.2.html) is the proper POSIX.1 standard function to use here, your suggestion is bad. – Nominal Animal Mar 13 '17 at 19:52
  • @NominalAnimal POSIX isn't exactly portable, though... **Never mind. Not what I meant.** – MD XF Mar 13 '17 at 19:52
  • Don't be ridiculous. POSIX semantics are used in Linux, BSDs, macOS, Solaris, Tru64, and so on -- basically everywhere except Windows. It is Windows stuff and idiotic suggestions like this that are not portable. – Nominal Animal Mar 13 '17 at 19:55
  • @NominalAnimal Does the behavior of `signal` vary enough across POSIX that writing `signal(SIGNAL, FUNCTION)` on two different platforms *may not call `FUNCTION` when `SIGNAL` is recieved?* – MD XF Mar 13 '17 at 19:56
  • On SysV Unix boxes, *`FUNCTION`* would only be called for the first signal delivery, and the disposition reset for the second; meaning two Ctrl+C rapidly in succession would usually kill the process. BSD `signal()` installs the handler as if with `.sa_flags = SA_RESTART` was specified via sigaction, so that the delivery will not interrupt a blocking syscall. Since the signal handler typically just sets a `volatile sig_atomic_t` flag, and relies on the main processing loop to be interrupted so that the flag is examined, this would not occur on BSDs. – Nominal Animal Mar 13 '17 at 20:05
  • On all the systems I mentioned, using `sigaction()` with `.sa_flags = 0;` the semantics are always the same: the delivery of the signal to the user function will interrupt a blocking syscall (in the same thread; in a multithreaded process the kernel may choose any thread that is not blocking the signal), and the typical `volatile sig_atomic_t` flag scenario will work. A typical example of a main loop being interrupted is `accept()`ing a new connection. If interrupted by a signal, it will return `-1` with `errno == EINTR`. – Nominal Animal Mar 13 '17 at 20:08