title: foreground signal tcsetpgrp c
body: <p>I'm making my own shell cause why the hell not.
  When you run a command and end it with &amp;, the process with be run in the background, so I'd like to make an fg command that you can use to put the background process to the foreground.</p>
  
  <p>I have some troubles making the fg function.
  If i understand it correctly, putting signal() in the child process will let the child process receive a signal.
  Signal receives two arguments, signum and the handler function.
  We're gonna use tcsetpgrp() to set a given background process to foreground. So in lsh_fg I call tcsetpgrp(STDIN_FILENO, pid).</p>
  
  <p>So signum should be sigttou so it can receive the signal from tcsetpgrp().</p>
  
  <p>I don't know what should be put inside the handler, since tcsetpgrp() is supposed to do as the man page describes it:
  "
  The  function tcsetpgrp() makes the process group with process group ID
         pgrp the foreground process group on the  terminal  associated  to  fd
  "
  As I understand it, tcsetpgrp() is sending a signal to the process that has signal(sigttou,handler), which is put to the foreground when it receives it. But I clearly misunderstood this since it's not working.</p>
  
  <p>My questions: How should I understand the way tcsetpgrp() and signal(sigttou,handler) work together? And what should my handler include?
  I really appreciate your answers cause i really got stuck here :-)
  See my code below:
  Ps: I'm new to C and system programming and this is my first post ever so any constructive criticism regarding my code is warmly welcome
  THANKS A LOT :D</p>
  
  <pre><code>#include &lt;sys/wait.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;signal.h&gt;
  
  pid_t pid;
  
  int toke_c;
  //function declaration for the function pointers
  int lsh_cd(char **args);
  int lsh_pwd(char **args);
  int lsh_exit(char **args);
  int lsh_fg(char **args);
  
  //An array of functions:
  int (*builtin_func[]) (char **) = {
    &amp;lsh_cd,
    &amp;lsh_pwd,
    &amp;lsh_exit,
    &amp;lsh_fg
  };
  
  //An array of the given strings:
  char *builtin_str[] = {
    "cd",
    "pwd",
    "exit",
    "fg"
  };
  
  ///built in functions cd and pwd
  
  int lsh_fg(char **args){
  tcsetpgrp(STDIN_FILENO, pid);
    return 1;
  }
  
  void fg_handler()
  {
  //What to put here???
  }
  
  ///built in functions cd and pwd
  int lsh_cd(char **args)
  {
    if (args[1] == NULL) {
      fprintf(stderr, "lsh: cd: no arguments given\n");
    } else {
      if (chdir(args[1]) != 0) {
        perror("lsh");
      }
    }
    return 1;
  }
  
  int lsh_pwd(char **args)
  {
  char * cwd;
      cwd=getcwd (NULL,0);
      printf ("%s\n ", cwd);
    return 1;
  }
  
  int lsh_exit(char **args)
  {
    return 0;
  }
  
  /* Handlers Here*/
  void killer()
  {
    if (pid == 0)
      exit(0);
  }
  
  void handler()
  {
    //I DON'T KNOW WHAT TO PUT HERE
  }
  
  int lsh_launch(char **args)
  {
  
    int status=0;
    pid = fork();
    if (pid == 0) {
      // child process
      signal(SIGINT, killer);
      if (execvp(args[0], args) == -1) {
        fprintf(stderr,"Command not found in $PATH\n");
      }
      return 1;
    } else if (pid &lt; 0) {
      //error
      perror("lsh");
    } else {
      // parent
      signal(SIGINT, killer);
      waitpid(pid, &amp;status, WUNTRACED);
    }
    return 1;
  }
  
  int lsh_background(char **args)
  {
  
    pid_t pid;
    int status=0;
    pid = fork();
    if (pid == 0) {
      // child process
      setpgid(0, 0);
      signal(SIGINT, killer);
      signal(SIGTTOU, fg_handler);
      if (execvp(args[0], args) == -1) {
        fprintf(stderr,"Command not found in $PATH\n");
      }
      return 1;
    } else if (pid &lt; 0) {
      //error
      perror("lsh");
    } else {
      // parent
      signal(SIGTTOU, fg_handler);
      signal(SIGINT, killer);
    }
    return 1;
  }
  
  //if a command was entered that we've been using
  int lsh_exec(int argc, char **args)
  {
    int i;
    if (args[0] == NULL) {return 1;}
    int tresh=4;
  
    char **args1=malloc(toke_c*sizeof(char *));
      int j;
      for(j=0;j&lt;toke_c-1;j++){
        args1[j]=args[j];
      }
  
    if(strcmp(args[toke_c-1],"&amp;")==0){
        return lsh_background(args1);
        }
  
        for (i = 0; i &lt; tresh; i++) {
        if (strcmp(args[0], builtin_str[i]) == 0) {
          return (*builtin_func[i])(args);
        }
      }
  
    return lsh_launch(args);
  }
  
  #define MAX_STR 256
  
  //reading the line
  char *lsh_lread(void)
  { 
    char *str = malloc (MAX_STR);
    fgets (str, MAX_STR, stdin);
  }
  
  //tokenizer
  char **lsh_tokenizer(char *line)
  {
    int bufsize = 64;
    int pos_t = 0;
    char **tokens = malloc(bufsize * sizeof(char*));
    char *token;
    token = strtok(line, " \t\r\n\a");
  
    while (token != NULL) {
      tokens[pos_t] = token;
      pos_t++;
  
      token = strtok(NULL, " \t\r\n\a");
    }
    tokens[pos_t] = NULL;
    toke_c=pos_t;
  
    return tokens;
  }
  
  
  void lsh_loop(void)
  {
    int argc;
    char *line;
    char **args;
    int status;
  
    do {
      printf("&gt;&gt; ");
      line = lsh_lread();
      args = lsh_tokenizer(line);
      status = lsh_exec(argc,args);
      free(line);
      free(args);
    } while (status);
  }
  
  
  int main(int argc, char **argv)
  {
    lsh_loop();
  
    return 0;
  }
  </code></pre>