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

标签 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 。在我的测试点,它 fork 并使子程序执行上面的程序(使用适当的参数)。此 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 中没有任何反应。它一直在运行。 sleep 程序的默认信号处理程序(也终止它)不应该像 abide() 那样执行吗?

感谢任何澄清!

最佳答案

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

信号(SIGINT,SIG_DFL)

在调用 fork()exec() 之间。

关于c - 如果明确捕获,SIGINT 仅在子进程上收到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23482305/

相关文章:

android - 如何在 Android 中清空(清除)logcat 缓冲区

c - 将低字节从 int 复制到 char : Simpler to just do a byte load? 的指令

c++ - 在cuda中重新分配不断增长的内存的功能

linux - 如何在 Linux 设备上安装 Windows Phone 8.1 应用程序?

python - sudo 找不到新的 python 版本

c++ - Debian 上的 qt ./configure

linux - 粉碎脚本并输出

代码不输出整个字符串,而是只输出其中的一部分

c - 如何让 backtrace()/backtrace_symbols() 打印函数名?

linux - 在目录上使用 ldd 命令时,如何只显示动态链接的可执行文件?