title: Unix C Shell - Job Control Issue!
body: <p>I've been working on creating my own Unix Shell in C to get practice with its interworkings...I'm having some <strong>issues getting my process to run in the background while allowing my shell to continue taking user input</strong>.  If you could take the time to dissect what I've got below it would be much appreciated! </p>
  
  <p><em>My variables are below, just incase that helps understand things more...</em></p>
  
  <pre><code>#define TRUE 1
  
  static char user_input = '\0'; 
  
  static char *cmd_argv[5]; // array of strings of command
  static int cmd_argc = 0; // # words of command
  
  static char buffer[50]; // input line buffer
  static int buffer_characters = 0;
  int jobs_list_size = 0;
  
  /* int pid; */
  int status;
  int jobs_list[50];
  </code></pre>
  
  <p><strong>Here is my main function.</strong></p>
  
  <pre><code>int main(int argc, char **argv)
  {           
      printf("[MYSHELL] $ ");
  
      while (TRUE) {
          user_input = getchar();
          switch (user_input) {
  
              case EOF:
                  exit(-1);
  
              case '\n':
                  printf("[MYSHELL] $ ");
                  break;
  
              default:
                  // parse input into cmd_argv - store # commands in cmd_argc
                  parse_input();
  
                  //check for zombie processes
                  check_zombies();
  
                  if(handle_commands() == 0)
                      create_process();
                      printf("\n[MYSHELL] $ ");
  
          }
      }
      printf("\n[MYSHELL] $ ");
      return 0;
  }
  </code></pre>
  
  <p><strong>Parse Input...I know, I can't get readline to work on this box :(</strong>
  If provided the <strong>&amp;</strong> operator, create the job in the background... (see below)</p>
  
  <pre><code>void parse_input()
  {
      // clears command line
      while (cmd_argc != 0) {
          cmd_argv[cmd_argc] = NULL;
          cmd_argc--; 
      }
  
      buffer_characters = 0;
  
      // get command line input
      while ((user_input != '\n') &amp;&amp; (buffer_characters &lt; 50)) {
          buffer[buffer_characters++] = user_input;
          user_input = getchar();
      }
  
      // clear buffer
      buffer[buffer_characters] = 0x00;
  
      // populate cmd_argv - array of commands
      char *buffer_pointer;
      buffer_pointer = strtok(buffer, " ");
  
      while (buffer_pointer != NULL) { 
          cmd_argv[cmd_argc] = buffer_pointer;
          buffer_pointer = strtok(NULL, " ");
  
          //check for background process execution
          if(strcmp(cmd_argv[cmd_argc], "&amp;")==0){
              printf("Started job %d\n", getpid());    
              make_background_job();
          }
  
          cmd_argc++;
      }
  }
  </code></pre>
  
  <p><strong>Make background job.</strong> Closes child process STDIN, opens new STDIN, and executes.</p>
  
  <pre><code>void make_background_job()
  {
      int pid;
      pid = fork();
      fclose(stdin); // close child's stdin
      fopen("/dev/null", "r"); // open a new stdin that is always empty
  
      fprintf(stderr, "Child pid = %d\n", getpid());
  
      //add pid to jobs list
      jobs_list[jobs_list_size] = getpid();
  /*     printf("jobs list %d", *jobs_list[jobs_list_size]);         */
      jobs_list_size++;
  
      execvp(*cmd_argv,cmd_argv);
  
      // this should never be reached, unless there is an error
      fprintf (stderr, "unknown command: %s\n", cmd_argv[0]);     
  }
  </code></pre>
  
  <p><strong>The meat of my job control.  Fork spawns child, returns 0 for child and PID for parent.</strong></p>
  
  <pre><code>void create_process()
  {   
      pid_t pid;
  
      pid = fork();
      status = 0;
  
      switch(pid){
          case -1:
              perror("[MYSHELL ] $ (fork)");
              exit(EXIT_FAILURE);
          case 0:            
              make_background_job();
              printf("\n\n----Just made background job in case 0 of create_process----\n\n");        
              break;
  
          default:
              printf("\n\n----Default case of create_process----\n\n");
              // parent process, waiting on child...
              waitpid(pid, &amp;status, 0);
  
              if (status != 0) 
                  fprintf  (stderr, "error: %s exited with status code %d\n", cmd_argv[0], status);
              else
                  break;
      }
  }
  </code></pre>
  
  <p>My problem is when I execute a job in the background, its executing the command twice, and exiting out of the shell.  (It functions correctly otherwise if no background process is enabled).  Where am I getting confused?  I think it may have to do with issues regarding my PID's, as I'm not populating the list correctly either in 'make_background_job'</p>
  
  <p>Here is my output, the example.sh just throws out helloWorld:</p>
  
  <pre><code>[MYSHELL] $ ./example.sh &amp;
  Started job 15479
  Child pid = 15479
  Child pid = 15481
  Hello World
  Hello World
  </code></pre>