title: How to use exec() system call correctly after a fork?
body: <p>I'm having an issues with my program I want my run_uptime function to display the output of uptime function every 5 seconds to stdout. However, I don't know what I'm doing wrong in my code, I've looked through various other questions related to exec() and fork() but I still can't seem to find a solution. One other thing is how can I rewrite the fork call without the switch statement, but that's more of an aesthetic reason but I still wanna know how to do it. I'd appreciate any help. Please explain why though, because I'm a newbie. </p>
  
  <p>Problem Statement, What the program should do:</p>
  
  <p>You shall create a program that does the following:    </p>
  
  <p>o Upon startup, read the total runtime (in seconds) the user wants the program to run for. A default value of 10 seconds will be used if the user does not include the time when launching the program (i.e., rohan> a3 30 causes the program to run for 30 seconds, rohan> a3 you would run the program   for 10 seconds).     </p>
  
  <p>o The program shall create three child processes, then busy-wait until all child processes are complete and then exit.     </p>
  
  <p>o The first child process shall implement a clock which prints the hour, minute, and second once every second (in human readable localtime)    </p>
  
  <p>o The second child process shall run the uptime (/usr/bin/uptime) program once every 5 seconds           </p>
  
  <p>o The third child process shall implement a countdown timer that prints the minutes and seconds remaining, once every second, until 00:00 is reached.       </p>
  
  <p>o The third child process, upon reaching 00:00, shall notify (signal, or pipe, or ..., etc, your choice of IPC mechanism) the first and second child process’ (i.e. it's sibling processes) telling them to terminate and then terminate itself.       </p>
  
  <p>o Once all child processes have terminated, the parent shall print a friendly message then exit.</p>
  
  <p>Here is my code, it compiles but I need a different output. </p>
  
  <pre><code>/* Include Files */
  #include &lt;stdio.h&gt;
  #include &lt;time.h&gt; /* for local time functions */
  #include &lt;unistd.h&gt; /* for fork */
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/wait.h&gt; /* for wait function */
  #include &lt;sys/types.h&gt; /* for pid_t */
  
  /* remember 0 means program finished correctly, by unix convention */
  
  /* Definitions */
  #define TIME_QUANTUM 5 //Default time for program to run!
  
  /* Functions */
  void system_clock(void); //function to display human readable time.
  void time_to_kill(int timequota); //prints out the time in a countdown fashion, till program ends.
  void run_uptime(void);
  
  /* Variables */
  int procpipe1[2]; //Allocate Pipe Set 1
  int procpipe2[2]; //Allocate Pipe Set 2
  char bufkill[12]; //Buffer to hold kill signal, to tell other processes to end.
  
  
      int main(int argc, const char * argv[])
  {
      int time=TIME_QUANTUM;
      if(argc==2)
      {
          time=atoi(argv[1]); //looking to see if user wants a custom running time.
      }
  
     //Creating pipes before creating child processes, so they could communicate.
     pipe(procpipe1);
     pipe(procpipe2);
  
     printf("Pipes opened, now creating child process!\n");
  
      //Create Child Processes and run associated functions in them.
      //Creating the the 1st child process!
  
      switch (fork())
      {
          case -1:
              printf("Error: couldn't create 1st Child!\n");
              exit(1);
  
          case 0: //If no error in creating child process then create process!
              printf("\nChild 1 process: time_to_kill executing...\n");
              system_clock();
              exit(1);
  
          default:
              break;
      }
  
      //Creating the 2nd child process!
      switch (fork())
      {
          case -1:
              printf("Error: couldn't create 3rd Child!\n");
          case 0: //If no error in creating child process then create process!
              printf("\nChild 2 process: time_to_kill executing...\n");
              run_uptime();
              exit(1);
  
          default:
              break;
      }
  
      //Creating the 3rd child process!
      switch (fork())
      {
          case -1:
              printf("Error: couldn't create 2nd Child!\n");
              exit(1);
          case 0: //If no error in creating child process then create process!
              printf("\nChild 3 process: time_to_kill executing...\n");
              time_to_kill(time); 
              exit(1);
  
          default:
              break;
      }
  
      printf("Parent closing pipes\n");
  
      //Need to close the pipes after using them, close communications between processes.
      //pipe close error checking
  
      close(procpipe1[0]);
      close(procpipe1[1]);
      close(procpipe2[0]);
      close(procpipe1[1]);
  
      printf("Parent waiting for children completion...\n");
  
      //Wait for child processes to end before ending Main, the overall process 
      //that spawned the child processes.
  
      wait(NULL);
      wait(NULL);
      wait(NULL);
  
      printf("Time to print out a Friendly Message!\n");
      printf("Parent process finishing, bye!\n");
      exit(EXIT_SUCCESS);   
  }//end main
  
  //This is the 1st Child Process
  void system_clock(void) 
  {
      /* variable of system_clock()*/
      //temp buffer to get termination string
      char str1[12];
      time_t now;
      struct tm *lcltime;
  
      strcpy(str1, "time to die"); //store this string into str1 local variable
  
      close(procpipe1[0]);
      close(procpipe1[1]);
      close(procpipe2[1]);
  
      //show current time
      for(;;)
      {
          now = time ( NULL );
          lcltime = localtime ( &amp;now );
  
          //read message from child 2 process
          int status = read(procpipe2[0], bufkill, 12);
  
          if ((strcmp(str1, bufkill)) != 0)
          {
              //printf("Read status: %d, Buffer= %s\n", status, bufkill);
              printf ("The time is %d:%d:%d\n", lcltime-&gt;tm_hour, lcltime-&gt;tm_min, lcltime-&gt;tm_sec );
              //show ever second
              sleep(1);
          }
  
  
          //if end signal came in
          //if(ret == 0)
          if ((strcmp(str1, bufkill)) == 0)
          {
              //close reading end
              close(procpipe2[0]);
  
              //return back to parent
              printf("Child 1 process: system_clock ending...\n");
              exit(1);
          }
      }  
  }//end system_clock
  
  //This is the 2nd Child Process
  void run_uptime() 
  {
      // variable of run_uptime
      //temp buffer to get termination string
      char str1[12];
  
      strcpy(str1, "time to die"); //store this string into str1 local variable
  
      close(procpipe1[0]);
      close(procpipe1[1]);
      close(procpipe2[1]);    
  
      for(;;)
      {
          //read message from child 2 process
          int status = read(procpipe2[0], bufkill, 12);
  
          if ((strcmp(str1, bufkill)) != 0)
          {
              //printf("Read status: %d, Buffer= %s\n", status, bufkill);
              execl("/usr/bin/uptime","uptime",NULL);
              //show ever 5 seconds
              sleep(1);
          }
  
  
          //if end signal came in
          if ((strcmp(str1, bufkill)) == 0)
          {
              //close reading end of pipe.
              close(procpipe2[0]);
  
              //return back to parent
              printf("Child 2 process: run_uptime ending...\n");
              exit(1);
          }
      }  
  }//end run_uptime
  
  //This is the 3rd Child Process
  void time_to_kill(int timequota) //This process signals the other processes to stop.
  {
      /* Need to change this signal */
      //string signal to end process 
      strcpy(bufkill, "time to die");
  
      //Pipes that aren't being used close them.
      close(procpipe1[0]);
      close(procpipe1[1]);
      close(procpipe2[0]);
  
      for( ;timequota&gt;0; timequota--)
      {
          printf("Count Down: 00:0%d\n", timequota);
          //send signal to child 1 process and child 2 process not to end
          write(procpipe2[1], "not die yet",12); //write into pipe2 statement that doesn't signal stopping process.
          //count down every second
          sleep(1);
      }
  
      //send signal to child 1 process and child 2 process to be terminate itself.
      write(procpipe2[1], bufkill, sizeof(bufkill)); //write into pipe2 the kill statement stored in bufkill
  
      //close pipe 2 writing end
      close(procpipe2[1]); 
  
      //back to main
      printf("Count Down: 0\n");
      printf("Child 3 process: time_to_kill ending...\n");
      exit(1);
  }//end time_to_kill
  </code></pre>