web-dev-qa-db-ja.com

子プロセスを終了し、execvp()からそのステータスを返す方法は?

私のシンプルなカスタムシェルでは、標準入力からコマンドを読み取り、execvp()でそれらを実行しています。その前に、現在のプロセスのフォークを作成し、その子プロセスでexecvp()を呼び出し、その直後に、exit(0)を呼び出します。

このようなもの:

pid = fork();

if(pid == -1) {
    perror("fork");
    exit(1);
}

if(pid == 0) {
    // CHILD PROCESS CODE GOES HERE...
    execvp(pArgs[0], pArgs);
    exit(0);
} else {
    // PARENT PROCESS CODE GOES HERE...
}

これで、execvp()で実行されるコマンドはエラーを返すことができますか?私はそれを適切に処理したいのですが、私は常にexit(0)を呼び出しています。これは、子プロセスが常に「OK」状態になることを意味します。

Execvp()呼び出しから適切なステータスを返し、exit()呼び出しに入れるにはどうすればよいですか? execvp()が返すint値を取得して、それを0ではなくexit()引数として渡す必要があります。それで十分ですか?

17
rfgamaral

親コードでwaitpid(3)またはwait(1)を使用して、子が終了してエラーメッセージが表示されるのを待つ必要があります。

構文は次のとおりです。

_pid_t waitpid(pid_t pid, int *status, int options);
_

または

_pid_t wait(int *status);
_

statusには終了ステータスが含まれます。 man pages を見て、解析方法を確認してください。


子プロセスからこれを行うことができないことに注意してください。 execvpを呼び出すと、子プロセスdies(すべての実用的な目的)であり、-置換exec 'dプロセスによって。 exit(0)に到達できる唯一の方法は、execvp自体が失敗した場合ですが、失敗は新しいプログラムが終了したためではありません。それはそもそも実行されなかったからです。

編集:子プロセスは本当に死にません。 PIDと環境は変更されませんが、コードとデータ全体がexec 'dプロセスで置き換えられます。 execが失敗しない限り、元の子プロセスに戻るnotを期待できます。

17
Nathan Fellman

親プロセスでwait()またはwaitpid()を使用します。ここの例: OSがプロセスを強制終了したときにコードを返す

また、子が死ぬと、SIGCHLDシグナルが親プロセスに送信されます。

3

あなたの質問から、あなたが何を求めているのかを理解するのは少し難しいです。そのため、関連するいくつかの問題を取り上げます。

  • execvp()は、(成功した場合)を返さないか、エラーを返します。子コードはハンドルエラー条件のみを必要とすることを意味します。子コードはexecvp()の結果をキャプチャし、その値をexit()で使用する必要があります。唯一の成功はexecvpが機能し、thatプロセスが0を返す(またはしない)ことを意味するため、子コードは決して0を返しません。
  • 親は、その終了ステータスに関するwaitpid()から子情報を取得できます。返されたstatusパラメータから情報をプルするために定義されたいくつかのマクロがあります。あなたの目的で注目に値するのは、子が「正常に」終了したかどうかを通知するWIFEXITEDと、exit()に渡される子のステータスを取得するWEXITSTATUSです。その他のマクロについては、waitpidのマニュアルページを参照してください。
3
dwc