web-dev-qa-db-ja.com

wait(&status)を使用しましたが、statusの値は256です。なぜですか?

私のコードには次の行があります:

t = wait(&status); 

子プロセスが機能している場合、statusの値は0です。

しかし、機能しないのになぜ256を返すのでしょうか。また、エラーが発生したときに子プロセスでexitに指定された引数の値を変更しても、何も変更されないのはなぜですか(たとえば、exit(1)ではなくexit(2))。

ありがとうございました

編集:私はLinuxを使用しており、GCCでコンパイルしました。

私はこのようにステータスを定義しました

int status;
t = wait(&status); 
8
Simon

このような与えられたコード...

_int main(int argc, char **argv) {
    pid_t pid;
    int res;

    pid = fork();
    if (pid == 0) {
        printf("child\n");
        exit(1);
    }

    pid = wait(&res);
    printf("raw res=%d\n", res);

    return 0;
}
_

... resの値は_256_になります。これは、waitからの戻り値が、プロセスの終了ステータスとプロセスが終了した理由の両方をエンコードするためです。一般に、waitからのゼロ以外の戻り値を直接解釈しようとしないでください。 _WIF..._マクロを使用する必要があります。たとえば、プロセスが正常に終了したかどうかを確認するには、次のようにします。

_ WIFEXITED(status)
         True if the process terminated normally by a call to _exit(2) or
         exit(3).
_

そして、終了ステータスを取得するには:

_ WEXITSTATUS(status)
         If WIFEXITED(status) is true, evaluates to the low-order 8 bits
         of the argument passed to _exit(2) or exit(3) by the child.
_

例えば:

_int main(int argc, char **argv) {
    pid_t pid;
    int res;

    pid = fork();
    if (pid == 0) {
        printf("child\n");
        exit(1);
    }

    pid = wait(&res);
    printf("raw res=%d\n", res);

    if (WIFEXITED(res))
        printf("exit status = %d\n", WEXITSTATUS(res));
    return 0;
}
_

詳細については、wait(2)のマニュアルページを参照してください。

11
larsks

ステータスコードには、子プロセスがどのように終了したかに関するさまざまな情報が含まれています。ステータスコードから情報を取得するためにマクロが提供されています。

Linuxのwait(2)から:

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 argu-
   ment, not a pointer to it, as is done in wait() 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().

   WEXITSTATUS(status)
          returns  the  exit status of the child.  This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a
          return statement in main().  This macro should be employed only if WIFEXITED returned true.

   WIFSIGNALED(status)
          returns true if the child process was terminated by a signal.

   WTERMSIG(status)
          returns the number of the signal that caused the child process to terminate.  This macro should be employed only if WIFSIGNALED returned true.

   WCOREDUMP(status)
          returns true if the child produced a core dump.  This macro should be employed only if WIFSIGNALED returned true.  This macro is not specified in POSIX.1-2001 and is not available on some UNIX
          implementations (e.g., AIX, SunOS).  Only use this enclosed in #ifdef WCOREDUMP ... #endif.

   WIFSTOPPED(status)
          returns true if the child process was stopped by delivery of a signal; this is possible only if the call was done using WUNTRACED or when the child is being traced (see ptrace(2)).

   WSTOPSIG(status)
          returns the number of the signal which caused the child to stop.  This macro should be employed only if WIFSTOPPED returned true.

   WIFCONTINUED(status)
          (since Linux 2.6.10) returns true if the child process was resumed by delivery of SIGCONT.
3
Thomas Shaw

提案:次の「プロセス完了ステータス」マクロのいずれかを試してください。

http://www.gnu.org/software/libc/manual/html_node/Process-Completion-Status.html

例:

  int status = 0;
  ..
  int retval = wait (&status);
  if (WIFEXITED(status)) 
    printf("OK: Child exited with exit status %d.\n", WEXITSTATUS(status));
  else
    printf("ERROR: Child has not terminated correctly.\n");
0
FoggyDay