Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么SIGTSTP未在子系统中解除阻止?_C_Unix_Process_Signals - Fatal编程技术网

C 为什么SIGTSTP未在子系统中解除阻止?

C 为什么SIGTSTP未在子系统中解除阻止?,c,unix,process,signals,C,Unix,Process,Signals,这里有点迷路了。我正在实现我自己的shell,我需要实现的功能之一是在没有子进程运行时忽略ctrl+c和ctrl+z,但当有子进程运行时(例如sleep 5),则需要终止这些进程 我已成功地在父级中使用掩码阻止SIGINT和SIGTSTP,如下所示: if ((sigemptyset(&intmask) == -1) || (sigaddset(&intmask, SIGINT) == -1) || (sigaddset(&intmask, SIGTSTP) == -

这里有点迷路了。我正在实现我自己的shell,我需要实现的功能之一是在没有子进程运行时忽略ctrl+c和ctrl+z,但当有子进程运行时(例如sleep 5),则需要终止这些进程

我已成功地在父级中使用掩码阻止SIGINT和SIGTSTP,如下所示:

  if ((sigemptyset(&intmask) == -1) || (sigaddset(&intmask, SIGINT) == -1) || (sigaddset(&intmask, SIGTSTP) == -1)) {
    perror("invalid failed to initialize signal mask");
    exit(EXIT_FAILURE);
  }

  signal(SIGUSR1, int_handler);

  if (sigprocmask(SIG_BLOCK, &intmask, NULL) == -1) {
    perror("invalid unable to block SIGINT");
    exit(EXIT_FAILURE);
  }
然后在孩子身上我发送了一个
SIGUSR1
信号:

 if (fork() == 0) {
    kill(cmd_group->ppid, SIGUSR1);
  }
它正在调用信号处理程序:

void int_handler(int signum) {
  if (signum == SIGUSR1) {
    sigprocmask(SIG_UNBLOCK, &intmask, NULL);
  }
}
当我运行
sleep5
时,它似乎在调用信号处理程序,但进程并没有以ctrl+c终止。我还应该注意到,子进程位于它们自己的进程组中,与父进程不同

那么为什么SIGINT和SIGTSTP在这里没有解除阻塞呢

编辑:

int main(int argc, char* argv[]) {

    signal(SIGINT, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);
...
}
if (fork() == 0) {
  signal(SIGINT, SIG_DFL);
  signal(SIGTSTP, SIG_DFL);

  // execute commands
}
在阅读了信号忽略和信号阻塞之间的区别之后,我决定最好通过
SIG\u IGN
handler忽略父级中的SIGINT和SIGTSTP

然后在子系统中重置回
SIG_DFL

家长:

int main(int argc, char* argv[]) {

    signal(SIGINT, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);
...
}
if (fork() == 0) {
  signal(SIGINT, SIG_DFL);
  signal(SIGTSTP, SIG_DFL);

  // execute commands
}
子项:

int main(int argc, char* argv[]) {

    signal(SIGINT, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);
...
}
if (fork() == 0) {
  signal(SIGINT, SIG_DFL);
  signal(SIGTSTP, SIG_DFL);

  // execute commands
}
对于SIGINT,它执行所需的行为:在父对象中忽略,在子对象中工作

然而,对于SIGTSTP,当我试图杀死一个子进程(如
sleep5
)时,它会导致它永远挂起(甚至不会从睡眠中返回)


什么原因可能导致这种情况?

孩子立即发出信号进行测试。我理解正确吗?可能值得检查孩子的
intmask
是否具有您认为的值。(它可能确实有,但在调试时,可以检查,如果只是为了消除这种可能性。)如何设置
cmd_group
的值?孩子抛出一个信号
SIGUSR1
,以便调用处理程序,然后该处理程序将取消阻止SIGTSTP和SIGINT。cmd_group是一个自定义结构,它的成员,
ppid
只是父级的PID,在我的程序开始时分配。如何打印
intmask
?似乎无法使用
%x
…我知道没有简单的方法可以打印
intmask
。我不是这方面的专家,但由于似乎没有专家在场,而且我对你的问题感兴趣,我正试图在我的机器上编译它,看看它能做什么。孩子立即发出信号,以便进行测试。我理解正确吗?可能值得检查孩子的
intmask
是否具有您认为的值。(它可能确实有,但在调试时,可以检查,如果只是为了消除这种可能性。)如何设置
cmd_group
的值?孩子抛出一个信号
SIGUSR1
,以便调用处理程序,然后该处理程序将取消阻止SIGTSTP和SIGINT。cmd_group是一个自定义结构,它的成员,
ppid
只是父级的PID,在我的程序开始时分配。如何打印
intmask
?似乎无法使用
%x
…我知道没有简单的方法可以打印
intmask
。我不是这方面的专家,但因为似乎没有专家在场,而且我对你的问题感兴趣,所以我尝试在我的机器上编译它,看看它能做什么。