Fin*_*fin 11 c linux shell signals wait
我正在写一个迷你shell(不,不是为了学校:P;为了我自己的乐趣),大部分基本功能现在已经完成,但我在尝试处理SIGTSTP时遇到困难.
据推测,当用户按下时Ctrl+Z,SIGTSTP应该被发送到shell的Foreground进程(如果存在),并且Shell应该正常继续.
创建每个进程后(如果它是Foreground进程),以下代码等待:
if(waitpid(pid, &processReturnStatus, WUNTRACED)>0){//wait stopped too
if(WIFEXITED(processReturnStatus) || WIFSIGNALED(processReturnStatus))
removeFromJobList(pid);
}
Run Code Online (Sandbox Code Playgroud)
我正在处理如下信号:
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
}
}
Run Code Online (Sandbox Code Playgroud)
会发生什么事情,当我按下时Ctrl+Z,子进程确实被挂起(ps -all用于查看进程的状态)但我的shell挂起waitpid它永远不会返回,即使我通过了WUNTRACED标志,据我所知,它应该waitpid返回时这个过程也停止了.
那么我可能做错了什么呢?还是我理解waitpid的行为不正确?
注意:
-findForegroundProcessID()返回正确的pid; 我仔细检查了一下.
- 我正在改变每个进程的组,直到我fork
-Handling Ctrl+C工作正常 -
如果我在shell挂起后使用另一个终端发送SIGCONT,子进程恢复其工作并且shell最终收获它.
- 我正在捕捉SIGTSTP,只要我读到(并测试过)就可以捕获. - 我尝试使用waitid而不是waitpid以防万一,问题仍然存在.
编辑:
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");
}
Run Code Online (Sandbox Code Playgroud)
我的SIGCHLD处理程序.
SIGCHLD是为停止的儿童提供的。信号处理程序中的waitpid()调用(未指定)将永远阻塞。 WUNTRACED
您可能不应该removeFromJobList()在两个不同的地方进行处理。如果我不得不猜测,听起来它涉及全局数据结构,并且不属于信号处理程序。
| 归档时间: |
|
| 查看次数: |
7170 次 |
| 最近记录: |