title: Bad file descriptor when running cat command in a shell
body: <p>I'm trying to implement I/O redirection in a shell that I'm writing for a Unix-like OS (xV6). In the manual that I'm reading for the OS, I found the following code that would run in the shell for the execution of the cat command:</p>
  
  <pre><code>char *argv[2];
  argv[0] = "cat";
  argv[1] = 0;
  if(fork() == 0) {
      close(0);
      open("input.txt", O_RDONLY);
      exec("cat", argv);
  }
  </code></pre>
  
  <p>I modified the code to run in my shell which has the argv array located in another function, but it maintains the functionality. For some reason, when I run the <code>cat &lt; input.txt</code> the shell outputs: </p>
  
  <pre><code>cat: -: Bad file descriptor
  cat: closing standard input: Bad file descriptor
  </code></pre>
  
  <p>I'm still new to OS programming so I'm not exactly clear on all of the functionality of I/O redirection, but I think the code I have should work. What could be causing the problem. I have the code for the I/O redirection below:</p>
  
  <pre><code>case '&lt;':
      ecmd = (struct execcmd*)cmd;
      rcmd = (struct redircmd*)cmd;
  
      if(fork() == 0){
        close(0);
        open("input", O_RDONLY);
        execvp(ecmd-&gt;argv[0], ecmd-&gt;argv );
      }
      runcmd(rcmd-&gt;cmd);
      break;
  </code></pre>
  
  <h2>EDIT</h2>
  
  <p>I did <code>strace -e open ls</code> and got: </p>
  
  <pre><code>open("/etc/ld.so.cache",    O_RDONLY|O_CLOEXEC) = 3
  open("/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
  open("/lib/x86_64-linux-gnu/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
  open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
  open("/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
  open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
  open("/lib/x86_64-linux-gnu/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
  open("/proc/filesystems", O_RDONLY)     = 3
  open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
  a.out  sh.c  test
  +++ exited with 0 +++
  </code></pre>
  
  <h1>EDIT 2</h1>
  
  <p>For some reason, this code for the case works, but I'm not sure why:</p>
  
  <pre><code>case '&lt;':
      rcmd = (struct redircmd*)cmd;
      close(rcmd-&gt;fd);
      if(open(rcmd-&gt;file, rcmd-&gt;mode) &lt; 0){
        printf(2, "Cannot open file %s\n", rcmd-&gt;file);
        perror(rcmd-&gt;file);
        exit(1);
      }
      runcmd(rcmd-&gt;cmd);
      break;
  </code></pre>