【问题标题】:Using `kill` to trigger a parent's `waitpid`使用`kill`触发父母的`waitpid`
【发布时间】:2019-06-29 22:40:54
【问题描述】:

我正在使用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是通过forking设置的:

    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() 是未定义的,顺便说一句。您应该再次阅读 waitpid() 的手册页,注意有关 options 参数的部分。
  • @Shawn 你帮了我,谢谢!随意张贴WUNTRACED 是我在waitpid 中需要的标志,我会将其标记为答案。 :)

标签: c shell posix


【解决方案1】:

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

如果您希望返回未使用ptrace 跟踪的子进程,则必须在使用waitpid 时指定WUNTRACED 选项。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 2021-09-26
    相关资源
    最近更新 更多