Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

wait

I have this line in my code :

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)?

Thank you

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

I defined status like this

int status;
t = wait(&status); 
like image 304
Simon Avatar asked Jun 10 '14 00:06

Simon


3 Answers

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.

like image 184
larsks Avatar answered Nov 15 '22 17:11

larsks


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");
like image 25
FoggyDay Avatar answered Nov 15 '22 18:11

FoggyDay


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.
like image 22
Thomas Shaw Avatar answered Nov 15 '22 18:11

Thomas Shaw