C wait for signal with loop
Asked Answered
G

1

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;
}
Grenoble answered 17/10, 2019 at 7:58 Comment(4)
You can use select(). That's from the top of my head cause I know that select() can block forever. select(2)Posse
There are probably many other possible tricks.Posse
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 signalHazaki
Don't use printf inside signal handlers, ever.Declarative
P
7

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

Problematic answered 17/10, 2019 at 8:21 Comment(5)
POSIX specifications: pause() and sigwait(). Do not be tempted to use sigpause() — it is obsolescent (which means it should only be used by existing code that already uses it, and not by any new code).Buxton
@JonathanLeffler so using ` sigwait ()` is ok ?Grenoble
@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.Buxton
There are more than 2 possibilities. poll(0, 0, -1) is a 3rd. And there are many others.Declarative
Note that sigwait() will consume the signal and the handler won't be called. I'd use sigsuspend().Disdainful

© 2022 - 2024 — McMap. All rights reserved.