Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Multiprocess parent return value

Im wondering about the nature of the variable status and when its returned in a function.

Ive set my function to get an error, but if I dont do return status >> 8(127) and instead do return status, I get a return value of 0.

Ive used return WEXITSTATUS (status) in the past and itd return the correct status number.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

My questions are if WEXITSTATUS actually does the operation status >> 8?
And when doing Multiprocessing and the parent process exists properly is it better to verify with WIFEXITED(status) then return WEXITSTATUS (status) rather than doing what I do?

int main {
    int status;
    int filedes[2];
    pid_t pid_enfant;
    pipe(filedes);

    if (pid_child == 0) {
        ...
        char *tab[] = {"/bin/bash", "-c", arg[1], NULL};
        execv("/bin/bash", arg[1]);
        return 1;
    } else {
        ...
        pid_t pid_child = wait(&status);
        return status >> 8;                   -- // return this vs this below
        //if (WIFEXITED(status) && pid_valide == pid_child)
              //return WEXITSTATUS (status);
    } 
}

>Solution :

To answer your your question regarding WEXITSTATUS, the answer is yes; it is meant to shift the status down by 8 bits.

   WEXITSTATUS(wstatus)
         returns the exit status of the child.  This consists of
         the least significant 8 bits of the status argument that
         the child specified in a call to exit(3) or _exit(2) or as
         the argument for a return statement in main().  This macro
         should be employed only if WIFEXITED returned true.

Further, it explicitly states that the value of WEXITSTATUS(wstatus) is only valid if WIFEXITED(wstatus) is non-zero. So for your code to be correct with this specification, you should have

pid_t pid_child = wait(&status);
if (WIFEXITED(status))
{
  return WEXITSTATUS(status);
}
else
{
  // child did not terminate normally
}

As to why you should check this, here’s a toy example:

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
  int signal = /* choose your favourite signal, or 0 */;
  
  switch (fork())
  {
    case -1:
      perror("fork");
      return -1;
    
    case 0:
      if (signal) { raise(signal); }
      return 0;

    default:
      {
        int status;
        pid_t child = wait(&status);        
        printf("child=%d, status=%04x\n", child, status);
        
        if (WIFEXITED(status))
        {
          puts("good exit");
          return WEXITSTATUS(status);
        }
        else
        {
          puts("bad exit");
          return -1;
        }
      }
      break;
  }
}

If we do not raise anything in the child and get a clean exit, we’ll see child=..., status=0000 in the parent, and would take the ‘good exit’ branch returning 0, as expected. However, if we raise something like SIGSEGV in the child, then the parent will get child=..., status=008b. Now, if you blindly did status >> 8, then your parent would return 0 just like the ‘good exit’ path, but clearly the child did not exit cleanly.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading