waitpidの戻り値の問題について


ある偶然のテストで、suプログラムのBUGを発見した後、問題の出所を調べることに着手した.まず,テストとしてコードを簡略化する.
int main(int argc, char *const argv[])
{
        pid_t pid = fork();
        if (!pid)
        {
                execv("/bin/ping", argv);
                //exit(3);
        } else
        {
                int status =-1;
                waitpid(pid, &status, 0);  
                printf("pppp exit = %d 
"
, status); exit(status); } }

上記の例では,サブプロセスが値を返す問題が見つかった.1.shellを使用するpingテストに失敗した場合の戻り値は1であるが、statusの値は512であり、プログラム全体の戻り値は0 2である.exit(1)exit(2)exit(3)をexecvの代わりに使うと256512,768の戻り値の法則が見つかり、一瞬目が覚めた!!
もう一度プログラミングマニュアルをよく見ると、すべてのプログラミング法の真相は公式ドキュメントにあり、検索された奇妙なコードを信じないでください!!!以下は戻り値の処理で、英語が上手ですべてが美しくて、蒼天は誰を許したことがありますか!
If status is not NULL, wait() and waitpid() store status information in the int to which it points. This integer can be inspected with the following macros (which take the integer itself as an argument, not a pointer to it, as is done inwait() and waitpid()!): WIFEXITED(status) returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main(). WIFSIGNALED(status) returns true if the child process was terminated by a signal.
マニュアルにはサンプルコードも親切に提供されています.私がいろいろな英語を無視しているのを責めています.
if (WIFEXITED(status)) {
   printf("exited, status=%d
"
, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("killed by signal %d
"
, WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("stopped by signal %d
"
, WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("continued
"
); }

最後に、このプログラムを改造します.ここでは静かにプログラムの実行が完了するのを待つだけなので、WIFEXITEDだけで終わります.
int main(int argc, char *const argv[])
{
        pid_t pid = fork();
        if (!pid)
        {
                execv("/bin/ping", argv);
        } else
        {
                int status =-1;
                waitpid(pid, &status, 0);  
                if (WIFEXITED(status)) {
                  exit(WEXITSTATUS(status));
                }
                exit(-1);
        }
}