diff options
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r-- | winsup/cygwin/syscalls.cc | 75 |
1 files changed, 39 insertions, 36 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 625d1503f..a79f88d2e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -229,51 +229,54 @@ setsid (void) extern "C" ssize_t _read (int fd, void *ptr, size_t len) { - sigframe thisframe (mainthread); + int res; + fhandler_base *fh; extern int sigcatchers; - bool sawsig; -beg: - sawsig = 0; - if (fdtab.not_open (fd)) + while (1) { - set_errno (EBADF); - return -1; - } + sigframe thisframe (mainthread); - // set_sig_errno (0); - fhandler_base *fh = fdtab[fd]; - DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; + if (fdtab.not_open (fd)) + { + set_errno (EBADF); + return -1; + } - /* Could block, so let user know we at least got here. */ - syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); + // set_sig_errno (0); + fh = fdtab[fd]; + DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; - int res; - if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ())) - debug_printf ("non-interruptible read\n"); - else if (!fh->ready_for_read (fd, wait, 0)) - { - if (!wait) - set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */ - else - set_sig_errno (EINTR); - res = -1; - goto out; - } + /* Could block, so let user know we at least got here. */ + syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); - /* Check to see if this is a background read from a "tty", - sending a SIGTTIN, if appropriate */ - res = fh->bg_check (SIGTTIN); - if (res > bg_eof) - { - myself->process_state |= PID_TTYIN; - res = fh->read (ptr, len); - myself->process_state &= ~PID_TTYIN; + if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ())) + debug_printf ("non-interruptible read\n"); + else if (!fh->ready_for_read (fd, wait, 0)) + { + if (!wait) + set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */ + else + set_sig_errno (EINTR); + res = -1; + goto out; + } + + /* Check to see if this is a background read from a "tty", + sending a SIGTTIN, if appropriate */ + res = fh->bg_check (SIGTTIN); + if (res > bg_eof) + { + myself->process_state |= PID_TTYIN; + res = fh->read (ptr, len); + myself->process_state &= ~PID_TTYIN; + } + + out: + if (res >= 0 || get_errno () == EINTR || !thisframe.call_signal_handler ()) + break; } -out: - if (res < 0 && get_errno () == EINTR && call_signal_handler ()) - goto beg; syscall_printf ("%d = read (%d<%s>, %p, %d), bin %d, errno %d", res, fd, fh->get_name (), ptr, len, fh->get_r_binary (), get_errno ()); MALLOC_CHECK; |