summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_serial.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_serial.cc')
-rw-r--r--winsup/cygwin/fhandler_serial.cc21
1 files changed, 9 insertions, 12 deletions
diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc
index 677b6221f..c58d0418c 100644
--- a/winsup/cygwin/fhandler_serial.cc
+++ b/winsup/cygwin/fhandler_serial.cc
@@ -71,7 +71,7 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
termios_printf ("error detected %x", ev);
else if (st.cbInQue && !vtime_)
inq = st.cbInQue;
- else if (!overlapped_armed)
+ else if (!is_nonblocking () && !overlapped_armed)
{
if ((size_t) tot >= minchars)
break;
@@ -83,16 +83,6 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
}
else if (GetLastError () != ERROR_IO_PENDING)
goto err;
- else if (is_nonblocking ())
- {
- PurgeComm (get_handle (), PURGE_RXABORT);
- if (tot == 0)
- {
- tot = -1;
- set_errno (EAGAIN);
- }
- goto out;
- }
else
{
overlapped_armed = 1;
@@ -132,7 +122,14 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
goto err;
else if (is_nonblocking ())
{
- PurgeComm (get_handle (), PURGE_RXABORT);
+ /* Use CancelIo rather than PurgeComm (PURGE_RXABORT) since
+ PurgeComm apparently discards in-flight bytes while CancelIo
+ only stops the overlapped IO routine. */
+ CancelIo (get_handle ());
+ if (GetOverlappedResult (get_handle (), &io_status, &n, FALSE))
+ tot = n;
+ else if (GetLastError () != ERROR_IO_INCOMPLETE)
+ goto err;
if (tot == 0)
{
tot = -1;