title: Is O_NONBLOCK being set a property of the file descriptor or underlying file?
body: <p>From what I have been reading on The Open Group website on <a href="http://www.opengroup.org/onlinepubs/009695399/functions/fcntl.html" rel="noreferrer"><code>fcntl</code></a>, <a href="http://www.opengroup.org/onlinepubs/009695399/functions/open.html" rel="noreferrer"><code>open</code></a>, <a href="http://www.opengroup.org/onlinepubs/009695399/functions/read.html" rel="noreferrer"><code>read</code></a>, and <a href="http://www.opengroup.org/onlinepubs/009695399/functions/write.html" rel="noreferrer"><code>write</code></a>, I get the impression that whether <code>O_NONBLOCK</code> is set on a file descriptor, and hence whether non-blocking I/O is used with the descriptor, should be a property of that file descriptor rather than the underlying file. Being a property of the file descriptor means, for example, that if I duplicate a file descriptor or open another descriptor to the same file, then I can use blocking I/O with one and non-blocking I/O with the other.</p>
  
  <p>Experimenting with a FIFO, however, it appears that it is not possible to have a blocking I/O descriptor and non-blocking I/O descriptor to the FIFO simultaneously (so whether <code>O_NONBLOCK</code> is set is a property of the underlying file [the FIFO]):</p>
  
  <pre><code>#include &lt;errno.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  
  int main(int argc, char **argv)
  {
      int fds[2];
      if (pipe(fds) == -1) {
          fprintf(stderr, "`pipe` failed.\n");
          return EXIT_FAILURE;
      }
  
      int fd0_dup = dup(fds[0]);
      if (fd0_dup &lt;= STDERR_FILENO) {
          fprintf(stderr, "Failed to duplicate the read end\n");
          return EXIT_FAILURE;
      }
  
      if (fds[0] == fd0_dup) {
          fprintf(stderr, "`fds[0]` should not equal `fd0_dup`.\n");
          return EXIT_FAILURE;
      }
  
      if ((fcntl(fds[0], F_GETFL) &amp; O_NONBLOCK)) {
          fprintf(stderr, "`fds[0]` should not have `O_NONBLOCK` set.\n");
          return EXIT_FAILURE;
      }
  
      if (fcntl(fd0_dup, F_SETFL, fcntl(fd0_dup, F_GETFL) | O_NONBLOCK) == -1) {
          fprintf(stderr, "Failed to set `O_NONBLOCK` on `fd0_dup`\n");
          return EXIT_FAILURE;
      }
  
      if ((fcntl(fds[0], F_GETFL) &amp; O_NONBLOCK)) {
          fprintf(stderr, "`fds[0]` should still have `O_NONBLOCK` unset.\n");
          return EXIT_FAILURE; // RETURNS HERE
      }
  
      char buf[1];
      if (read(fd0_dup, buf, 1) != -1) {
          fprintf(stderr, "Expected `read` on `fd0_dup` to fail immediately\n");
          return EXIT_FAILURE;
      }
      else if (errno != EAGAIN) {
          fprintf(stderr, "Expected `errno` to be `EAGAIN`\n");
          return EXIT_FAILURE;
      }
  
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>This leaves me thinking: is it ever possible to have a non-blocking I/O descriptor and blocking I/O descriptor to the same file and if so, does it depend on the type of file (regular file, FIFO, block special file, character special file, socket, etc.)?</p>