c - 使用 `kill` 触发 parent 的 `waitpid`

标签 c shell posix

我正在使用 sigaction(SIGTSTP, &ctrlz_signal, NULL); 来确保我可以捕捉到 Ctrl-Z

void ctrlz_signal(int sigNo) {
    printf("Caught Ctrl-Z  |  curr_chld=%d\n", CURR_CHILD);
    if(CURR_CHILD != 0) kill(CURR_CHILD, SIGTSTP);
}

CURR_CHILD 通过 fork 设置:

    sigaction(SIGTSTP, &ctrlz_signal, NULL);

    int         status;
    CURR_CHILD = fork();


    if (CURR_CHILD < 0) {
        // ...

    } else if (CURR_CHILD == 0) {  // child
        // exec(...)

    } else {  // back in parent
        waitpid(CURR_CHILD, &status, 0);  // wait for child to finish
        // ...
    }

看起来它成功地停止了子进程,但是它并没有触发父进程的waitpid。我原以为当我使用这个 kill 函数时会有一个信号发送给父级,但似乎不是,因为我的“shell”卡在了那个 waitpid 行。

我该如何做到,一旦按下 Ctrl-Z,运行 exec 命令的进程(此时是一个子命令)应该是置于后台(已停止),然后父进程应该重新获得对程序流程的控制权?

最佳答案

printf 不是 async-signal-safe函数(因为它不可重入),因此不能在信号处理程序中使用。使用此类函数将导致未定义的行为。

如果你想让一个没有被ptrace跟踪的子进程返回,你必须在使用waitpid时指定WUNTRACED选项。 .

或者,您可以使用 ptrace使用 PTRACE_TRACEME 选项,这样即使 waitpid 调用中未指定 WUNTRACED 选项,它也会为子进程提供状态。

关于c - 使用 `kill` 触发 parent 的 `waitpid`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54545813/

相关文章:

c - MISRA C 建议不要使用 malloc,这是否意味着 calloc 更安全?

clion 更改默认项目模板

c - 如果发生错误,我应该关闭(文件)吗?

c - 在嵌入式系统中从汇编语言切换到 C 语言

linux - 如何组合shell命令

arrays - while循环只读最后一行?

c - POSIX C 中 fork() 的重量更轻的替代品?

linux - 每 5 分钟将 curl 输出重定向到动态文件名

c - Linux C,如何安排10个等待线程以FIFO方式执行?

c - C信号死锁条件