Sossenbinder
Sossenbinder

Reputation: 5302

Why are my forked processes not returning the value I want to get back?

I currently have to write a program which creates as much forked processes as the user wants, then wait for all of them to complete and let them return a random number between 1 and 6.

This is my code so far:

#include <time.h>
#include <stdlib.h>
#include <stdio.h>

int main(){

  int n,i;
  int *returnvalue, value;
  int pid;
  int waitingID;

  returnvalue = &value;

  printf("How many processes to start?\n");
  scanf("%d",&n);

  for(i=0; i < n; i++){
    pid = fork();
    if(pid==0){
      printf("I am %d, from iteration %d\n",getpid(), i);
    }
    else if(pid > 0){
      waitingID = waitpid(pid, returnvalue, 0);
      printf("Return-value of %d is: %d\n", waitingID, *returnvalue);
      break;
    }
    else{
      printf("A problem occured.");
    }
  }

  srand(time(NULL));
  exit((rand()%6)+1);

  return 0;
}

It actually basically works so far, but I am never getting a number between 1 and 6, but rather some values like 768, 512, 256 and so on.

It feels like the random line is just being ignored.

How can I fix my code in order to return proper random values?

Upvotes: 0

Views: 39

Answers (1)

John Bollinger
John Bollinger

Reputation: 180161

The value waitpid() returns via its second argument is not the exit code of the collected process. Rather, it is a bitmask containing the exit code (if in fact the process exited) along with several other details. There is a collection of macros declared in wait.h by which you can extract the various pieces.

In particular, given waitpid(pid, returnvalue, 0) > 0, you can determine whether, in fact, the process exited (as opposed, for example, to being stopped) by testing WIFEXITED(*returnValue). If indeed it did, then you can get the exit status WEXITSTATUS(*returnValue). Thus, you might write

    else if (pid > 0){
      waitingID = waitpid(pid, returnvalue, 0);
      if (waitingID < 0) {
          perror("While waiting on a child process");
      } else if (waitingId == 0) {
          printf("wait() unexpectedly returned 0\n");
      } else if (WIFEXITED(*returnValue)) {
          printf("Process %d exited with code: %u\n", waitingID,
              WEXITSTATUS(*returnvalue));
      } else {
          printf("Process %d was stopped or continued\n", waitingID);
      }
      break;
    }

Upvotes: 3

Related Questions