cygwin: block devices: fix file offset after short writes

When reading/writing block devices, Cygwin emulates Linux, providing
a byte-exact file position, albeit the underlying device drivers don't.

Unfortunately this only worked correctly for reading.  The raw_write
method failed to revalidate the buffer after the read-modify-write
cycle in case len is not a multiple of the sector length.  This in
turn resulted in lseek reporting a wrong file pointer.

Also, fix a condition for invalidating the buffer after writing from
a remaining read buffer.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2017-12-19 18:58:06 +01:00
parent d5abcdd5a7
commit eb4bfe4621
2 changed files with 13 additions and 2 deletions

View File

@ -566,11 +566,11 @@ fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
/* Align pointers, lengths, etc. */
cplen = MIN (cplen, written);
devbufstart += cplen;
if (devbufstart >= devbufend)
devbufstart = devbufend = 0;
p += cplen;
len -= cplen;
bytes_written += cplen;
if (len)
devbufstart = devbufend = 0;
}
/* As long as there's still something left in the input buffer ... */
while (len)
@ -607,6 +607,14 @@ fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
p += cplen;
len -= cplen;
bytes_written += cplen;
/* If we overwrote, revalidate devbuf. It still contains the
content from the above read/modify/write. Revalidating makes
sure lseek reports the correct position. */
if (cplen < bytes_per_sector)
{
devbufstart = cplen;
devbufend = bytes_per_sector;
}
}
return bytes_written;
}

View File

@ -31,3 +31,6 @@ Bug Fixes
- Remove a call to fflush from ftell{o}, which may result in wrong offsets.
Addresses: https://cygwin.com/ml/cygwin/2017-12/msg00151.html
- Fix file pointer computation after short writes on block devices.
Addresses: https://cygwin.com/ml/cygwin/2017-12/msg00151.html