问题
I need to catch the returned value of a child process..
The problem is: with using the waitpid() function I can catch only 8 bits of the returned value
WEXITSTATUS(wstatus) 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.
How can I catch the full int value that is returned from main()
?
EDIT: Stackoverflow forced me to edit the question as it linked another answered question but it has nothing to do with mine!
回答1:
POSIX requires that the full exit value be passed in the si_status
member of the siginfo_t
structure passed to the SIGCHLD handler, if it is appropriately established via a call to sigaction
with SA_SIGINFO
specified in the flags:
If si_code is equal to CLD_EXITED, then si_status holds the exit value of the process; otherwise, it is equal to the signal that caused the process to change state. The exit value in si_status shall be equal to the full exit value (that is, the value passed to _exit(), _Exit(), or exit(), or returned from main()); it shall not be limited to the least significant eight bits of the value.
(Emphasis mine).
Note that upon testing, it appears that Linux does not honour this requirement and returns only the lower 8 bits of the exit code in the si_status member. Other operating systems may correctly return the full status; FreeBSD does. See test program here.
Be wary, though, that is not completely clear that you will receive an individual SIGCHLD signal for every child process termination (multiple pending instances of a signal can be merged), so this technique is not completely infallible. It is probably better to find another way to communicate a value between processes if you need more than 8 bits.
回答2:
The short answer is that you pretty much can't. Traditionally, the exit status of a process under Unix/Linux is propagated as an 8-bit value. You can return any integer from main
that you like, you can call exit
with any integer that you like, but only the low-order 8 bits are available to the parent via any of the wait
functions.
The reason WEXITSTATUS
is documented as returning only the low-order 8 bits of the status is that those are the only bits that there are.
If you're trying to pass arbitrary data from a subprocess back to its parent, the exit status is not the way to do it. Me, I normally print data to the standard output, and have the caller capture it using popen
or the equivalent.
Addendum: I thought the kernel didn't even record the full int
-sized exit status, and that it was therefore impossible to retrieve it by any means, but as davmac explains in another answer, you might be able to get your hands on it in a SIGCHLD
handler.
回答3:
I believe the only ways you can get it is by strace
ing the process and looking for the exit system calls, which now seem to be exit_group
, by debugging, or possibly by using some ugly hacks like LD_PRELOAD
. I.e. nothing unintrusive.
For zombie processes the exit code can be found in the last column of /proc/<pid>/stat but it is already & 0xFF
.
来源:https://stackoverflow.com/questions/50982730/how-to-get-the-full-returned-value-of-a-child-process