2016-12-07 3 views
2

私は、forkを実行するプログラムを作成しようとしています。子プログラムはコマンドを実行し、親に制御を返します。私は親がSIGTSTP(Cz)シグナルを意図した通りに動作させるのに問題がありますが、親はそれを無視しますが、子は停止して親に制御を戻し、子を後で再開したり殺したりできるようにします。 (組み込みコマンド付き)。私は関連するコードを単なる小さなプログラムに分けてテストしましたが、A)Czがタイプされたときに子が止まらない、またはB)停止しますが、親にコントロールを返しません私はstdinのための猫を使用すると、Czの後に別に動作するので、これに向かって傾いている)。ここに私のコードです。SIGTSTPシグナルは停止していませんか?

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <fcntl.h> 
#include <cstring> 
#include <unistd.h> 
#include <cstdlib> 
#include <iostream> 
#include <vector> 
#include <string> 
#include <signal.h> 


int main(){ 
    std::cout.setf(std::ios::unitbuf); 

    std::vector<std::string> vec; vec.push_back("cat"); 
    std::vector<char*> chvec; 
    for(unsigned int i = 0; i < vec.size(); i++){ 
    chvec.push_back(&vec[i][0]); 
    } 
    chvec.push_back(NULL); 
    vec.erase(vec.begin(), vec.begin() + chvec.size()); 

    char** argv = &chvec[0]; 
    signal(SIGTSTP,SIG_IGN); 

    pid_t pid; 
    if((pid = fork()) == 0){ 
    signal(SIGTSTP,SIG_DFL); 
    /*pid = getpid(); 
    setpgid(pid,pid);*/ 
    std::cout << "before exec" << std::endl; 
    execvp(argv[0],argv); 
    perror("exec"); 
    } 
    else{ 
    //setpgid(pid,pid); 
    int status; 
    waitpid(pid,&status,0); 
    if(WIFEXITED(status) || WIFSIGNALED(status)){ 
     std::cout << "exited or signaled" << std::endl; 
    } 
    if(WIFSTOPPED(status)){ 
     std::cout << "process stopped" << std::endl; 
    } 
    //std::cout << "process exited" << std::endl; 
    pause(); 
    } 
    return EXIT_SUCCESS; 
} 
+0

'chvec []'は末尾のヌルポインタを必要とします。 – Barmar

+0

これを修正しました(何も影響していないようですが) – faezer

+0

別の端末ウィンドウで 'ps'を使って' A'と 'B'の違いを知ることができます。子が停止している場合、それは 'T'状態になります。 – Barmar

答えて

1

それはすでにあなたが消去されvecベクトルの結果として、未定義の動作を修正する必要があるコメントで指摘されました。それが最初の問題です。

あなたのコードがWIFSTOPPEDを使用してプロセスの終了ステータスをチェックしていることがわかりました。

レッツ・review the documentation for the wait(2) system call、それはこのことについて言っている参照してください。

WIFSTOPPED(wstatus) 
     returns true if the child process was stopped by delivery of a 
     signal; this is possible only if the call was done using WUN‐ 
     TRACED or when the child is being traced (see ptrace(2)). 

をので、手元にその情報に基づいて、前述の未定義の動作を固定した後、およびにごwaitpid()の呼び出しを変更した後:

waitpid(pid,&status,WUNTRACED); 

は、それから私は、生成されたcatプロセスにkill -TSTP <pid>メッセージを送信することができました、そして、期待

プロセスは、あなたのテストプログラムから

メッセージを停止し得ます。

P.S.子プロセスにストレスをかけると、子プロセスがTSTPシグナルを受信して​​いて、うまく止まっていることがわかりました。問題は単に、親がそれを処理していなかったことであり、必要なオプションはwaitpid()ではありませんでした。

+0

ああ、私はまあ...以前はWUNTRACEDを使ってみましたが、停止信号を待つ代わりに、C-zを待つのではなく何らかの理由でcatが自動的に停止しました。私が試した他の多くのものか​​ら残っているコードがあったかもしれませんが、これはうまくいきましたが、今はうまくいきます... soooたくさんありがとう! – faezer

関連する問題