title: pipe-fork-dup-exec not working
body: <p>I am trying to build a fake shell by creating a bash subprocess and sending input into and fetching output from it with another thread. It seems my calls of write() is successful but I am unable to get any output from it. Here is my code and some output on the terminal.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;unistd.h&gt; 
  #include &lt;istream&gt;
  #include &lt;fstream&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;cstdio&gt;
  #include &lt;thread&gt;
  #include &lt;cassert&gt;
  
  
  void read_and_write(int fd) {
      char* buffer = NULL;
      size_t size = 0;
      FILE* fp = fdopen(fd, "r");
      assert(fp);
  
      loop:
      printf("writing thread open\n");
      while (getline(&amp;buffer, &amp;size, fp) != -1) {
          printf("writing\n");
          printf("%s", buffer);
      }
      printf("done_printing\n");
      goto loop;
  
      free(buffer);
  }
  
  int main(int argc, char const *argv[]){
      std::string user_in;
  
      int stderr_pipe[2];
      int stdout_pipe[2];
      int stdin_pipe[2];
  
      pipe(stderr_pipe);
      pipe(stdout_pipe);
      pipe(stdin_pipe);
  
      pid_t bash = fork();
      if (bash == -1) {
          perror("fork failed");
          goto cleanup;
      } else if (bash == 0) {
          close(stdin_pipe[1]);
          close(STDIN_FILENO);
          dup2(stdin_pipe[0], STDIN_FILENO);
  
          close(stdout_pipe[0]);
          close(STDOUT_FILENO);
          dup2(stdout_pipe[1], STDOUT_FILENO);
  
          close(stderr_pipe[0]);
          close(STDERR_FILENO);
          dup2(stderr_pipe[1], STDERR_FILENO);
  
          printf("starting shell\n");
          execlp("bash", "bash", NULL);
          perror("exec failed");
          goto cleanup;
      } else {
          char* stdout_buffer = NULL;
          char* stderr_buffer = NULL;
          size_t stderr_size = 0;
          size_t stdout_size = 0;
          size_t bytesread_stderr = 0;
          size_t bytesread_stdout = 0;
  
          close(stdin_pipe[0]);
          close(stdout_pipe[1]);
          close(stderr_pipe[1]);
  
          std::thread t(read_and_write, stdout_pipe[0]);
          t.detach();
  
          while (std::getline(std::cin, user_in)) {
              fprintf(stderr, "%s\n", "reading ");
              ssize_t bytes = write(stdin_pipe[1], user_in.c_str(), user_in.size());
              printf("%zd bytes written\n", bytes);
          }
  
          int status;
          waitpid(bash, &amp;status, 0);
          return 0;
      }
  
      cleanup:    
      return 1;
  
      return 0;
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>writing thread open
  ls 
  reading 
  2 bytes written
  echo hello
  reading 
  10 bytes written
  whoami
  reading 
  6 bytes written
  </code></pre>
  
  <p>P.S. There are some cleanup left to do, but I just want to get the code working first.</p>