Unix C - Portable WEXITSTATUS
c, freebsd, openbsd, portability, unix
Solution
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));
Problem
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?