diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc index 5028194a9e..1fe72fc8b8 100644 --- a/winsup/cygwin/fhandler/console.cc +++ b/winsup/cygwin/fhandler/console.cc @@ -1011,10 +1011,14 @@ fhandler_console::read (void *pv, size_t& buflen) push_process_state process_state (PID_TTYIN); - int copied_chars = 0; + size_t copied_chars = 0; - DWORD timeout = is_nonblocking () ? 0 : INFINITE; + DWORD timeout = is_nonblocking () ? 0 : + (get_ttyp ()->ti.c_lflag & ICANON ? INFINITE : + (get_ttyp ()->ti.c_cc[VMIN] == 0 ? 0 : + (get_ttyp ()->ti.c_cc[VTIME]*100 ? : INFINITE))); +read_more: while (!input_ready && !get_cons_readahead_valid ()) { int bgres; @@ -1037,6 +1041,11 @@ fhandler_console::read (void *pv, size_t& buflen) pthread::static_cancel_self (); /*NOTREACHED*/ case WAIT_TIMEOUT: + if (copied_chars) + { + buflen = copied_chars; + return; + } set_sig_errno (EAGAIN); buflen = (size_t) -1; return; @@ -1082,19 +1091,20 @@ fhandler_console::read (void *pv, size_t& buflen) } /* Check console read-ahead buffer filled from terminal requests */ - while (con.cons_rapoi && *con.cons_rapoi && buflen) - { - buf[copied_chars++] = *con.cons_rapoi++; - buflen --; - } + while (con.cons_rapoi && *con.cons_rapoi && buflen > copied_chars) + buf[copied_chars++] = *con.cons_rapoi++; copied_chars += - get_readahead_into_buffer (buf + copied_chars, buflen); + get_readahead_into_buffer (buf + copied_chars, buflen - copied_chars); if (!con_ra.ralen) input_ready = false; release_input_mutex (); + if (buflen > copied_chars && !(get_ttyp ()->ti.c_lflag & ICANON) + && copied_chars < get_ttyp ()->ti.c_cc[VMIN]) + goto read_more; + #undef buf buflen = copied_chars;