我正在写一个迷你外壳(不,不是为了学校:P;为了我自己的乐趣),现在大部分基本功能已经完成,但是在尝试处理 SIGTSTP 时我被卡住了。
假设当用户按下 时Ctrl+Z
,SIGTSTP 应该被发送到 shell 的 Foreground 进程(如果存在),并且 Shell 应该正常继续。
创建每个进程后(如果是前台进程),下面的代码等待:
if(waitpid(pid, &processReturnStatus, WUNTRACED)>0){//wait stopped too
if(WIFEXITED(processReturnStatus) || WIFSIGNALED(processReturnStatus))
removeFromJobList(pid);
}
我正在按如下方式处理信号:
void sigtstpHandler(int signum)
{
signum++;//Just to remove gcc's warning
pid_t pid = findForegroundProcessID();
if(pid > -1){
kill(-pid, SIGTSTP);//Sending to the whole group
}
}
发生的情况是,当我按下 时Ctrl+Z
,子进程确实被挂起(ps -all
用于查看进程的状态)但我的 shell 挂在waitpid
它永远不会返回,即使我传递了WUNTRACED
标志,据我所知,它应该waitpid
在该过程也停止了。
那么我可能做错了什么?还是我错误地理解了waitpid的行为?
注意:
-findForegroundProcessID() 返回正确的 pid;我仔细检查了那个。
- 我在我之后更改每个进程的组 - 处理工作正常-
如果我在我的外壳挂起后使用另一个终端发送 SIGCONT,子进程将恢复其工作,外壳最终会获得它fork
。
-我正在捕获 SIGTSTP,据我阅读(和测试)可以捕获它。- 我尝试使用 waitid 而不是 waitpid 以防万一,问题仍然存在。
编辑:Ctrl+C
void sigchldHandler(int signum)
{
signum++;//Just to remove the warning
pid_t pid;
while((pid = waitpid(-1, &processReturnStatus, 0)) > 0){
removeFromJobList(pid);
}
if(errno != ECHILD)
unixError("kill error");
}
我的 SIGCHLD 处理程序。