Search code examples
cexecfork

C - Retrieving a child's exit status that is larger than 8 bits


Note: For simplicity, I don't include much error checking and my sample code doesn't really serve any practical purpose.

What I want:

I want a program that fork()s a child process and has it invoke a process using execl(). My parent then retrieves the exit code for that process. This is fairly trivial.

What I tried:

int main(int argc, char** argv) {
    int ch = fork();
    if(ch == -1) {
        perror(NULL);
    }else if(ch == 0) {
        // In child, invoke process
        execl("/path/process", "process", 0);
    }else {
        // In parent, retrieve child exit code
        int status = 0;
        wait(&status);
        // print exit status
        if(WIFEXITED(status)) printf("%d\n", WEXITSTATUS(status));
    }
}

My issue:

WEXITSTATUS() only retrieves the lower 8 bits of the exit value while I need all the bits from the int value. Specifically, process performs a calculation and the result may be larger than 8 bits. It may even be negative, in which case, the highest bit will be needed to represent the correct value.

What else I tried:

Also, while looking around, I found the pipe() function. However, I'm not sure how to use it in this situation since, after calling execl(), I can't write to a file descriptor from within the child.

So how can I go about retrieving a child's exit status that is larger than 8 bits?


Solution

  • I don't think that what you are trying to accomplish it's possible, because in Linux (actually i think it's UX specific), a process exit code is an 8-bit number: 0-255 (and as a convention, 0 means success, anything else means error) and lots of stuff rely on this fact (including the macros you used). Take the following piece of code:

    // a.c
    int main() {
        return 257;
    }
    

    If you compile it (gcc a.c), and run the resulting executable (a.out) checking (echo $?) its exit code (that will be truncated by the OS; hmm or is it the shell?) it will output 1 (wrap around arithmetic): 257 % 256 = 1.

    As an alternative as you mentioned, you could use pipe (this post is pretty descriptive) or sockets (AF_UNIX type).