sync_client failing with "Fatal error: failed to finish reading file!"

Bron Gondwana brong at
Mon Jun 17 02:00:50 EDT 2013

On Wed, Jun 12, 2013, at 06:07 AM, Nic Bernstein wrote:
>  Checking the source for dlist.c, here is the context for this error
>  [printfile()]:

(I'm just keeping the important lines here)

>    size = sbuf.st_size;
>    while (size) {
>        int n = fread(buf, 1, (size > 4096 ? 4096 : size), f);
>        if (n <= 0) break;
>        prot_write(out, buf, n);
>        size -= n;
>    }
>    fclose(f);
>    if (size) fatal("failed to finish reading file!", EC_IOERR);

> The only way we can see this happening is if size <0; in other words,
> something has written more into the file since we opened it. Is that a
> correct interpretation?  If so, the error message doesn't really jive
> with the error condition.  Shouldn't the test be:

> if (size > 0) fatal...

> instead?  If size < 0, then manifestly we have finished reading
> the file.

No, if size < 0 then we've read PAST the end of the file - which is also
totally bogus.  I can see a case for while (size > 0) on the loop though,
for this exact case, so we drop out earlier than EOF.

There are only two ways to exit that loop: either size gets down to zero,
or fread returns a non-positive value.  From the man page:

        On success, fread() and fwrite() return the number of
        items read or written.
        This number equals the number of bytes transferred only
        when size is 1.  If an error occurs, or the end of the
        file is reached, the return value is a short item count
        (or zero).

        fread() does not distinguish between end-of-file and
        error, and callers must use feof(3) and ferror(3) to
        determine which occurred.

So we could certainly make the code better about reporting the
cause of the error.  I suspect 99% probability file permissions
problems (your 'cyrus' user can't read it, but can stat it) and
1% probability a corrupt filesystem with that file contents
being unreadable.  It's probably the very first fread which is



  Bron Gondwana
  brong at

More information about the Info-cyrus mailing list