2

私は在宅勤務用の端末を実装しています。
bg ( Background ) と fg ( Foreground ) コマンドを実装する必要があるだけです。
私のコードは次のようになります。

void run(){

    string command[] = parseMyInput( getInput() );  
    int fork_result = fork();
    if( -1 == fork_result )
        //handle error
    else if( 0 == fork_result ){  // child

         setpgrp();  // I don't want the children to get the signals

         if( -1 == execvp( command[0], makeArgs(command) ) )
             //handle error
    }
    else {  // parent

        if( command[ length - 1 ] != "&" ){

            int status;
            waitpid( fork_result, &status, 0 );

            //continue after child is finished
           //( need to be here also after a SIGTSTP is raised by ctrl+z )
        }
    }

それがフォアグラウンド プロセスである場合 (最後に「&」記号がなかった場合)、ctrl+z ( SIGTSTP ) でフォアグラウンド プロセス (子) を停止し、制御をに戻すことができる必要があります。停止した時点からの父 (私の端末) (waitpid)。

問題は、ctrl+z が押された後 (親がシグナル ハンドル メソッドでコントロールを取得し、kill( child_pid, SIGTSTP ) を使用して子を停止した後)、親が停止した場所から続行しないことです (waitpid )。シグナル処理メソッドが終了した後、どこに続くのかわかりません。

シグナル処理メソッドで run() を呼び出すと機能しますが、再帰は必要ありません。すぐに StackOverFlow を取得できると思います...

シグナル処理メソッドのコードは次のとおりです。

void sigtstp_handel( int signal ){  

    if( is_foreground_process_alive() )
        kill( foreground_process_pid, SIGTSTP );

    // run();
}  

編集:問題になるかどうかはわかりませんが、Linux Ubuntu 12.10 を使用しています。とはいえ、Home Work の場合は、他のシステムで動作させる必要があります。

ありがとう!

4

1 に答える 1

2

の公式 POSIX リファレンスを読むwaitpid:

トレースされた

The status of any child processes specified by pid that are stopped,
and whose status has not yet been reported since they stopped, shall
also be reported to the requesting process.

したがって、WUNTRACEDフラグを追加するwaitpidと、待機中のプロセスが停止したときに呼び出しが返されるはずです。

于 2012-11-21T02:39:40.257 に答える