summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/syscalls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r--winsup/cygwin/syscalls.cc75
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;