gpt4 book ai didi

shell - 使用 SIGTSTP 挂起子进程后,shell 没有响应

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:11:17 25 4
gpt4 key购买 nike

我正在用 C 编写一个基本的 shell,我现在正致力于暂停一个子进程。

我认为我的信号处理程序是正确的,我的子进程正在挂起,但在那之后,终端应该返回到父进程,而这并没有发生。

child 被挂起,但我的 shell 不再注册任何输入或输出。 tcsetpgrp() 似乎没有帮助。

这是我的 SIGTSTP shell 代码中的信号处理程序:

void suspend(int sig) {
pid_t pid;
sigset_t mask;
//mpid is the pgid of this shell.
tcsetpgrp(STDIN_FILENO, mpid);
tcsetpgrp(STDOUT_FILENO, mpid);
sigemptyset(&mask);
sigaddset(&mask, SIGTSTP);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
signal(SIGTSTP, SIG_DFL);
//active.pid is the pid of the child currently in the fg.
if (active.pid != 0) {
kill(active.pid, SIGTSTP);
}
else{
//if this code is being run in the child, child calls SIGTSTP on itself.
pid = getpid();
if (pid != 0 && pid != mpid){
kill(pid, SIGTSTP);
}
}
signal(SIGTSTP, suspend);
}

谁能告诉我我做错了什么?

我是否将我的 shell 与子进程一起暂停,我是否需要以某种方式将 stdin 和 stdout 返回给 shell?我该怎么做?

谢谢!

最佳答案

这是一个老问题,但我仍然认为我找到了答案。
你没有写你 parent 的代码,但我假设它看起来像:

int main(){ 
pid_t pid = fork();
if(pid == 0) //child process
//call some program
else //parent process
wait(&status); //or waitpid(pid, &status, 0)
//continue with the program
}

问题出在 wait() 或 waitpid() 上,如果您在使用 Ctrl+Z 后在 Ubuntu 等操作系统上运行您的程序,您的子进程就会这样正在获取 SIGTSTP 但父进程中的 wait() 函数仍在等待!

这样做的正确方法是用 pause() 替换父级中的 wait(),并创建另一个捕获 SIGCHLD 的处理程序。例如:

void sigHandler(int signum){
switch(signum){
case SIGCHLD:
// note that the last argument is important for the wait to work
waitpid(-1, &status, WNOHANG);
break;
}
}

在这种情况下,子进程收到 Ctrl+Z 后,父进程也收到 SIGCHLD 和 pause() 返回。

关于shell - 使用 SIGTSTP 挂起子进程后,shell 没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12664664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com