Web lists-archives.com

Re: Wrong file position after writing 65537 bytes to block device




On Tue, Dec 19, 2017 at 9:14 AM, Corinna Vinschen
<corinna-cygwin@xxxxxxxxxx> wrote:
> Neither glibc nor FreeBSD show this behaviour.  Keep in mind that stdio
> is designed for buffered I/O.  What should happen, basically, is that a
> multiple of the stdio buffersize is written and the remainder is kept in
> the stdio buffer:
>
>   fwrite(65537)
>   -> write(65536)
>   -> store 1 byte in FILE._buf
>
> ftell calls lseek which returns 65536.  It adds the number of bytes
> still in the buffer, so it should return 65537.  Further fwrite's
> seemlessly append to the bytes already written, as expected.  ftell
> calling fflush and thus setting the current file position to the next
> sector boundary breaks this expectation.
>
> I pushed a patch yesterday and uploaded new developer snapshots to
> https://cygwin.com/snapshots/
>
> Please test.

Thanks, I can confirm that the 2017-12-18 snapshot fixed the test
program I posted.

What about the harder case where the program calls fflush, though?

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *f = fopen(argv[1], "w");
    char x[65536 + 1];
    fwrite(x, 1, 65536 + 1, f);
    fflush(f);
    printf("%ld", ftell(f));
    return 0;
}

cygwin reports 66048, while Linux reports 65537.  In cygwin, if such a
write is done in a loop, for example, you can get garbled output on
disk.

fflush can be visibly unnecessary when done from C, but python3 (where
I originally observed the problem) appears to do implicit flushing.

If this is annoying to fix and I am the only one who notices, please
don't worry about it, I can just write in proper block sizes to block
devices.

Best regards,

Ivan

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple