title: Explaining read, write system calls behavior with STDOUT_FILENO, STDIN_FILENO, and \n
body: <p><br/>
  I know there are many questions here that talk about write, read system calls and file descriptors in C. I tried searching a bit but I really couldn't find what I'm looking for so...</p>
  
  <h3>EOF on new line when reading from STDIN_FILENO?</h3>
  
  <p>Let's say I have this code in <code>test.c</code>:</p>
  
  <pre><code>int main(void){
      char buff[8];
      int res;
      res=read(STDIN_FILENO, buff, 8);
      assert(res!=-1);
      res=write(STDOUT_FILENO, buff, res);
      assert(res!=-1);
      return 0
  }
  </code></pre>
  
  <p>with header files included and all. Why do I have this behavior when executing the file <code>test</code>?</p>
  
  <pre><code>$ ./test
  1
  1
  $ ./test
  11$
  </code></pre>
  
  <p>In the first execution I use a new line (<kbd>enter</kbd>) while in the second execution I use <kbd>ctrl</kbd>+<kbd>d</kbd> to put an eof. <strong>Why does a new line character act like an eof in this case?</strong></p>
  
  <p>I mean read should try to read 8 characters. Shouldn't it have waited in the first execution? what if I wanted to type <code>'1\n2\n3'</code> in the buffer? How to make my program work?</p>
  
  <p>I've got two ideas but I don't know how to verify them:</p>
  
  <ol>
  <li>Is this behavior related in any way to how processes read from a pipe? The idea of reading only what's in there even if more could be coming? If so: how to make the read call a blocking system call? (I hope I'm not misusing the term).</li>
  <li>Could the terminal be putting an EOF character when a new line character is typed? I don't think it's true but if I type <code>123456789</code>+<kbd>enter</kbd> while executing <code>test</code> stops taking input after the enter key, uses characters from 1 to 8 and the terminal executes 9 as command (which means it takes the 9 and the newline character). I just don't get it.</li>
  </ol>
  
  <h3>Why is the program still working if STDIN_FILENO and STDOUT_FILENO are switched by mistake?</h3>
  
  <p>So now I have another code, <code>test2.c</code>:</p>
  
  <pre><code>int main(void){
      char buff[8];
      int res;
      res=read(STDOUT_FILENO, buff, 8);
      assert(res!=-1);
      res=write(STDIN_FILENO, buff, res);
      assert(res!=-1);
      return 0;
  }
  </code></pre>
  
  <p>And I have the same behavior in both cases. <strong>Why don't read and write fail with <code>EBADF</code> ?</strong> Could this be some subtle tty-shell interaction thing I'm not aware of?</p>
  
  <p>Thanks!!</p>
  
  <p>N.B: If you have any suggestions on how to improve this question or the title please let me know.</p>