title: Can write(2) return 0 bytes written*, and what to do if it does?
body: <p>I'd like to implement a proper <a href="https://linux.die.net/man/2/write" rel="noreferrer"><code>write(2)</code></a> loop that takes a buffer and keeps calling <code>write</code> until the entire buffer is written.</p>
  
  <p>I guess the basic approach is something like:</p>
  
  <pre><code>/** write len bytes of buf to fd, returns 0 on success */
  int write_fully(int fd, char *buf, size_t len) {
    while (len &gt; 0) {
      ssize_t written = write(fd, buf, len);
      if (written &lt; 0) {
        // some kind of error, probably should try again if its EINTR?
        return written;
      }
      buf += written;
      len -= written;
    }
    return 0;
  } 
  </code></pre>
  
  <p>... but this raises the question of whether <code>write()</code> can validly return 0 bytes written and what to do in this case. If the situation persists, the above code will just hot spin on the <code>write</code> call which seems like a bad idea. As long as something <em>other</em> than zero is returned you are making forward progress.</p>
  
  <p>The man page for <code>write</code> is a bit ambiguous. It says, for example:</p>
  
  <blockquote>
    <p>On success, the number of bytes written is returned (zero indicates
    nothing was written).</p>
  </blockquote>
  
  <p>Which seems to indicate that it is possible in some scenarios. Only one such scenario is explicitly called out:</p>
  
  <blockquote>
    <p>If  count  is zero and fd refers to a regular file, then write() may
    return a failure status if one of the errors below is detected.  If no
    errors are detected, or error detection is not performed, 0 will be
    returned without causing any other effect.  If count is zero and fd
    refers to a file other than a regular file, the results are not
    specified.</p>
  </blockquote>
  
  <p>That case is avoided above because I never call <code>write</code> with <code>len == 0</code>. There are lot of other cases where nothing could be written, but in general they all have specific error codes associated with them.</p>
  
  <p>The file itself will be a <code>open</code>ed from a path/name given on the command line. So it will <em>usually</em> be a regular file, but users may of course pass things like pipes, do input redirection, pass special devices like <code>/dev/stdout</code> and so on. I am at least in control of the <code>open</code> call and the  <code>O_NONBLOCK</code> flag is not passed to open. I can't reasonably check the behavior for all the file systems, all the special devices (and even if I could, more will be added), so I want to know <strong>how to handle this in a reasonable and general way</strong>.</p>
  
  <hr>
  
  <p>* ... for a non-zero buffer size.</p>