I was doing an exercise for university where I had to return a value with exit, that value was actually a count of something. This could be above 255 (which exit() can\'t ha
And the real question in this topic, is the same thing to call this macro in my code as dividing by 256?
It will probably always work in the cases where the child process terminates normally (i.e., by calling exit(), not by a segmentation fault, assertion failure, etc.).
The status stored by waitpid()
encodes both the reason that the child process was terminated and the exit code. The reason is stored in the least-significant byte (obtained by status & 0xff
), and the exit code is stored in the next byte (masked by status & 0xff00
and extracted by WEXITSTATUS()
). When the process terminates normally, the reason is 0 and so WEXITSTATUS
is just equivalent to shifting by 8 (or dividing by 256). However, if the process is killed by a signal (such as SIGSEGV), there is no exit code, and you have to use WTERMSIG
to extract the signal number from the reason byte.
If the status variable is a signed 16-bit integer (a 'short') on a machine where 'int' is a 32-bit quantity, and if the exit status is in the range 128..255, then WEXITSTATUS() still gives you a correct value where dividing by 256 or simply shifting right will give you an incorrect value.
This is because the short will be sign extended to 32-bits, and the masking undoes the the sign extension, leaving the correct (positive) value in the result.
If the machine used 16-bit integers, then the code in WEXITSTATUS() would probably do shift then mask to ensure similar behaviour:
#define WEXITSTATUS(status) (((status)>>8) & 0xFF)
It is because the implementation takes care of such details for you that you should use the WEXITSTATUS() macro.
As far as I can tell from checking the Single Unix Spec, your system happens to store the exit status in the second-to-rightmost octet, but I don't believe the standard does. So, you should use the macros for at least a few reasons:
WEXITSTATUS
does. Less so with other approaches. If you saw the hand-rolled version of WIFSIGNALED
, would you recognize it? How much longer would it take than WIFSIGNALED
.Here 0xff00 is a binary mask (link text). ANDing it with a value sets all bits to zero, except the second byte (counting from the right).
You should only use WEXITSTATUS
on a process which is known to have exited normally. This information is given by the WIFEXITED
macro.
And the real question in this topic, is the same thing to call this macro in my code as dividing by 256?
The macro makes the code more readable, and it's guaranted to work on any Posix-compliant implementation. As far as I know Posix doesn't specify the format of the status, so you can't expect your code to work everywhere.