为C中的任何信号设置信号处理程序

时间:2014-05-09 21:39:17

标签: c posix

我正在研究C信号,而我在练习时遇到问题需要编写一个程序,该程序将从进程收到的任何信号发回给发送者进程。 我考虑过使用函数signal()或函数sigaction(),但是他们要求你指定signum,我需要它们来处理我的程序收到的每个信号。 如果不为每个信号编号调用sigaction(),有没有办法这样做? 提前感谢您的回答

1 个答案:

答案 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