Search code examples
cglibc

Is it possible for fwrite to write some bytes but return zero?


According to the man page of fwrite:

fread() and fwrite() return the number of items successfully read or written (i.e., not the number of characters). If an error occurs, or the end-of-file is reached, the return value is a short item count (or zero).

I'm wondering if it possible for fwrite(ptr, 65537, 1, fp) to write only 512 bytes and yet return zero?

I tried to get a quick source trace to glibc-2.12.2 source code.

malloc/malloc.c:#define fwrite(buf, size, count, fp) _IO_fwrite (buf, size, count, fp) 

I guess the real implementation is in the iofwrite.c.

_IO_size_t
_IO_fwrite (buf, size, count, fp)
     const void *buf;
     _IO_size_t size;
     _IO_size_t count;
     _IO_FILE *fp;
{
  _IO_size_t request = size * count;
  _IO_size_t written = 0;
  CHECK_FILE (fp, 0);
  if (request == 0)
    return 0;
  _IO_acquire_lock (fp);     
  if (_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1)
    written = _IO_sputn (fp, (const char *) buf, request);
  _IO_release_lock (fp);
  /* We have written all of the input in case the return value indicates
     this or EOF is returned.  The latter is a special case where we
     simply did not manage to flush the buffer.  But the data is in the
     buffer and therefore written as far as fwrite is concerned.  */
  if (written == request || written == EOF)
    return count;
  else
    return written / size;
}

So, I guess it is possible return 0 in the return code of fwrite even if it has really written some bytes into the file.


Solution

  • Yes — it is possible for fwrite(ptr, 65537, 1, fp) to return 0 as the return code even if it really wrote some bytes into the file.

    For example, if there is only space left on the disk for 512 bytes, then you have a short write, but it wrote 0 complete units of 65537 bytes (that's a curious number; usually it would be 65536, wouldn't it?), so the return value must be 0.

    If you want to know how much was really written, you should use:

     nbytes = fwrite(ptr, 1, 65537, fp);
    

    to get the exact byte count; now you'd get 512 back from your hypothetical short write.