waitpid阻止它不应该

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处理程序.

fiz*_*zer 1

SIGCHLD是为停止的儿童提供的。信号处理程序中的waitpid()调用(未指定)将永远阻塞。 WUNTRACED

您可能不应该removeFromJobList()在两个不同的地方进行处理。如果我不得不猜测,听起来它涉及全局数据结构,并且不属于信号处理程序。