mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-19 07:22:14 +08:00
* errno.cc (errmap): Handle ERROR_IO_PENDING.
* fhandler.cc (fhandler_base::open): Make tape I/O asynchronous. * fhandler.h (class fhandler_dev_tape): Add mt_evt member. * fhandler_tape.cc (mtinfo_drive::initialize): Initialize async_writes. (mtinfo_drive::close): Handle async writes. (mtinfo_drive::read): Add mt_evt parameter. Use overlapped I/O. (mtinfo_drive::async_wait): New function. (mtinfo_drive::write): Add mt_evt parameter. Use overlapped I/O. Handle async writes. (mtinfo_drive::_set_pos): Handle async writes. (mtinfo_drive::set_partition): Ditto. (mtinfo_drive::prepare): Ditto. (mtinfo_drive::get_status): Drop useless "else". Handle async_writes flag. (mtinfo_drive::set_options): Handle async_writes flags. (fhandler_dev_tape::close): Close mt_evt handle. (fhandler_dev_tape::raw_read): Create mt_evt handle and use in call to mtinfo_drive::read. (fhandler_dev_tape::raw_write): Create mt_evt handle and use in call to mtinfo_drive::write. * mtinfo.h (MTINFO_VERSION): Bump. (enum dirty_state): Add async_write_pending state. (class mtinfo_drive): Add OVERLAPPED struct "ov". Add async_writes flag. (mtinfo_drive::async_wait): Add declaration. (mtinfo_drive::read): Add mt_evt parameter. (mtinfo_drive::write): Ditto. * registry.cc (load_registry_hive): Call enable_restore_privilege instead of set_process_privilege.
This commit is contained in:
parent
da3c66eb9a
commit
0c8731b8f4
@ -1,3 +1,36 @@
|
||||
2004-04-19 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* errno.cc (errmap): Handle ERROR_IO_PENDING.
|
||||
* fhandler.cc (fhandler_base::open): Make tape I/O asynchronous.
|
||||
* fhandler.h (class fhandler_dev_tape): Add mt_evt member.
|
||||
* fhandler_tape.cc (mtinfo_drive::initialize): Initialize async_writes.
|
||||
(mtinfo_drive::close): Handle async writes.
|
||||
(mtinfo_drive::read): Add mt_evt parameter. Use overlapped I/O.
|
||||
(mtinfo_drive::async_wait): New function.
|
||||
(mtinfo_drive::write): Add mt_evt parameter. Use overlapped I/O.
|
||||
Handle async writes.
|
||||
(mtinfo_drive::_set_pos): Handle async writes.
|
||||
(mtinfo_drive::set_partition): Ditto.
|
||||
(mtinfo_drive::prepare): Ditto.
|
||||
(mtinfo_drive::get_status): Drop useless "else". Handle async_writes
|
||||
flag.
|
||||
(mtinfo_drive::set_options): Handle async_writes flags.
|
||||
(fhandler_dev_tape::close): Close mt_evt handle.
|
||||
(fhandler_dev_tape::raw_read): Create mt_evt handle and use in call
|
||||
to mtinfo_drive::read.
|
||||
(fhandler_dev_tape::raw_write): Create mt_evt handle and use in call
|
||||
to mtinfo_drive::write.
|
||||
* mtinfo.h (MTINFO_VERSION): Bump.
|
||||
(enum dirty_state): Add async_write_pending state.
|
||||
(class mtinfo_drive): Add OVERLAPPED struct "ov". Add async_writes
|
||||
flag.
|
||||
(mtinfo_drive::async_wait): Add declaration.
|
||||
(mtinfo_drive::read): Add mt_evt parameter.
|
||||
(mtinfo_drive::write): Ditto.
|
||||
|
||||
* registry.cc (load_registry_hive): Call enable_restore_privilege
|
||||
instead of set_process_privilege.
|
||||
|
||||
2004-04-19 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_tape.cc (mtinfo_drive::_set_pos): Take additional dont_wait
|
||||
|
@ -119,6 +119,7 @@ static NO_COPY struct
|
||||
X (NO_MEDIA_IN_DRIVE, ENOMEDIUM),
|
||||
X (DEVICE_REQUIRES_CLEANING, EIO),
|
||||
X (DEVICE_DOOR_OPEN, EIO),
|
||||
X (IO_PENDING, EAGAIN),
|
||||
{ 0, NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -610,7 +610,8 @@ fhandler_base::open (int flags, mode_t mode)
|
||||
/* Allow reliable lseek on disk devices. */
|
||||
if (get_major () == DEV_FLOPPY_MAJOR)
|
||||
access |= GENERIC_READ;
|
||||
else if (get_major () != DEV_SERIAL_MAJOR)
|
||||
else if (get_major () != DEV_SERIAL_MAJOR
|
||||
&& get_major () != DEV_TAPE_MAJOR)
|
||||
{
|
||||
create_options |= FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
access |= SYNCHRONIZE;
|
||||
|
@ -535,6 +535,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw
|
||||
class fhandler_dev_tape: public fhandler_dev_raw
|
||||
{
|
||||
HANDLE mt_mtx;
|
||||
HANDLE mt_evt;
|
||||
|
||||
bool is_rewind_device () { return get_minor () < 128; }
|
||||
unsigned int driveno () { return (unsigned int) get_minor () & 0x7f; }
|
||||
|
@ -81,6 +81,7 @@ mtinfo_drive::initialize (int num, bool first_time)
|
||||
if (first_time)
|
||||
{
|
||||
buffer_writes (true);
|
||||
async_writes (false);
|
||||
two_fm (false);
|
||||
fast_eom (false);
|
||||
auto_lock (false);
|
||||
@ -135,16 +136,22 @@ mtinfo_drive::close (HANDLE mt, bool rewind)
|
||||
lasterr = 0;
|
||||
if (GetTapeStatus (mt) == ERROR_NO_MEDIA_IN_DRIVE)
|
||||
dirty = clean;
|
||||
if (dirty == has_written)
|
||||
if (dirty >= has_written)
|
||||
{
|
||||
/* if last operation was writing, write a filemark */
|
||||
debug_printf ("writing filemark");
|
||||
write_marks (mt, TAPE_FILEMARKS, two_fm () ? 2 : 1);
|
||||
if (two_fm () && !lasterr && !rewind) /* Backspace over 2nd filemark. */
|
||||
/* If an async write is still pending, wait for completion. */
|
||||
if (dirty == async_write_pending)
|
||||
lasterr = async_wait (mt, NULL);
|
||||
if (!lasterr)
|
||||
{
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -1, false);
|
||||
if (!lasterr)
|
||||
part (partition)->fblock = 0; /* That's obvious, isn't it? */
|
||||
/* if last operation was writing, write a filemark */
|
||||
debug_printf ("writing filemark");
|
||||
write_marks (mt, TAPE_FILEMARKS, two_fm () ? 2 : 1);
|
||||
if (two_fm () && !lasterr && !rewind) /* Backspace over 2nd fmark. */
|
||||
{
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -1, false);
|
||||
if (!lasterr)
|
||||
part (partition)->fblock = 0; /* That's obvious, isn't it? */
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dirty == has_read && !rewind)
|
||||
@ -179,7 +186,7 @@ mtinfo_drive::close (HANDLE mt, bool rewind)
|
||||
}
|
||||
|
||||
int
|
||||
mtinfo_drive::read (HANDLE mt, void *ptr, size_t &ulen)
|
||||
mtinfo_drive::read (HANDLE mt, HANDLE mt_evt, void *ptr, size_t &ulen)
|
||||
{
|
||||
BOOL ret;
|
||||
DWORD bytes_read = 0;
|
||||
@ -191,6 +198,9 @@ mtinfo_drive::read (HANDLE mt, void *ptr, size_t &ulen)
|
||||
ulen = 0;
|
||||
goto out;
|
||||
}
|
||||
/* If an async write is still pending, wait for completion. */
|
||||
if (dirty == async_write_pending)
|
||||
lasterr = async_wait (mt, NULL);
|
||||
dirty = clean;
|
||||
if (part (partition)->emark == eof_hit)
|
||||
{
|
||||
@ -225,8 +235,12 @@ mtinfo_drive::read (HANDLE mt, void *ptr, size_t &ulen)
|
||||
part (partition)->smark = false;
|
||||
if (auto_lock () && lock < auto_locked)
|
||||
prepare (mt, TAPE_LOCK, true);
|
||||
ret = ReadFile (mt, ptr, ulen, &bytes_read, 0);
|
||||
ov.Offset = ov.OffsetHigh = 0;
|
||||
ov.hEvent = mt_evt;
|
||||
ret = ReadFile (mt, ptr, ulen, &bytes_read, &ov);
|
||||
lasterr = ret ? 0 : GetLastError ();
|
||||
if (lasterr == ERROR_IO_PENDING)
|
||||
lasterr = async_wait (mt, &bytes_read);
|
||||
ulen = (size_t) bytes_read;
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
@ -273,10 +287,22 @@ out:
|
||||
}
|
||||
|
||||
int
|
||||
mtinfo_drive::write (HANDLE mt, const void *ptr, size_t &len)
|
||||
mtinfo_drive::async_wait (HANDLE mt, DWORD *bytes_written)
|
||||
{
|
||||
DWORD written;
|
||||
|
||||
bool ret = GetOverlappedResult (mt, &ov, &written, TRUE);
|
||||
if (bytes_written)
|
||||
*bytes_written = written;
|
||||
return ret ? 0 : GetLastError ();
|
||||
}
|
||||
|
||||
int
|
||||
mtinfo_drive::write (HANDLE mt, HANDLE mt_evt, const void *ptr, size_t &len)
|
||||
{
|
||||
BOOL ret;
|
||||
DWORD bytes_written = 0;
|
||||
int async_err = 0;
|
||||
|
||||
if (GetTapeStatus (mt) == ERROR_NO_MEDIA_IN_DRIVE)
|
||||
return lasterr = ERROR_NO_MEDIA_IN_DRIVE;
|
||||
@ -285,12 +311,24 @@ mtinfo_drive::write (HANDLE mt, const void *ptr, size_t &len)
|
||||
len = 0;
|
||||
return error ("write");
|
||||
}
|
||||
if (dirty == async_write_pending)
|
||||
async_err = async_wait (mt, &bytes_written);
|
||||
dirty = clean;
|
||||
part (partition)->smark = false;
|
||||
if (auto_lock () && lock < auto_locked)
|
||||
prepare (mt, TAPE_LOCK, true);
|
||||
ret = WriteFile (mt, ptr, len, &bytes_written, 0);
|
||||
ov.Offset = ov.OffsetHigh = 0;
|
||||
ov.hEvent = mt_evt;
|
||||
ret = WriteFile (mt, ptr, len, &bytes_written, &ov);
|
||||
lasterr = ret ? 0: GetLastError ();
|
||||
if (lasterr == ERROR_IO_PENDING)
|
||||
{
|
||||
if (async_writes () && mp ()->BlockSize == 0)
|
||||
dirty = async_write_pending;
|
||||
else
|
||||
/* Wait for completion if a non-async write. */
|
||||
lasterr = async_wait (mt, &bytes_written);
|
||||
}
|
||||
len = (size_t) bytes_written;
|
||||
if (bytes_written > 0)
|
||||
{
|
||||
@ -301,6 +339,8 @@ mtinfo_drive::write (HANDLE mt, const void *ptr, size_t &len)
|
||||
if (part (partition)->fblock >= 0)
|
||||
part (partition)->fblock += blocks_written;
|
||||
}
|
||||
if (!lasterr && async_err)
|
||||
lasterr = async_err;
|
||||
if (lasterr == ERROR_EOM_OVERFLOW)
|
||||
part (partition)->emark = eom;
|
||||
else if (lasterr == ERROR_END_OF_MEDIA)
|
||||
@ -310,6 +350,8 @@ mtinfo_drive::write (HANDLE mt, const void *ptr, size_t &len)
|
||||
part (partition)->emark = no_eof;
|
||||
if (!lasterr)
|
||||
dirty = has_written;
|
||||
else if (lasterr == ERROR_IO_PENDING)
|
||||
dirty = async_write_pending;
|
||||
}
|
||||
return error ("write");
|
||||
}
|
||||
@ -344,9 +386,12 @@ int
|
||||
mtinfo_drive::_set_pos (HANDLE mt, int mode, long count, int partition,
|
||||
BOOL dont_wait)
|
||||
{
|
||||
/* If an async write is still pending, wait for completion. */
|
||||
if (dirty == async_write_pending)
|
||||
lasterr = async_wait (mt, NULL);
|
||||
dirty = clean;
|
||||
TAPE_FUNC (SetTapePosition (mt, mode, partition, count, count < 0 ? -1 : 0,
|
||||
dont_wait));
|
||||
dirty = clean;
|
||||
return lasterr;
|
||||
}
|
||||
|
||||
@ -575,6 +620,12 @@ mtinfo_drive::set_partition (HANDLE mt, long count)
|
||||
int
|
||||
mtinfo_drive::write_marks (HANDLE mt, int marktype, DWORD count)
|
||||
{
|
||||
/* If an async write is still pending, wait for completion. */
|
||||
if (dirty == async_write_pending)
|
||||
{
|
||||
lasterr = async_wait (mt, NULL);
|
||||
dirty = has_written;
|
||||
}
|
||||
if (marktype != TAPE_SETMARKS)
|
||||
dirty = clean;
|
||||
if (marktype == TAPE_FILEMARKS
|
||||
@ -639,6 +690,9 @@ mtinfo_drive::prepare (HANDLE mt, int action, bool is_auto)
|
||||
{
|
||||
BOOL dont_wait = FALSE;
|
||||
|
||||
/* If an async write is still pending, wait for completion. */
|
||||
if (dirty == async_write_pending)
|
||||
lasterr = async_wait (mt, NULL);
|
||||
dirty = clean;
|
||||
if (action == TAPE_UNLOAD || action == TAPE_LOAD || action == TAPE_TENSION)
|
||||
dont_wait = nowait () ? TRUE : FALSE;
|
||||
@ -781,7 +835,7 @@ mtinfo_drive::get_status (HANDLE mt, struct mtget *get)
|
||||
if (buffer_writes ())
|
||||
get->mt_gstat |= GMT_IM_REP_EN (-1); /* TODO: Async writes */
|
||||
|
||||
else if (tstat == ERROR_DEVICE_REQUIRES_CLEANING)
|
||||
if (tstat == ERROR_DEVICE_REQUIRES_CLEANING)
|
||||
get->mt_gstat |= GMT_CLN (-1);
|
||||
|
||||
/* Cygwin specials: */
|
||||
@ -803,6 +857,8 @@ mtinfo_drive::get_status (HANDLE mt, struct mtget *get)
|
||||
get->mt_gstat |= GMT_SYSV (-1);
|
||||
if (nowait ())
|
||||
get->mt_gstat |= GMT_NOWAIT (-1);
|
||||
if (async_writes ())
|
||||
get->mt_gstat |= GMT_ASYNC (-1);
|
||||
|
||||
get->mt_erreg = 0; /* FIXME: No softerr counting */
|
||||
|
||||
@ -842,6 +898,7 @@ mtinfo_drive::set_options (HANDLE mt, long options)
|
||||
break;
|
||||
case MT_ST_BOOLEANS:
|
||||
buffer_writes (!!(options & MT_ST_BUFFER_WRITES));
|
||||
async_writes (!!(options & MT_ST_ASYNC_WRITES));
|
||||
two_fm (!!(options & MT_ST_TWO_FM));
|
||||
fast_eom (!!(options & MT_ST_FAST_MTEOM));
|
||||
auto_lock (!!(options & MT_ST_AUTO_LOCK));
|
||||
@ -862,6 +919,8 @@ mtinfo_drive::set_options (HANDLE mt, long options)
|
||||
set = (what == MT_ST_SETBOOLEANS);
|
||||
if (options & MT_ST_BUFFER_WRITES)
|
||||
buffer_writes (set);
|
||||
if (options & MT_ST_ASYNC_WRITES)
|
||||
async_writes (set);
|
||||
if (options & MT_ST_TWO_FM)
|
||||
two_fm (set);
|
||||
if (options & MT_ST_FAST_MTEOM)
|
||||
@ -1197,6 +1256,8 @@ fhandler_dev_tape::close (void)
|
||||
|
||||
lock (-1);
|
||||
ret = mt->drive (driveno ())->close (get_handle (), is_rewind_device ());
|
||||
if (mt_evt)
|
||||
CloseHandle (mt_evt);
|
||||
if (ret)
|
||||
__seterrno_from_win_error (ret);
|
||||
cret = fhandler_dev_raw::close ();
|
||||
@ -1245,12 +1306,15 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
|
||||
}
|
||||
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)
|
||||
{
|
||||
debug_printf ("read %d bytes from tape (rest %d)",
|
||||
block_fit, len - block_fit);
|
||||
ret = mt->drive (driveno ())->read (get_handle (), buf, 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)
|
||||
@ -1271,7 +1335,7 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
|
||||
if (!ret && len > 0)
|
||||
{
|
||||
debug_printf ("read %d bytes from tape (one block)", block_size);
|
||||
ret = mt->drive (driveno ())->read (get_handle (), devbuf,
|
||||
ret = mt->drive (driveno ())->read (get_handle (), mt_evt, devbuf,
|
||||
block_size);
|
||||
if (ret)
|
||||
__seterrno_from_win_error (ret);
|
||||
@ -1297,7 +1361,9 @@ int
|
||||
fhandler_dev_tape::raw_write (const void *ptr, size_t len)
|
||||
{
|
||||
lock (-1);
|
||||
int ret = mt->drive (driveno ())->write (get_handle (), ptr, len);
|
||||
if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL)))
|
||||
debug_printf ("Creating event failed: %E");
|
||||
int ret = mt->drive (driveno ())->write (get_handle (), mt_evt, ptr, len);
|
||||
__seterrno_from_win_error (ret);
|
||||
return unlock (len);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#define MTINFO_MAGIC 0x179b2af0
|
||||
#define MTINFO_VERSION 1
|
||||
#define MTINFO_VERSION 2
|
||||
|
||||
/* Maximum number of supported partitions per drive. */
|
||||
#define MAX_PARTITION_NUM 64
|
||||
@ -33,7 +33,8 @@ enum dirty_state
|
||||
{
|
||||
clean,
|
||||
has_read,
|
||||
has_written
|
||||
has_written,
|
||||
async_write_pending
|
||||
};
|
||||
|
||||
enum lock_state
|
||||
@ -67,9 +68,11 @@ class mtinfo_drive
|
||||
lock_state lock;
|
||||
TAPE_GET_DRIVE_PARAMETERS _dp;
|
||||
TAPE_GET_MEDIA_PARAMETERS _mp;
|
||||
OVERLAPPED ov;
|
||||
struct status_flags
|
||||
{
|
||||
unsigned buffer_writes : 1;
|
||||
unsigned async_writes : 1;
|
||||
unsigned two_fm : 1;
|
||||
unsigned fast_eom : 1;
|
||||
unsigned auto_lock : 1;
|
||||
@ -101,6 +104,7 @@ class mtinfo_drive
|
||||
int set_blocksize (HANDLE mt, long count);
|
||||
int get_status (HANDLE mt, struct mtget *get);
|
||||
int set_options (HANDLE mt, long options);
|
||||
int async_wait (HANDLE mt, DWORD *bytes_written);
|
||||
|
||||
public:
|
||||
void initialize (int num, bool first_time);
|
||||
@ -108,12 +112,13 @@ public:
|
||||
int get_mp (HANDLE mt);
|
||||
int open (HANDLE mt);
|
||||
int close (HANDLE mt, bool rewind);
|
||||
int read (HANDLE mt, void *ptr, size_t &ulen);
|
||||
int write (HANDLE mt, const void *ptr, size_t &len);
|
||||
int read (HANDLE mt, HANDLE mt_evt, void *ptr, size_t &ulen);
|
||||
int write (HANDLE mt, HANDLE mt_evt, const void *ptr, size_t &len);
|
||||
int ioctl (HANDLE mt, unsigned int cmd, void *buf);
|
||||
int set_pos (HANDLE mt, int mode, long count, bool sfm_func);
|
||||
|
||||
IMPLEMENT_STATUS_FLAG (bool, buffer_writes)
|
||||
IMPLEMENT_STATUS_FLAG (bool, async_writes)
|
||||
IMPLEMENT_STATUS_FLAG (bool, two_fm)
|
||||
IMPLEMENT_STATUS_FLAG (bool, fast_eom)
|
||||
IMPLEMENT_STATUS_FLAG (bool, auto_lock)
|
||||
|
@ -241,7 +241,7 @@ load_registry_hive (PSID psid)
|
||||
RegCloseKey (hkey);
|
||||
return;
|
||||
}
|
||||
set_process_privilege (SE_RESTORE_NAME);
|
||||
enable_restore_privilege ();
|
||||
if (get_registry_hive_path (psid, path))
|
||||
{
|
||||
strcat (path, "\\NTUSER.DAT");
|
||||
|
Loading…
x
Reference in New Issue
Block a user