summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/fhandler_serial.cc21
2 files changed, 14 insertions, 12 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index da85ec122..d0f613d21 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,8 @@
+2012-05-25 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_serial.cc (fhandler_serial::raw_read): Just call ReadFile
+ directly in case of non-blocking I/O and handle result gracefully.
+
2012-05-24 Corinna Vinschen <corinna@vinschen.de>
* thread.cc (__cygwin_lock_lock): Replace null thread check with test
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;