* 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.
This commit is contained in:
Christopher Faylor 2000-03-12 04:44:37 +00:00
parent 1e8b88023c
commit 774ea16211
4 changed files with 153 additions and 126 deletions

View File

@ -1,3 +1,15 @@
Sat Mar 11 22:47:43 2000 Christopher Faylor <cgf@cygnus.com>
* 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 <cgf@cygnus.com>
* fhandler_console.cc (fhandler_console::read)
Fri Mar 10 13:20:50 2000 Christopher Faylor <cgf@cygnus.com> Fri Mar 10 13:20:50 2000 Christopher Faylor <cgf@cygnus.com>
* sigproc.cc: Set wait_sig priority to normal. * sigproc.cc: Set wait_sig priority to normal.

View File

@ -137,8 +137,13 @@ fhandler_console::read (void *pv, size_t buflen)
DWORD nwait; DWORD nwait;
w4[0] = h; w4[0] = h;
nwait = 2; if (iscygthread ())
w4[1] = signal_arrived; nwait = 1;
else
{
w4[1] = signal_arrived;
nwait = 2;
}
for (;;) for (;;)
{ {
@ -151,8 +156,7 @@ fhandler_console::read (void *pv, size_t buflen)
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
break; break;
case WAIT_OBJECT_0 + 1: case WAIT_OBJECT_0 + 1:
if (!iscygthread ()) set_sig_errno (EINTR);
set_sig_errno (EINTR);
return -1; return -1;
default: default:
__seterrno (); __seterrno ();

View File

@ -154,7 +154,8 @@ void
fhandler_pty_master::doecho (const void *str, DWORD len) fhandler_pty_master::doecho (const void *str, DWORD len)
{ {
acquire_output_mutex (INFINITE); 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); // WaitForSingleObject (output_done_event, INFINITE);
release_output_mutex (); release_output_mutex ();
} }
@ -219,135 +220,144 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
char outbuf[OUT_BUFFER_SIZE]; char outbuf[OUT_BUFFER_SIZE];
DWORD n; DWORD n;
int column = 0; int column = 0;
int rc = 0;
again:
if (len == 0) if (len == 0)
return 0; goto out;
if (neednl_) for (;;)
{ {
/* We need to return a left over \n character, resulting from if (neednl_)
\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 (GetLastError () == ERROR_BROKEN_PIPE) /* We need to return a left over \n character, resulting from
return 0; \r\n conversion. Note that we already checked for FLUSHO and
__seterrno (); OutputStopped at the time that we read the character, so we
return -1; 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) if (GetLastError () == ERROR_BROKEN_PIPE)
return 0; rc = 0;
__seterrno (); else
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--)
{ {
switch (*iptr) __seterrno ();
{ rc = -1;
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++;
} }
return optr - buf; break;
}
else // raw output mode
{
memcpy (buf, outbuf, n);
return n;
} }
out:
termios_printf ("returning %d", rc);
return rc;
} }
static DWORD WINAPI static DWORD WINAPI
@ -546,8 +556,10 @@ fhandler_tty_slave::write (const void *ptr, size_t len)
if (output_done_event != NULL) if (output_done_event != NULL)
{ {
termios_printf("tty%d waiting for output_done", ttynum); DWORD rc;
WaitForSingleObject (output_done_event, n * 1000); 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) if (get_ttyp ()->write_retval < 0)

View File

@ -826,7 +826,6 @@ sigproc_printf ("ReleaseSemaphore succeeded");
sip_printf ("Waiting for thiscomplete %p", thiscomplete); sip_printf ("Waiting for thiscomplete %p", thiscomplete);
SetLastError (0); SetLastError (0);
Sleep (0);
rc = WaitForSingleObject (thiscomplete, WSSC); rc = WaitForSingleObject (thiscomplete, WSSC);
/* Check for strangeness due to this thread being redirected by the /* Check for strangeness due to this thread being redirected by the
signal handler. Sometimes a WAIT_TIMEOUT will occur when the signal handler. Sometimes a WAIT_TIMEOUT will occur when the