diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-12-14 15:54:33 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-12-14 15:54:33 +0000 |
commit | e3d14af155fb84890a32fad7f7706967ac5bc7d9 (patch) | |
tree | 05df3064a2c24a1542e182a3aa2d5ff4e3df8f56 /winsup/cygwin/fhandler_tape.cc | |
parent | 10cba930d401056aed4b2fb360b5e084d61ecabb (diff) | |
download | newlib-e3d14af155fb84890a32fad7f7706967ac5bc7d9.zip newlib-e3d14af155fb84890a32fad7f7706967ac5bc7d9.tar.gz newlib-e3d14af155fb84890a32fad7f7706967ac5bc7d9.tar.bz2 |
* fhandler.cc (fhandler_base::open_9x): Handle O_SYNC and O_DIRECT
flags.
(fhandler_base::open): Ditto.
* fhandler_floppy.cc (fhandler_dev_floppy::open): Don't allocate devbuf
in O_DIRECT case.
* fhandler_raw.cc (fhandler_dev_raw::ioctl): Don't allow buffer
changes in O_DIRECT case. Allow returning a buffer size 0, which
indicates O_DIRECT.
* fhandler_tape.cc (fhandler_dev_tape::open): Use O_SYNC flag to
hand down the !buffer_writes case. Don't allocate devbuf in O_DIRECT
case.
(fhandler_dev_tape::raw_read): Don't mess with devbuf if it's NULL.
* include/fcntl.h: Define _FDIRECT, O_DIRECT, O_DSYNC and O_RSYNC.
* include/cygwin/version.h: Bump API minor version.
Diffstat (limited to 'winsup/cygwin/fhandler_tape.cc')
-rw-r--r-- | winsup/cygwin/fhandler_tape.cc | 141 |
1 files changed, 80 insertions, 61 deletions
diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index d3fd3ee..0b4e537 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -1216,11 +1216,16 @@ fhandler_dev_tape::open (int flags, mode_t) __seterrno (); return 0; } - /* The O_TEXT flag is used to indicate write-through (non buffered writes) - to the underlying fhandler_dev_raw::open call. */ - flags &= ~O_TEXT; + + /* The O_SYNC flag is not supported by the tape driver. Use the + MT_ST_BUFFER_WRITES and MT_ST_ASYNC_WRITES flags in the drive + settings instead. In turn, the MT_ST_BUFFER_WRITES is translated + into O_SYNC, which controls the FILE_WRITE_THROUGH flag in the + NtCreateFile call in fhandler_base::open. */ + flags &= ~O_SYNC; if (!mt->drive (driveno ())->buffer_writes ()) - flags |= O_TEXT; + flags |= O_SYNC; + ret = fhandler_dev_raw::open (flags); if (ret) { @@ -1231,8 +1236,11 @@ fhandler_dev_tape::open (int flags, mode_t) mt->drive (driveno ())->set_pos (get_handle (), TAPE_SPACE_FILEMARKS, 1, true); - devbufsiz = mt->drive (driveno ())->dp ()->MaximumBlockSize; - devbuf = new char [devbufsiz]; + if (!(flags & O_DIRECT)) + { + devbufsiz = mt->drive (driveno ())->dp ()->MaximumBlockSize; + devbuf = new char [devbufsiz]; + } devbufstart = devbufend = 0; } else @@ -1283,70 +1291,81 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen) return; } block_size = mt->drive (driveno ())->mp ()->BlockSize; - if (devbufend > devbufstart) + if (devbuf) { - bytes_to_read = min (len, devbufend - devbufstart); - debug_printf ("read %d bytes from buffer (rest %d)", - bytes_to_read, devbufend - devbufstart - bytes_to_read); - memcpy (buf, devbuf + devbufstart, bytes_to_read); - len -= bytes_to_read; - bytes_read += bytes_to_read; - buf += bytes_to_read; - devbufstart += bytes_to_read; - if (devbufstart == devbufend) - devbufstart = devbufend = 0; - /* If a switch to variable block_size occured, just return the buffer - remains until the buffer is empty, then proceed with usual variable - block size handling (one block per read call). */ - if (!block_size) - len = 0; - } - if (len > 0) - { - if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL))) - debug_printf ("Creating event failed, %E"); - size_t block_fit = !block_size ? len : rounddown(len, block_size); - if (block_fit) + if (devbufend > devbufstart) { - debug_printf ("read %d bytes from tape (rest %d)", - block_fit, len - block_fit); - ret = mt->drive (driveno ())->read (get_handle (), mt_evt, buf, - block_fit); - if (ret) - __seterrno_from_win_error (ret); - else if (block_fit) - { - len -= block_fit; - bytes_read += block_fit; - buf += block_fit; - /* Only one block in each read call, please. */ - if (!block_size) - len = 0; - } - else { + bytes_to_read = min (len, devbufend - devbufstart); + debug_printf ("read %d bytes from buffer (rest %d)", + bytes_to_read, devbufend - devbufstart - bytes_to_read); + memcpy (buf, devbuf + devbufstart, bytes_to_read); + len -= bytes_to_read; + bytes_read += bytes_to_read; + buf += bytes_to_read; + devbufstart += bytes_to_read; + if (devbufstart == devbufend) + devbufstart = devbufend = 0; + /* If a switch to variable block_size occured, just return the buffer + remains until the buffer is empty, then proceed with usual variable + block size handling (one block per read call). */ + if (!block_size) len = 0; - if (bytes_read) - lastblk_to_read (true); - } } - if (!ret && len > 0) + if (len > 0) { - debug_printf ("read %d bytes from tape (one block)", block_size); - ret = mt->drive (driveno ())->read (get_handle (), mt_evt, devbuf, - block_size); - if (ret) - __seterrno_from_win_error (ret); - else if (block_size) + if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL))) + debug_printf ("Creating event failed, %E"); + size_t block_fit = !block_size ? len : rounddown(len, block_size); + if (block_fit) + { + debug_printf ("read %d bytes from tape (rest %d)", + block_fit, len - block_fit); + ret = mt->drive (driveno ())->read (get_handle (), mt_evt, buf, + block_fit); + if (ret) + __seterrno_from_win_error (ret); + else if (block_fit) + { + len -= block_fit; + bytes_read += block_fit; + buf += block_fit; + /* Only one block in each read call, please. */ + if (!block_size) + len = 0; + } + else { + len = 0; + if (bytes_read) + lastblk_to_read (true); + } + } + if (!ret && len > 0) { - devbufstart = len; - devbufend = block_size; - bytes_read += len; - memcpy (buf, devbuf, len); + debug_printf ("read %d bytes from tape (one block)", block_size); + ret = mt->drive (driveno ())->read (get_handle (), mt_evt, devbuf, + block_size); + if (ret) + __seterrno_from_win_error (ret); + else if (block_size) + { + devbufstart = len; + devbufend = block_size; + bytes_read += len; + memcpy (buf, devbuf, len); + } + else if (bytes_read) + lastblk_to_read (true); } - else if (bytes_read) - lastblk_to_read (true); } } + else + { + if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL))) + debug_printf ("Creating event failed, %E"); + bytes_read = ulen; + ret = mt->drive (driveno ())->read (get_handle (), mt_evt, ptr, + bytes_read); + } ulen = (ret ? (size_t) -1 : bytes_read); unlock (); } |