6

execve プロセスからそれを開始したプロセスに終了ステータス 0 を送信したい。成功すると execve が返されないため、その後は何もできません。しかし、execveが成功した場合は欲しいです。

4

2 に答える 2

6

以下を使用して、execが成功したことを確認できますFD_CLOEXEC

  • パイプを作成します。

  • フォーク。

  • 子では、パイプの読み取り側を閉じ、パイプFD_CLOEXECの書き込み側にフラグを設定します。次に、 に進みますexec。が成功した場合exec、パイプは により自動的に閉じられFD_CLOEXECます。失敗した場合execは、パイプにバイトを書き込んで終了します。

  • 親で、パイプの書き込み側を閉じ、読み取り側から読み取ります。0 バイト (EOF) を読み取った場合は、exec成功したことを意味します。パイプでバイトを読み取った場合、それはexec失敗したことを意味します。

errno障害が発生した場合にパイプ経由で書き込まれたデータは、 afterの値などのエラー情報を送信するために使用できますexec

簡潔にするためにエラー チェックを省略したコードは、次のようになります。

int pipe_fds[2];
pipe(pipe_fds);
if (!fork()) {
  close(pipe_fds[0]);
  fcntl(pipe_fds[1], F_SETFD, F_CLOEXEC);
  execve(...);
  write(pipe_fds[1], "", 1);
  _exit(1);
}
else {
  int n;
  char out;
  close(pipe_fds[1]);
  n = read(pipe_fds[0], &out, 1);
  if (n == 0)
    printf("exec successful\n");
  else
    printf("exec failed\n");
  close(pipe_fds[0]);
}

他のスレッドが独自のプロセスを並行して実行する可能性がある場合、この手法は安全ではない可能性があることに注意してください。問題は、パイプが作成されてから close-on-exec フラグが設定されるまでに遅延があることです。関係のないスレッドがその重要なウィンドウで fork して exec した場合、子はそれを継承pipe_fds[1]し、それを閉じないため、親がハングします。pipe2これは、close-on-exec フラグが設定されたパイプをアトミックに作成できるLinux 固有の呼び出しを使用して修正できます。

于 2013-03-19T10:50:21.217 に答える
2

終了までにプロセスが開始されるのを待つにはfork()、次を使用できますwait()

/* parent */
int status;
while (wait(&status) != uproc.pid) {
    printf("waiting for child to exit");
    }

そして、この質問に基づいて

子の終了ステータスは、変数waitで関数によって提供されます。status

マクロを使用して終了ステータスを取得しますがWEXITSTATUS、プログラムが正常に終了した (つまり、関数exitから呼び出された、または返された) 場合のみです。main

if (WIFEXITED(status))
    printf("Child exit status: %d\n", WEXITSTATUS(status));
else
    printf("Child exited abnormally\n");
于 2013-03-19T10:50:07.747 に答える