6

現在、子プロセスを実行する必要がある C プログラムを作成しています。私は複数の子プロセスを同時に実行していないので、これはかなり簡単です。ビルトイン シェル プログラム (つまり、cat や echo など) は間違いなく正常に実行されていますが、これらのプログラムのいずれかが正常に実行されなかった場合に通知できるようにする必要もあります。次の簡略化されたコードでこれを試しています。

int returnStatus; // The return status of the child process.
pid_t pid = fork();

if (pid == -1) // error with forking.
{
   // Not really important for this question.
}
else if (pid == 0) // We're in the child process.
{
   execvp(programName, programNameAndCommandsArray); // vars declared above fork().

   // If this code executes the execution has failed.
   exit(127); // This exit code was taken from a exec tutorial -- why 127?
}
else // We're in the parent process.
{
   wait(&returnStatus); // Wait for the child process to exit.

   if (returnStatus == -1) // The child process execution failed.
   {
      // Log an error of execution.
   }
}

例えば、rm fileThat DoesntExist.txt を実行しようとすると、ファイルが存在しないので失敗と見なしたいと思います。どうすればこれを達成できますか? また、その execvp() 呼び出しは組み込みのシェル プログラムを正常に実行しますが、実行可能ファイルの現在のディレクトリ (つまり、このコードが内部で実行されているプログラム) 内のプログラムは実行しません。現在のディレクトリでプログラムを実行するために他に何かしなければならないことはありますか?

ありがとう!

4

3 に答える 3

18

これは、非常に洗練されたソリューションを備えた古典的な問題です。フォークする前pipeに、親に を作成します。の後fork、親はパイプの書き込み側を閉じ、read読み取り側からの試行をブロックする必要があります。fcntl子は読み取り側を閉じ、書き込み側に対してを使用して close-on-exec フラグを設定する必要があります。

ここで、子が正常に呼び出した場合execvp、パイプの書き込み側はデータなしで閉じられread、親では 0 が返さexecvpれます。子で失敗した場合、エラー コードがパイプに書き込まreadれ、親ではゼロ以外の値が返されます。 、親が処理するエラー コードを読み取った。

于 2012-12-04T19:08:08.930 に答える
3

wait(2)子プロセスの終了ステータス以上のものを提供します。実際の終了ステータスを取得するには、WIFEXITED()マクロを使用して子が正常に終了したかどうかをテストする必要があります (シグナルなどによる異常終了とは対照的に)。次に、WEXITSTATUS()マクロを使用して実際の終了ステータスを取得します。

wait(&status);
if(WIFEXITED(status))
{
    if(WEXITSTATUS(status) == 0)
    {
        // Program succeeded
    }
    else
    {
        // Program failed but exited normally
    }
}
else
{
    // Program exited abnormally
}

が現在のディレクトリでプログラムを実行するexecvp(3)には、現在のディレクトリを$PATH環境に追加するか (通常はお勧めできません)、フル パスを渡す必要があり./myprogramますmyprogram

于 2012-12-04T19:07:28.610 に答える
0

障害検出に関しては、exec() 関数が現在のプロセスを新しいプロセスに置き換えると、現在のプロセスはなくなります。実行されたプログラムが、要求されたことが成功か失敗かを判断するかどうかは問題ではありません。ただし、フォークの前の親プロセスは、コマンドの成功/失敗情報を含む可能性が高い子の終了コードを検出できます。

実行可能ファイルの検索に関しては、execvp() はシェルのアクションを複製し、現在のパスを検索します。作業ディレクトリで実行可能ファイルが見つからない場合は、ディレクトリが検索パスにない (またはファイルが実際には実行可能でない) 可能性があります。フルパス名で指定してみてください。

コマンドを実行して結果を待つだけの場合は、fork/exec で自分でビルドするのではなく、これを処理する system() 関数を使用することをお勧めします。

于 2012-12-04T19:05:30.053 に答える