aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2017-12-19 18:58:06 +0100
committerCorinna Vinschen <corinna@vinschen.de>2017-12-19 18:58:06 +0100
commiteb4bfe4621ecaa49d0b4e586315286f8e4731046 (patch)
treecb14578214805a8320576c6583a06f8ca1463113
parentd5abcdd5a7fc3e45f4b0d20b7661c746e1091a8d (diff)
cygwin: block devices: fix file offset after short writesnewlib-snapshot-20171222
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>
-rw-r--r--winsup/cygwin/fhandler_floppy.cc12
-rw-r--r--winsup/cygwin/release/2.10.03
2 files changed, 13 insertions, 2 deletions
diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc
index de9e163e5..cca00bab8 100644
--- a/winsup/cygwin/fhandler_floppy.cc
+++ b/winsup/cygwin/fhandler_floppy.cc
@@ -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;
}
diff --git a/winsup/cygwin/release/2.10.0 b/winsup/cygwin/release/2.10.0
index 3afc4b7d0..0c6b406a1 100644
--- a/winsup/cygwin/release/2.10.0
+++ b/winsup/cygwin/release/2.10.0
@@ -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