Simon
Simon

Reputation: 6480

I used wait(&status) and the value of status is 256, why?

I have this code:

int status;
t = wait(&status); 

When the child process works, the value of status is 0, well.

But why does it return 256 when it doesn't work? And why changing the value of the argument given to exit in the child process when there is an error doesn't change anything (exit(2) instead of exit(1) for example)?

Edit : I'm on linux, and I compiled with GCC.

Upvotes: 16

Views: 50885

Answers (3)

paulsm4
paulsm4

Reputation: 121779

SUGGESTION: try one of the following "Process Completion Status" macros:

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

EXAMPLE:

  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");

Upvotes: 1

larsks
larsks

Reputation: 312028

Given code like this...

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;
}

...the value of res will be 256. This is because the return value from wait encodes both the exit status of the process as well as the reason the process exited. In general, you should not attempt to interpret non-zero return values from wait directly; you should use of the WIF... macros. For example, to see if a process exited normally:

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

And then to get the exit status:

 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.

For example:

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;
}

You can read more details in the wait(2) man page.

Upvotes: 19

Thomas Shaw
Thomas Shaw

Reputation: 81

The status code contains various information about how the child process exited. Macros are provided to get information from the status code.

From wait(2) on linux:

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.

Upvotes: 6

Related Questions