title: Why does writing to a named pipe continue after no one is reading?
body: <p>I'm doing some experiments to learn about named pipes. It's my understanding that the OS will block a program that writes to a named pipe until another program reads from the named pipe. So I've written two programs, <code>startloop</code> and <code>readbyte</code>. <code>startloop</code> creates a fifo and continually writes to it with each read of the client (<code>readbyte</code>):</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/stat.h&gt;
  
  int main(int argc, char *argv[]) {
      const char num = 123;
      mkfifo("fifo", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
      int fd = open("fifo", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
      while (1) {
          printf("loop_start\n");
          write(fd, &amp;num, sizeof(num));
      }
      close(fd);
      return 0;
  }
  </code></pre>
  
  <p><code>readbyte</code> reads one byte from the fifo when run:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;fcntl.h&gt;
  
  int main(int argc, char *argv[]) {
      char num;
      int fd;
      if ((fd = open(argv[1], O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
          perror("Cannot open input file\n"); exit(1);
      }
  
      read(fd, &amp;num, sizeof(num));
      printf("%d\n", num);
      close(fd);
      return 0;
  }
  </code></pre>
  
  <p><code>readbyte</code> prints the number as expected when run on "fifo":</p>
  
  <pre><code>hostname:dir username$ ./readbyte fifo 
  65
  </code></pre>
  
  <p>As I expect, <code>loopstart</code> doesn't print anything until I read from the fifo with <code>readbyte</code>. However, when it becomes unblocked, it writes to "fifo" several times instead of immediately being suspended. Why is this?</p>
  
  <pre><code>hostname:dir username$ ./startloop
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  loop_start
  </code></pre>