私はミニシェルを書いています(いいえ、学校用ではありません:P;私自身の楽しみのために)そして基本的な機能のほとんどはこれで完了しましたが、SIGTSTPを処理しようとすると行き詰まります。
おそらく、ユーザーがを押すCtrl+Z
と、SIGTSTPが存在する場合はシェルのフォアグラウンドプロセスに送信され、シェルは通常どおり続行する必要があります。
各プロセスを作成した後(フォアグラウンドプロセスの場合)、次のコードが待機します。
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
シェルがハングします。プロセスも停止します。
では、何が間違っている可能性がありますか?または、waitpidの動作を正しく理解していませんか?waitpid
WUNTRACED
waitpid
注:
-findForegroundProcessID()は正しいpidを返します。私はそれを再確認しました。
-直後に各プロセスのグループを変更しています-処理はfork
正常に機能Ctrl+C
しています
-シェルがハングした後に別の端末を使用してSIGCONTを送信すると、子プロセスは作業を再開し、シェルは最終的にそれを取得します。
-私が読んだ(そしてテストした)限り、捕まえることができるSIGTSTPを捕まえています。-念のため、waitpidの代わりにwaitidを使用してみましたが、問題が解決しませんでした。
編集:
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ハンドラー。