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?
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 8bit number (max 256): 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).
this code is from: How to send a simple string between two programs using pipes?
writer.c
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int fd;
char * myfifo = "/tmp/myfifo";
/* create the FIFO (named pipe) */
mkfifo(myfifo, 0666);
/* write "Hi" to the FIFO */
fd = open(myfifo, O_WRONLY);
write(fd, "Hi", sizeof("Hi"));
close(fd);
/* remove the FIFO */
unlink(myfifo);
return 0;
}
reader.c
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#define MAX_BUF 1024
int main()
{
int fd;
char * myfifo = "/tmp/myfifo";
char buf[MAX_BUF];
/* open, read, and display the message from the FIFO */
fd = open(myfifo, O_RDONLY);
read(fd, buf, MAX_BUF);
printf("Received: %s\n", buf);
close(fd);
return 0;
}
the code, probably the parent/reader, should delete the fifo node, perhaps by calling rm
.
Otherwise the fifo entry is left in existence, even across a re-boot, just like any other file.