如果明确捕获,则仅在子进程上收到SIGINT

时间:2014-05-05 21:34:25

标签: c linux shell unix sigint

我有以下带有UNIX系统调用的测试C程序:

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

void abide(int sig_num) {
    printf("I, sleeper, will abide to this signal %d!\n", sig_num);
    fflush(stdout);
    exit(0);
}

void refuse(int sig_num) {
    signal(SIGINT, refuse);
    printf("I, sleeper, REFUSE this signal %d!\n", sig_num);
    fflush(stdout);
}

int main(int argc, char *argv[]) {
    if (argc > 1 && strcmp(argv[1], "refuse") == 0) {
        signal(SIGINT, refuse);
    } else if (argc > 1 && strcmp(argv[1], "deaf") == 0) {
        printf("I, sleeper, have been made deaf...\n");
    } else {
        signal(SIGINT, abide);
    }
    printf("I, sleeper, am now sleeping for 10s...\n");
    sleep(10);
    printf("I, sleeper, has terminated normally.\n");
    return 0;
}

然后我有另一个程序作为一个小shell。在我的测试点,它分叉并使子程序执行上面的程序(使用适当的参数)。此shell也使用

忽略Ctrl + C命令
signal(SIGINT, SIG_IGN);

结果如下:

MyShell> ./sleeper
I, sleeper, am now sleeping for 10s...
^CI, sleeper, will abide to this signal!
MyShell> ./sleeper refuse
I, sleeper, am now sleeping for 10s...
^CI, sleeper, REFUSE this signal!
I, sleeper, has terminated normally.
MyShell> ./sleeper deaf
I, sleeper, have been made deaf...
I, sleeper, am now sleeping for 10s...
^C^C^C^C    <---- not terminating

第一轮似乎是正确的。第二个有点奇怪,因为我们实际上忽略了信号,但程序终止了。也许是因为我们正在调用sleep()被中断。

但这是让我困惑的第三个结果。在常规shell中,程序终止,但在我的自定义shell中没有任何反应。它一直在运行。睡眠程序的默认信号处理程序(它也终止它)不应该像abide()一样执行吗?

感谢您的任何澄清!

1 个答案:

答案 0 :(得分:1)

解决了它。问题有点微妙。使用fork()后,即使您之后使用exec()系统调用,子进程显然也会继承其父级信号处理程序。因此sleeper的子进程正在使用ignore处理程序。解决方案只是添加默认处理程序

signal(SIGINT, SIG_DFL)

fork()exec()之间的