title: Print and read from xterm in a multithreaded C program using cat, tee and fifos
body: <p>I am trying to create a chat interface in my C program.
  The program use two fifos to communicate with a forked <code>xterm</code> running the commands <code>cat fifo_out</code> and <code>tee fifo_in &gt; /dev/null</code> at the same time. 
  Then a thread is opened for reading input in the *fifo_in
   coming from the terminal thanks to <code>tee</code>, in the same time another thread prints message in <em>fifo_out</em> and things get displayed in xterm.</p>
  
  <p>All seems to work pretty well... Except when a message has been printed while writing some text in the terminal, splitting the entered text in two parts. This cause a segfault!</p>
  
  <p>Do you have any idea why it happens like that ?</p>
  
  <p>Here is a minimal example:</p>
  
  <pre><code>int open_terminal(pid_t *pid, int *pipe)
  {
    mkfifo("fifo_in", 0600);
    mkfifo("fifo_out", 0600); 
    pid_t p = fork();
    int fd_in, fd_out;
    switch (p) {
      case -1:
        return -1;
      case 0:
          execlp("xterm", "xterm", "-e", "cat fifo_out &amp; tee fifo_in &gt; /dev/null", NULL);
          exit(EXIT_FAILURE);
          break;
      default:
          if ((fd_in = open("fifo_in", O_RDONLY)) == - 1)
            return -1;
          if ((fd_out = open("fifo_out", O_WRONLY)) == - 1)
            return -1;
          *pid = p;
          pipe[0] = fd_in; pipe[1] = fd_out;
          return 0;
    }
    return -1;
  }
  
  
  void *message_thread(void *args)
  {
    int *fd_out = (int *)args;
    while (1) {
      dprintf(*fd_out, "You're awesome!\n");
      sleep(5);
    }
  }
  
  
  void *input_thread(void *args)
  {
    int *fd_in = (int *)args;
    FILE *f = fdopen(*fd_in, "r");
    while (1) {
      size_t n;
      char *line;
      getline(&amp;line, &amp;n, f);
      printf("Read: %s", line);
      free(line);
      if(strcmp(line, "exit\n") == 0)
        return NULL;
    }
  }
  
  
  int main(int argc, char *argv[])
  {
    pid_t pid;
    int pipe[2];
    if (open_terminal(&amp;pid, pipe) == -1) {
      printf("Can't open terminal.\n");
      return 1;
    }
    pthread_t mt, it;
    pthread_create(&amp;mt, NULL, message_thread, &amp;pipe[1]);
    pthread_create(&amp;it, NULL, input_thread, &amp;pipe[0]);
  
    pthread_join(it, NULL);
  
    return 0;
  }
  </code></pre>
  
  <p>To reproduce my conditions, run the program input some text, wait until some text is printed after your text then type again and enter.</p>