When I run the following code (headers and main entry ommitted)
void fork11()
{
pid_t pid[N];
int i;
int child_status;
for (i = 0; i < N; i++)
if ((pid[i] = fork()) == 0)
exit(100+i); /* Child */
for (i = N-1; i >= 0; i--) {
pid_t wpid = waitpid(pid[i], &child_status, 0);
if (WIFEXITED(child_status)) {
printf("Child %d terminated with exit status %d\n", wpid, WEXITSTATUS(child_status));
printf("child_status: %d\n", child_status);
} else {
printf("Child %d terminate abnormally\n", wpid);
}
}
}
the result is
Child 5126 terminated with exit status 104
child_status: 26624
Child 5125 terminated with exit status 103
child_status: 26368
Child 5124 terminated with exit status 102
child_status: 26112
Child 5123 terminated with exit status 101
child_status: 25856
Child 5122 terminated with exit status 100
child_status: 25600
with some digging around I find WEXITSTATUS
is a simple macro
#define WEXITSTATUS(x) ((_W_INT(x) >> 8) & 0x000000ff)
take child process 5126 for example, waitpid
converts 104
to 26624=0x6800
, WEXITSTATUS
converts 26624
back to 104=0x68
, I tried to look up source code of waitpid
but ended up with some kernel functions which I can't understand... could anyone explain a little bit about how does waitpid
convert exit code? It seems fairly simple in the above example but I think it's much more than that, thanks!
When a process exits, the return value passed to the exit()
function is used as a parameter for the actual int
(4 bytes) passed to any process that waits for it. In addition to the 8 bits of this status code, more information is being passed.
For example, in the actual (final) exit code (the entire 4 bytes), it's being specified whether the process was signaled or not.
As seen here about WEXITSTATUS
:
This consists of the least significant 8 bits of the status argument that the child specified in a call to
exit(3)
...
This means that processes cannot exit with codes that require more than 8 bits.
User contributions licensed under CC BY-SA 3.0