Search code examples
cunixexit-codewaitpid

waitpid wrong usage?


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);
}

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.