From ae9b22c69b7374129d872cde66290c925a0c9857 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 5 Feb 2001 16:10:06 +0000 Subject: [PATCH] * fhandler.cc (fhandler_base::open): Always add GENERIC_READ access when opening raw disk devices. * fhandler_floppy.cc (fhandler_dev_floppy::lseek): Implement bytewise access. * fhandler_raw.cc (fhandler_dev_raw::open): Always open raw disk device binary. (fhandler_dev_raw::raw_write): Don't drop read buffer content when writing after read. --- winsup/cygwin/ChangeLog | 11 +++++ winsup/cygwin/fhandler.cc | 6 +++ winsup/cygwin/fhandler_floppy.cc | 79 ++++++++++++++++++++++++++++++-- winsup/cygwin/fhandler_raw.cc | 11 +++-- 4 files changed, 101 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 838f25372..b0db4a5a9 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +Mon Feb 5 17:00:00 2001 Corinna Vinschen + + * fhandler.cc (fhandler_base::open): Always add GENERIC_READ access + when opening raw disk devices. + * fhandler_floppy.cc (fhandler_dev_floppy::lseek): Implement bytewise + access. + * fhandler_raw.cc (fhandler_dev_raw::open): Always open raw disk device + binary. + (fhandler_dev_raw::raw_write): Don't drop read buffer content when + writing after read. + Mon Feb 5 13:30:00 2001 Corinna Vinschen * mmap.cc (mmap_record::fixup_map): New method to duplicate diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index f6779614a..1c9e600a8 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -324,6 +324,12 @@ fhandler_base::open (int flags, mode_t mode) access_ = GENERIC_READ | GENERIC_WRITE; } + /* Allow reliable lseek on disk devices. */ + if (get_device () == FH_FLOPPY) + { + access_ |= GENERIC_READ; + } + /* FIXME: O_EXCL handling? */ if ((flags & O_TRUNC) && ((flags & O_ACCMODE) != O_RDONLY)) diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc index ec48c91f3..a767443b9 100644 --- a/winsup/cygwin/fhandler_floppy.cc +++ b/winsup/cygwin/fhandler_floppy.cc @@ -15,6 +15,7 @@ details. */ #include #include #include "fhandler.h" +#include "cygerrno.h" /**********************************************************************/ /* fhandler_dev_floppy */ @@ -78,9 +79,81 @@ fhandler_dev_floppy::close (void) off_t fhandler_dev_floppy::lseek (off_t offset, int whence) { - /* FIXME: Need to implement better. */ - offset = (offset / 512) * 512; - return fhandler_base::lseek (offset, whence); + int ret; + DWORD off; + char buf[512]; + + if (whence == SEEK_SET) + { + if (offset < 0) + { + set_errno (EINVAL); + return -1; + } + + /* Invalidate buffer. */ + ret = writebuf (); + if (ret) + return ret; + devbufstart = devbufend = 0; + + off = (offset / 512) * 512; + + if (SetFilePointer (get_handle (), off, NULL, FILE_BEGIN) + == INVALID_SET_FILE_POINTER) + { + __seterrno (); + return -1; + } + return raw_read (buf, offset - off); + } + else if (whence == SEEK_CUR) + { + DWORD low; + LONG high = 0; + + low = SetFilePointer (get_handle (), 0, &high, FILE_CURRENT); + if (low == INVALID_SET_FILE_POINTER && GetLastError ()) + { + __seterrno (); + return -1; + } + long long cur = (long long) high << 32 + low; + if (is_writing) + cur += devbufend - devbufstart; + else + cur -= devbufend - devbufstart; + + /* Invalidate buffer. */ + ret = writebuf (); + if (ret) + return ret; + devbufstart = devbufend = 0; + + cur += offset; + if (cur < 0) + { + set_errno (EINVAL); + return -1; + } + + long long set = (cur / 512) * 512; + high = set >> 32; + low = set & 0xffffffff; + + off = cur - set; + + low = SetFilePointer (get_handle (), low, &high, FILE_BEGIN); + if (low == INVALID_SET_FILE_POINTER && GetLastError ()) + { + __seterrno (); + return -1; + } + return raw_read (buf, off); + } + /* SEEK_END is not supported on raw disk devices. */ + set_errno (EINVAL); + return -1; } int diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index 70cf8284c..d8ecf61ea 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -135,8 +135,10 @@ fhandler_dev_raw::open (const char *path, int flags, mode_t) set_name (path, real_path.get_win32 ()); - /* Always open a raw device existing */ - ret = fhandler_base::open (path, flags & ~(O_CREAT | O_TRUNC)); + /* Always open a raw device existing and binary. */ + flags &= ~(O_CREAT | O_TRUNC); + flags |= O_BINARY; + ret = fhandler_base::open (path, flags); if (ret) { if (devbufsiz > 1L) @@ -334,7 +336,10 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len) } if (!is_writing) - devbufstart = devbufend = 0; + { + devbufend = devbufstart; + devbufstart = 0; + } is_writing = 1; if (devbuf)