I'm trying to get the exit code of a subprocess. On Linux and FreeBSD I can go like so:
[0] [ishpeck@kiyoshi /tmp]$ uname
FreeBSD
[0] [ishpeck@kiyoshi /tmp]$ cat tinker.c
#include <stdio.h>
#include <sys/wait.h>
int main(void)
{
FILE *proc = popen("ls", "r");
printf("Exit code: %d\n", WEXITSTATUS(pclose(proc)));
return 0;
}
[0] [ishpeck@kiyoshi /tmp]$ gcc tinker.c -o tinker
[0] [ishpeck@kiyoshi /tmp]$ ./tinker
Exit code: 0
[0] [ishpeck@kiyoshi /tmp]$ grep WEXITSTATUS /usr/include/sys/wait.h
#define WEXITSTATUS(x) (_W_INT(x) >> 8)
However, on OpenBSD, I get complaints from the compiler...
[0] [ishpeck@ishberk-00 /tmp]$ uname
OpenBSD
[0] [ishpeck@ishberk-00 /tmp]$ cat tinker.c
#include <stdio.h>
#include <sys/wait.h>
int main(void)
{
FILE *proc = popen("ls", "r");
printf("Exit code: %d\n", WEXITSTATUS(pclose(proc)));
return 0;
}
[0] [ishpeck@ishberk-00 /tmp]$ gcc tinker.c -o tinker
tinker.c: In function 'main':
tinker.c:7: error: lvalue required as unary '&' operand
[1] [ishpeck@ishberk-00 /tmp]$ grep WEXITSTATUS /usr/include/sys/wait.h
#define WEXITSTATUS(x) (int)(((unsigned)_W_INT(x) >> 8) & 0xff)
I don't really care how it's done, I just need the exit code.
This leads me to believe that I would also have this problem on Mac: http://web.archiveorange.com/archive/v/8XiUWJBLMIKYSCRJnZK5#F4GgyRGRAgSCEG1
Is there a more portable way to use the WEXITSTATUS macro? Or is there a more portable alternative?
This macro queries the child termination status provided by the wait and waitpid functions. If the WIFEXITED macro indicates that the child process exited normally, the WEXITSTATUS macro returns the exit code specified by the child process.
The simple answer is "sys/types. h is a fundamental header and contains many types required by other headers".
OpenBSD's implementation of WEXITSTATUS
uses the address-of operator (unary &
) on its argument, effectively requiring that its argument have storage. You are calling it with the return value of a function, which doesn't have storage, so the compiler complains.
It is unclear whether OpenBSD's WEXITSTATUS
is POSIX-compliant, but the problem can be easily worked around by assigning the return value of pclose()
to a variable:
int status = pclose(proc);
printf("Exit code: %d\n", WEXITSTATUS(status));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With