Question

I am trying to access the EXIT STATUS of the forked child process from the parent, but I am getting weird answers. Sometimes, I get 256 or sometimes I get a negative number depending upon whether I specify &status or just status. I know I am really close. Can someone provide me with a little help how I will get the EXIT_STATUS

Here is my code

pid_t  pid;
int *status;
if((pid = fork()) < 0)
    fprintf(stdout, "Error forking child process\n");

else if (pid == 0)
{
    execvp(input[0], input);
    fprintf(stdout, "Invalid process!!\n");
    _exit(EXIT_FAILURE);

}
else
{
    while (waitpid(-1, status, 0) != pid);
    fprintf(stdout, "The status is %d\n", &status);
}
Was it helpful?

Solution

You're seeing this behavior because you do not initialize the pointer you're using, and therefore you are invoking undefined behavior, which means that, quite literally, anything at all might happen. Try changing status to be an int (instead of an int*):

int status;
/* ... */
while (waitpid(-1, &status, 0) != pid);
fprintf(stdout, "The status is %d\n", status);

Your code, on the other hand:

int * status;

This creates a pointer to int and does not initialize it.

while (waitpid(-1, status, 0) != pid);

Here you pass this pointer to waitpid(), which will write at the pointed-to location. Since you have not initialized the pointer, it's writing to an unspecified memory location! This may crash the process or overwrite allocated memory elsewhere, which may lead to a spontaneous crash later, or data corruption!

fprintf(stdout, "The status is %d\n", &status);

This prints out the address of the pointer variable -- not the value it points to! Using *status instead of &status may allow this part to work, but you're still using an uninitialized pointer.

I would strongly suggest that you turn your compiler's warning settings up to the maximum (pass -Wall with gcc) to make it warn on everything. It would have caught the usage of an uninitialized pointer, and it may have also warned you about using the %d format specifier with a pointer-type value.

OTHER TIPS

Don't use large numbers or negative numbers for return values, they confuse things. As an example, on a 32 bit system:

for int: 255 is 0x000000ff -1 is 0xffffffff. So if you return any of the eight bit blocks in -1 they are are all 0xff or 255.

If you call exit(1) or exit(2) or exit(3), or some other small positive number things will play out better for you. In the parent be sure call WIFEXITED(&status) first.

Since you seem to want to use the exit status to "tell" you something about the problem that occurred try sysexits: http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits

Or simply use EXIT SUCCESS or EXIT_FAILURE ex:return EXIT_SUCCESS; or exit(EXIT_FAILURE); which are guaranteed to work - ie., give you a success or failure as a return.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top