我正在研究C信号,而我在练习时遇到问题需要编写一个程序,该程序将从进程收到的任何信号发回给发送者进程。
我考虑过使用函数signal()
或函数sigaction()
,但是他们要求你指定signum,我需要它们来处理我的程序收到的每个信号。
如果不为每个信号编号调用sigaction()
,有没有办法这样做?
提前感谢您的回答
答案 0 :(得分:4)
您没有指定您正在使用的操作系统,但这在POSIX系统上很简单。我无法与Windows通话。
您想要的电话是sigwaitinfo。
您需要阻止所有信号,然后使用sigwaitinfo
同步处理任何接收到的信号。 Sigwaitinfo的返回码是接收到的信号,当您传递非null siginfo_t结构作为第二个参数时,您将获得从返回siginfo_t结构的信号处理程序获得的相同信息,包括发送过程的pid。获取接收到的信号和pid并使用kill
将信号发送回原始进程。在致电kill
之前,请确保您没有将信号发送给您自己,以免您最终陷入向自己发送和接收信号的循环中。
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#define errExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while (0)
int main(int argc, char *argv[])
{
siginfo_t signalInfo;
sigset_t allSignals;
printf("echo pid = %d\n", getpid());
// block every signal but SIGKILL & SIGSTOP which can't be blocked
sigfillset(&allSignals);
if (sigprocmask(SIG_SETMASK, &allSignals, NULL) == -1)
errExit("sigprocmask");
while(1)
{
// accept signals until SIGTERM delivered
int sig = sigwaitinfo(&allSignals, &signalInfo);
if (sig == -1)
errExit("sigwaitinfo");
if (sig == SIGTERM)
{
printf("buh-bye\n");
exit(EXIT_SUCCESS);
}
printf("echo received signal %s (%d) from pid = %d\n", strsignal(sig), sig, signalInfo.si_pid);
/*** NOT doing this for testing because it will kill the sending shell
// echo signal back to sender but not to yourself
// which would be stupid and lead to an endless loop
if (signalInfo.si_pid != getpid())
kill(signalInfo.si_pid, sig);
***/
}
}
<强> TEST 强>
---终端1 ---
//current shell's pid
> echo $$
7646
//send signals after starting echo pgm in another terminal
> kill -SIGUSR1 7754
> kill -SIGUSR2 7754
> kill -SIGTERM 7754
---终端2 ---
> echosig
echo pid = 7754
echo received signal User defined signal 1 (10) from pid = 7646
echo received signal User defined signal 2 (12) from pid = 7646
buh-bye