5

In C Linux, is there any way to wait for signal like SIGUSR1 and SIGUSR2 without loop?

For eaxmple in this code I wait for SIGUSR1 or SIGUSR2 to print message, but while I want , I do while true....

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void signal_callback_handler(int signum)
{
   printf("Caught signal %d\n",signum); 
}

int main()
{
   signal(SIGUSR1, signal_callback_handler);
   signal(SIGUSR2, signal_callback_handler);
   while(1)
   {
      printf("Program processing stuff here.\n");
      sleep(1);
   }
   return EXIT_SUCCESS;
}

How can I wait and do not do anything (do not do while true) until SIGUSR1 or SIGUSR2 arrived ?

For example :

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void signal_callback_handler(int signum)
{
   printf("Caught signal %d\n",signum); 
}

int main()
{
   signal(SIGUSR1, signal_callback_handler);
   signal(SIGUSR2, signal_callback_handler);

    printf("this line happned after signal arrived \n ");
   return EXIT_SUCCESS;
}
joif doi
  • 181
  • 1
  • 2
  • 10
  • You can use `select()`. That's from the top of my head cause I know that `select()` can block forever. [`select(2)`](http://man7.org/linux/man-pages/man2/select.2.html) – Iharob Al Asimi Oct 17 '19 at 08:03
  • There are probably many other possible tricks. – Iharob Al Asimi Oct 17 '19 at 08:04
  • You might want to read the man page on sleep. On linux sleep is terminated by signals. So you could sleep for a very long time -- years say -- and when you come out of it check to see if your signal handler has been called. By the way it's not a good idea to call printf in a signal handler; see man 7 signal – dmuir Oct 17 '19 at 08:35
  • 1
    Don't use `printf` inside signal handlers, ever. –  Oct 17 '19 at 09:14

1 Answers1

6

There are two possibilities:

  • pause() or
  • sigwait()

Documentation for pause:

Description
pause() causes the calling process (or thread) to sleep until a signal is delivered that either terminates the process or causes the invocation of a signal-catching function.

Source: https://linux.die.net/man/2/pause


And the documentation for sigwait:

Description
The sigwait() function suspends execution of the calling thread until one of the signals specified in the signal set set becomes pending. The function accepts the signal (removes it from the pending list of signals), and returns the signal number in sig.

Source: https://linux.die.net/man/3/sigwait

Both functions are conforming to POSIX.1-2001

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Sinic
  • 348
  • 3
  • 10
  • 1
    POSIX specifications: [`pause()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html) and [`sigwait()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigwait.html). Do **not** be tempted to use [`sigpause()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpause.html) — it is obsolescent (which means it should only be used by existing code that already uses it, and not by any new code). – Jonathan Leffler Oct 17 '19 at 08:33
  • @JonathanLeffler so using ` sigwait ()` is ok ? – joif doi Oct 17 '19 at 08:44
  • @joifdoi: Yes, using either `sigwait()` or `pause()` is OK. Using `sigwait()` pauses a thread. The `pause()` function is more ancient (pre-dating threads by a long margin) and holds up the (only) thread in a process. I tend to use `pause()` because I pre-date threads too; these days, `sigwait()` is probably the better choice. It provides for much better selectivity — you can (must) specify which signals you're interested in, whereas `pause()` returns when any signal is received. – Jonathan Leffler Oct 17 '19 at 08:49
  • There are more than 2 possibilities. `poll(0, 0, -1)` is a 3rd. And there are many others. –  Oct 17 '19 at 09:12
  • 1
    Note that sigwait() will consume the signal and the handler won't be called. I'd use sigsuspend(). – Mark Plotnick Oct 17 '19 at 14:12