diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 11d1aad74..0e7c859b8 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +Sat Mar 11 22:47:43 2000 Christopher Faylor + + * fhandler_console.cc (fhandler_console::read): Don't even think about + breaking on interrupt if executing in a "cygwin" thread. + * fhandler_tty.cc (fhandler_pty_master::process_slave_output): + Streamline, simplify code. + * sigproc.cc (sig_send): Remove debugging statement. + +Sat Mar 11 22:46:55 2000 Christopher Faylor + + * fhandler_console.cc (fhandler_console::read) + Fri Mar 10 13:20:50 2000 Christopher Faylor * sigproc.cc: Set wait_sig priority to normal. diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index e95cc0a9a..54d8da618 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -137,8 +137,13 @@ fhandler_console::read (void *pv, size_t buflen) DWORD nwait; w4[0] = h; - nwait = 2; - w4[1] = signal_arrived; + if (iscygthread ()) + nwait = 1; + else + { + w4[1] = signal_arrived; + nwait = 2; + } for (;;) { @@ -151,8 +156,7 @@ fhandler_console::read (void *pv, size_t buflen) case WAIT_OBJECT_0: break; case WAIT_OBJECT_0 + 1: - if (!iscygthread ()) - set_sig_errno (EINTR); + set_sig_errno (EINTR); return -1; default: __seterrno (); diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 3261ea2ce..14da2bbbd 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -154,7 +154,8 @@ void fhandler_pty_master::doecho (const void *str, DWORD len) { acquire_output_mutex (INFINITE); - WriteFile (get_ttyp ()->to_master, str, len, &len, NULL); + if (!WriteFile (get_ttyp ()->to_master, str, len, &len, NULL)) + termios_printf ("Write to %p failed, %E", get_ttyp ()->to_master); // WaitForSingleObject (output_done_event, INFINITE); release_output_mutex (); } @@ -219,135 +220,144 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len) char outbuf[OUT_BUFFER_SIZE]; DWORD n; int column = 0; - -again: + int rc = 0; if (len == 0) - return 0; + goto out; - if (neednl_) + for (;;) { - /* We need to return a left over \n character, resulting from - \r\n conversion. Note that we already checked for FLUSHO and - OutputStopped at the time that we read the character, so we - don't check again here. */ - buf[0] = '\n'; - neednl_ = 0; - return 1; - } - - /* Set RLEN to the number of bytes to read from the pipe. */ - rlen = len; - if (get_ttyp ()->ti.c_oflag & OPOST && get_ttyp ()->ti.c_oflag & ONLCR) - { - /* We are going to expand \n to \r\n, so don't read more than - half of the number of bytes requested. */ - rlen /= 2; - if (rlen == 0) - rlen = 1; - } - if (rlen > sizeof outbuf) - rlen = sizeof outbuf; - - HANDLE handle = get_io_handle (); - - /* Doing a busy wait like this is quite inefficient, but nothing - else seems to work completely. Windows should provide some sort - of overlapped I/O for pipes, or something, but it doesn't. */ - DWORD avail; - while (1) - { - if (! PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL)) + if (neednl_) { - if (GetLastError () == ERROR_BROKEN_PIPE) - return 0; - __seterrno (); - return -1; + /* We need to return a left over \n character, resulting from + \r\n conversion. Note that we already checked for FLUSHO and + OutputStopped at the time that we read the character, so we + don't check again here. */ + buf[0] = '\n'; + neednl_ = 0; + rc = 1; + break; } - if (avail > 0) - break; - if (hit_eof ()) - return 0; - Sleep (10); - } - if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE) - { + /* Set RLEN to the number of bytes to read from the pipe. */ + rlen = len; + if (get_ttyp ()->ti.c_oflag & OPOST && get_ttyp ()->ti.c_oflag & ONLCR) + { + /* We are going to expand \n to \r\n, so don't read more than + half of the number of bytes requested. */ + rlen /= 2; + if (rlen == 0) + rlen = 1; + } + if (rlen > sizeof outbuf) + rlen = sizeof outbuf; + + HANDLE handle = get_io_handle (); + + /* Doing a busy wait like this is quite inefficient, but nothing + else seems to work completely. Windows should provide some sort + of overlapped I/O for pipes, or something, but it doesn't. */ + while (1) + { + DWORD avail; + if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL)) + goto err; + if (avail > 0) + break; + if (hit_eof ()) + goto out; + Sleep (10); + } + + if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE) + goto err; + + termios_printf ("rlen %u", n); + + if (get_ttyp ()->ti.c_lflag & FLUSHO) + { + get_ttyp ()->write_retval = n; + if (output_done_event != NULL) + SetEvent (output_done_event); + continue; + } + + if (get_ttyp ()->OutputStopped) + { + termios_printf ("waiting for restart_output_event"); + WaitForSingleObject (restart_output_event, INFINITE); + termios_printf ("done waiting for restart_output_event"); + } + + if (!(get_ttyp ()->ti.c_oflag & OPOST)) // post-process output + { + memcpy (buf, outbuf, n); + rc = n; + } + else // raw output mode + { + char *iptr = outbuf, *optr = buf; + + while (n--) + { + switch (*iptr) + { + case '\r': + if ((get_ttyp ()->ti.c_oflag & ONOCR) && column == 0) + { + iptr++; + continue; + } + if (get_ttyp ()->ti.c_oflag & OCRNL) + *iptr = '\n'; + else + column = 0; + break; + case '\n': + if (get_ttyp ()->ti.c_oflag & ONLCR) + { + *optr++ = '\r'; + column = 0; + } + if (get_ttyp ()->ti.c_oflag & ONLRET) + column = 0; + break; + default: + column++; + break; + } + + /* Don't store data past the end of the user's buffer. This + can happen if the user requests a read of 1 byte when + doing \r\n expansion. */ + if (optr - buf >= (int) len) + { + neednl_ = 1; + if (*iptr != '\n' || n != 0) + system_printf ("internal error: %d unexpected characters", n); + break; + } + + *optr++ = *iptr++; + } + rc = optr - buf; + } + break; + + err: if (GetLastError () == ERROR_BROKEN_PIPE) - return 0; - __seterrno (); - return -1; - } - - termios_printf ("len=%u", n); - - if (get_ttyp ()->ti.c_lflag & FLUSHO) - { - get_ttyp ()->write_retval = n; - if (output_done_event != NULL) - SetEvent (output_done_event); - goto again; - } - - if (get_ttyp ()->OutputStopped) - { - termios_printf ("waiting for restart_output_event"); - WaitForSingleObject (restart_output_event, INFINITE); - } - - if (get_ttyp ()->ti.c_oflag & OPOST) // post-process output - { - char *iptr = outbuf, *optr = buf; - - while (n--) + rc = 0; + else { - switch (*iptr) - { - case '\r': - if ((get_ttyp ()->ti.c_oflag & ONOCR) && column == 0) - { - iptr++; - continue; - } - if (get_ttyp ()->ti.c_oflag & OCRNL) - *iptr = '\n'; - else - column = 0; - break; - case '\n': - if (get_ttyp ()->ti.c_oflag & ONLCR) - { - *optr++ = '\r'; - column = 0; - } - if (get_ttyp ()->ti.c_oflag & ONLRET) - column = 0; - break; - default: - column++; - break; - } - - /* Don't store data past the end of the user's buffer. This - can happen if the user requests a read of 1 byte when - doing \r\n expansion. */ - if (optr - buf >= (int) len) - { - neednl_ = 1; - if (*iptr != '\n' || n != 0) - system_printf ("internal error: %d unexpected characters", n); - break; - } - - *optr++ = *iptr++; + __seterrno (); + rc = -1; } - return optr - buf; - } - else // raw output mode - { - memcpy (buf, outbuf, n); - return n; + break; } + +out: + termios_printf ("returning %d", rc); + return rc; } static DWORD WINAPI @@ -546,8 +556,10 @@ fhandler_tty_slave::write (const void *ptr, size_t len) if (output_done_event != NULL) { - termios_printf("tty%d waiting for output_done", ttynum); - WaitForSingleObject (output_done_event, n * 1000); + DWORD rc; + DWORD x = n * 1000; + rc = WaitForSingleObject (output_done_event, x); + termios_printf("waited %d ms for output_done_event, WFSO %d", x, rc); } if (get_ttyp ()->write_retval < 0) diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index c36bd64db..a58bf0fcb 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -826,7 +826,6 @@ sigproc_printf ("ReleaseSemaphore succeeded"); sip_printf ("Waiting for thiscomplete %p", thiscomplete); SetLastError (0); -Sleep (0); rc = WaitForSingleObject (thiscomplete, WSSC); /* Check for strangeness due to this thread being redirected by the signal handler. Sometimes a WAIT_TIMEOUT will occur when the