title: Reading and Writing to file is not finishing until after the program finishes
body: <p>What my program is doing is that it takes 3 commands such as <code>wc</code> <code>md5sum</code> etc, commands that operate on files from Linux. It also takes a file path name as input as well. It creates forks for each command and then it stores the command output into a file. After all these complete I print out the command output and result time etc in <code>main</code>. </p>
  
  <p>The problem I am having is that commands that take longer to run such as <code>wc</code> on a big file, the command output isn't being saved into the file until after the program is completely finished. Therefore it isn't printing out in my results. </p>
  
  <p>I am not sure why this is happening because the parent should print results until child processes are complete. I need some help with this or a point in the right direction. I would prefer just storing the command output in a <code>char *</code> instead of writing to file, but I can't figure out how to redirect the output to a char buffer for return. Thanks in advance.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;assert.h&gt;
  #include &lt;time.h&gt;
  
  #define MAXIN 255
  #define SEP "--------------------------------------------------------------------------------"
  
  int currProc = 0;
  const char *procStrFin[] = {"First process finished...", "Second process finished...", "Third process finished..."};
  int p1file = 0;
  int p2file = 0;
  int p3file = 0;
  
  struct Response
  {
    int pid1;
    int pid2;
    int pid3;
    char *result1;
    char *result2;
    char *result3;
    double time1;
    double time2;
    double time3;
  };
  
  //Fork and run command with args
  struct Response runCmd(char *command1, char *command2, char *command3, char *file)
  {
    struct Response res;
    res.result1 = "";
    res.result2 = "";
    res.result3 = "";
  
    /*
      Command 1 Parse
      */
    char *fullCommand1 = strcat(command1, " ");
    fullCommand1 = strcat(fullCommand1, file);
    //Create an array of split commands for arg1 of execvp
    char *p1s = strtok(fullCommand1, " ");     //start token pointer
    char *splitCommand1[strlen(fullCommand1)]; //init split command array based on size of full command
    int i1 = 0;                                //init counter
    while (p1s != NULL)                        //Loop through each word and store in array
    {
      splitCommand1[i1++] = p1s;
      p1s = strtok(NULL, " ");
    }
    splitCommand1[i1] = NULL; //NULL terminate array
  
    /*
      Command 2 Parse
      */
    char *fullCommand2 = strcat(command2, " ");
    fullCommand2 = strcat(fullCommand2, file);
    //Create an array of split commands for arg1 of execvp
    char *p2s = strtok(fullCommand2, " ");     //start token pointer
    char *splitCommand2[strlen(fullCommand2)]; //init split command array based on size of full command
    int i2 = 0;                                //init counter
    while (p2s != NULL)                        //Loop through each word and store in array
    {
      splitCommand2[i2++] = p2s;
      p2s = strtok(NULL, " ");
    }
    splitCommand2[i2] = NULL; //NULL terminate array
  
    /*
      Command 3 Parse
      */
    char *fullCommand3 = strcat(command3, " ");
    fullCommand3 = strcat(fullCommand3, file);
    //Create an array of split commands for arg1 of execvp
    char *p3s = strtok(fullCommand3, " ");     //start token pointer
    char *splitCommand3[strlen(fullCommand3)]; //init split command array based on size of full command
    int i3 = 0;                                //init counter
    while (p3s != NULL)                        //Loop through each word and store in array
    {
      splitCommand3[i3++] = p3s;
      p3s = strtok(NULL, " ");
    }
    splitCommand3[i3] = NULL; //NULL terminate array
  
    /*
      FORKS
      */
    double time_spent1 = 0.0;
    double time_spent2 = 0.0;
    double time_spent3 = 0.0;
    clock_t begin = clock();
    clock_t end;
  
    int p1 = fork();
    if (p1 &lt; 0)
    {
      //Output redirect to file and run command
      close(STDOUT_FILENO);
      p1file = open("p1.temp", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
      printf("CMD1:[SHELL 1] STATUS CODE=-1");
    }
    else if (p1 == 0) //P1 Controlled
    {
      //Output redirect to file and run command
      close(STDOUT_FILENO);
      p1file = open("p1.temp", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
      execvp(splitCommand1[0], splitCommand1);
    }
    else //Parent Controlled
    {
      end = clock();
      time_spent1 += (double)(end - begin) / CLOCKS_PER_SEC;
      printf("%s\n", procStrFin[currProc]);
      res.pid1 = p1;
      res.time1 = time_spent1;
      currProc++;
      int p2 = fork();
      if (p2 &lt; 0)
      {
        //Output redirect to file and run command
        close(STDOUT_FILENO);
        p2file = open("p2.temp", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
        printf("CMD2:[SHELL 2] STATUS CODE=-1");
      }
      else if (p2 == 0) //P2 Controlled
      {
        close(STDOUT_FILENO);
        p2file = open("p2.temp", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
        execvp(splitCommand2[0], splitCommand2);
      }
      else //Parent Controlled
      {
        end = clock();
        time_spent2 += (double)(end - begin) / CLOCKS_PER_SEC;
        printf("%s\n", procStrFin[currProc]);
        res.pid2 = p2;
        res.time2 = time_spent2;
        currProc++;
        int p3 = fork();
        if (p3 &lt; 0)
        {
          //Output redirect to file and run command
          close(STDOUT_FILENO);
          p3file = open("p3.temp", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
          printf("CMD3:[SHELL 3] STATUS CODE=-1");
        }
        else if (p3 == 0) //P3 Controlled
        {
          close(STDOUT_FILENO);
          p3file = open("p3.temp", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
          execvp(splitCommand3[0], splitCommand3);
        }
        else //Parent Controlled
        {
          end = clock();
          time_spent3 += (double)(end - begin) / CLOCKS_PER_SEC;
          printf("%s\n", procStrFin[currProc]);
          res.pid3 = p3;
          res.time3 = time_spent3;
          int parent = wait(NULL); //Wait on children
          return res;
        }
      }
    }
  }
  
  //Quick max function
  float max(float num1, float num2)
  {
    return (num1 &gt; num2) ? num1 : num2;
  }
  
  /* Take file path and read from file*/
  char *readFromFile(char *filename)
  {
    char *buffer = 0;
    long length;
    FILE *f = fopen(filename, "rb"); //was "rb"
  
    if (f)
    {
      fseek(f, 0, SEEK_END);
      length = ftell(f);
      fseek(f, 0, SEEK_SET);
      buffer = (char *)malloc((length + 1) * sizeof(char));
      if (buffer)
      {
        fread(buffer, sizeof(char), length, f);
      }
      fclose(f);
    }
    buffer[length] = '\0';
    // for (int i = 0; i &lt; length; i++) {
    //     printf("buffer[%d] == %c\n", i, buffer[i]);
    // }
    //printf("buffer = %s\n", buffer);
  
    return buffer;
  }
  
  //Deletes file
  int deleteFile(char *filename)
  {
    if (remove(filename) == 0)
    {
      return 0;
    }
    else
    {
      return 1;
    }
  }
  
  //MAIN
  int main(int argc, char const *argv[])
  {
    char buf[MAXIN];
    //Command 1
    printf("Welcome to MASH!\nmash-1&gt;");
    fgets(buf, MAXIN, stdin);
    buf[strcspn(buf, "\n")] = 0; //remove newlines
    char *cmd1 = strdup(buf);
  
    //Command 2
    printf("mash-2&gt;");
    fgets(buf, MAXIN, stdin);
    buf[strcspn(buf, "\n")] = 0; //remove newlines
    char *cmd2 = strdup(buf);
  
    //Command 3
    printf("mash-3&gt;");
    fgets(buf, MAXIN, stdin);
    buf[strcspn(buf, "\n")] = 0; //remove newlines
    char *cmd3 = strdup(buf);
  
    // File Command
    printf("file&gt;");
    fgets(buf, MAXIN, stdin);
    buf[strcspn(buf, "\n")] = 0; //remove newlines
    char *fileCmd = strdup(buf);
  
    struct Response response = runCmd(cmd1, cmd2, cmd3, fileCmd);
  
    //Command Results Output
    int pre = 12;
    int cmd1Len = 80 - (strlen(cmd1) + pre);
    int cmd2Len = 80 - (strlen(cmd2) + pre);
    int cmd3Len = 80 - (strlen(cmd3) + pre);
    char cmd1Sep[80] = "";
    for (int i = 0; i &lt; cmd1Len; i++)
    {
      strcat(cmd1Sep, "-");
    }
    char cmd2Sep[80] = "";
    for (int i = 0; i &lt; cmd2Len; i++)
    {
      strcat(cmd2Sep, "-");
    }
    char cmd3Sep[80] = "";
    for (int i = 0; i &lt; cmd3Len; i++)
    {
      strcat(cmd3Sep, "-");
    }
  
    //Get file input
    char *cmd1Out = readFromFile("p1.temp");
    char *cmd2Out = readFromFile("p2.temp");
    char *cmd3Out = readFromFile("p3.temp");
  
    printf("-----CMD 1: %s%s\n", cmd1, cmd1Sep);
    printf("%sResult took:%fms\n", cmd1Out, response.time1);
    printf("-----CMD 2: %s%s\n", cmd2, cmd2Sep);
    printf("%sResult took:%fms\n", cmd2Out, response.time2);
    printf("-----CMD 3: %s%s\n", cmd3, cmd3Sep);
    printf("%sResult took:%fms\n", cmd3Out, response.time3);
    printf("%s\n", SEP);
    printf("Parent PID: %d\n", getpid());
    printf("Children process IDs: %d %d %d.\n", response.pid1, response.pid2, response.pid3);
    printf("Total elapsed time:%fms\n", max(response.time3, max(response.time2, response.time1)));
  
    //Delete Files
    // deleteFile("p1.temp");
    // deleteFile("p2.temp");
    // deleteFile("p3.temp");
    return 0;
  }
  </code></pre>
  
  <p>Example Output:</p>
  
  <pre class="lang-none prettyprint-override"><code>Welcome to MASH!
  mash-1&gt;wc
  mash-2&gt;md5sum
  mash-3&gt;grep -c the
  file&gt;big.log
  First process finished...
  Second process finished...
  Third process finished...
  -----CMD 1: wc------------------------------------------------------------------
  Result took:0.000070ms
  -----CMD 2: md5sum--------------------------------------------------------------
  Result took:0.000120ms
  -----CMD 3: grep----------------------------------------------------------------
  40
  Result took:0.000160ms
  --------------------------------------------------------------------------------
  Parent PID: 7664
  Children process IDs: 7665 7666 7667.
  Total elapsed time:0.000160ms
  </code></pre>