title: How to use a file pointer of a file descriptor with multiple child processes without getting "Bad file descriptor" error in C?
body: <p>I am implementing a scenario in which the parent process forks a number of child processes, these child processes do a computation and return the result to the parent process via a pipe. Since the child processes have to use an external library's data types (GMP's mpz_t type), they need to use this library's own output stream function. This function allows a file pointer as an input instead of file descriptor. Therefore, I obtain file pointer of the pipe's writing end and use to write some data. Below is given child and parent process portions of the code:</p>
  
  <pre><code>pid_t ppid;
  ppid = getpid();
  struct sigaction sig;
  sigemptyset(&amp;sig.sa_mask);
  sig.sa_flags = 0;
  sig.sa_handler = sig_usr;
  
  if(sigaction(SIGINT,&amp;sig,NULL) != 0)
      printf("\ncan't catch SIGINT\n");
  
  if(sigaction(SIGUSR1,&amp;sig,NULL) != 0)
      printf("\ncan't catch SIGINT\n");
  
  pid_t childpid;
  
  pid_t childpids[operand1Length*operand2Length];
  int childPIDInd = 0;
  
  //Create pipe: (must do before fork() so FDs are inherited by child)
  int pipefd[2];  //array to hold pipe FDs
  pipe(pipefd);
  
  for(i=operand2Length-1, k=0; i&gt;=0; i--, k++){
      for(j=operand1Length-1, l=0; j&gt;=0; j--, l++){
  
          childpid = fork();
  
          switch(childpid){
              case -1:
                  //fork error
                  perror("fork failed!\n");
                  exit(EXIT_FAILURE);
  
              case 0:
                  close(pipefd[0]);
                  subOperandLength = subOperands[k].length;
  
                  FILE* fp = NULL;
  
                  fhe_mul(subOperands[k].operand[subOperandLength-1-k-l], num1-&gt;operand[j], num2-&gt;operand[i], pk);
  
                  while(WritePermit);  // unless parent process sends a signal any child process cannot enter this critical section.
  
                  fp = fdopen(pipefd[1], "w");
  
                  if(fp == NULL)
                      fprintf(stderr, "Child Process #%d file pointer is NULL. Error: %s. Pipe FD: %d\n", getpid(), strerror(errno), pipefd[1]);  
                      //Except the child process which enters the critical section first, 
                      //for all other child processes fp is NULL.
  
                  gmp_fprintf(fp, "%Zd\n", subOperands[k].operand[subOperandLength-1-k-l]);
                  gmp_fprintf(fp, "%d\n", k);
                  gmp_fprintf(fp, "%d\n", subOperandLength-1-k-l);
  
                  fflush(fp);
                  fclose(fp);
  
                  kill(ppid, SIGUSR1);
  
                  exit(EXIT_SUCCESS);
  
              default:
                  childpids[childPIDInd] = childpid;
                  childPIDInd++;
  
                  close(pipefd[1]);
  
                  if(i == 0 &amp;&amp; j == 0){ // last child was created
                      kill(childpids[0], SIGINT);
  
                      mpz_t deneme;
                      mpz_init(deneme);
  
                      FILE* fs = fdopen(pipefd[0], "r");
  
                      int forIndex, pidIndex;
  
                      for(forIndex=0, pidIndex=1; forIndex&lt;4; forIndex++, pidIndex++){
                          while(WritePermit2);
                          while((gmp_fscanf(fs, "%Zx\n", &amp;deneme)) &gt; 0){
                              gmp_fprintf(stdout, "Parent Process #%d: %Zd\n", getpid(), deneme);
                          }
                          kill(childpids[pidIndex], SIGINT);
                          WritePermit2=1;
                      }
  
                      fclose(fs);
  
                      int status;
                      int i=0;
                      int clean = 1;
                      while (i &lt; operand1Length*operand2Length) {
                          wait(&amp;status);
                          if(!WIFEXITED(status))
                              clean = 0;
                          i++;
                      }
  
                      if(!clean){
                          printf("I am having some problems with my children! :'(\n");
                          exit(EXIT_FAILURE);
                      }
  
          }
      }
  }
  </code></pre>
  
  <p>Only for one of the child processes <em>fp</em> works. Then, somehow, it becomes NULL, so gmp_fprintf raises error at other child processes.</p>
  
  <p>Please, do not hesitate to ask if you need more detail about the code. Thank you for your help in advance!</p>