diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a6ea390fe..df65b3bf5 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2011-05-05 Corinna Vinschen + + * pinfo.h (class push_process_state): New class to push a process state + flag temporarily into myself->process_state. + * fhandler_console.cc (fhandler_console::read): Add push_process_state + handler. + (fhandler_console::write): Call bg_check from here. Add + push_process_state handler. + * fhandler_tty.cc (fhandler_tty_slave::write): Ditto. + (fhandler_tty_slave::read): Ditto. + (fhandler_pty_master::write): Ditto. + (fhandler_pty_master::read): Ditto. + * syscalls.cc (readv): Remove bg_check call and setting process state. + (writev): Ditto. + 2011-05-05 Corinna Vinschen * syscalls.cc (readv): Add myfault handler. Don't check repeatedly diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 8a5ff1830..b33b14dee 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -247,6 +247,8 @@ fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event) void __stdcall fhandler_console::read (void *pv, size_t& buflen) { + push_process_state process_state (PID_TTYIN); + HANDLE h = get_io_handle (); #define buf ((char *) pv) @@ -288,6 +290,7 @@ restart: goto restart; goto sig_exit; case WAIT_OBJECT_0 + 2: + process_state.pop (); pthread::static_cancel_self (); /*NOTREACHED*/ case WAIT_TIMEOUT: @@ -1814,6 +1817,12 @@ do_print: ssize_t __stdcall fhandler_console::write (const void *vsrc, size_t len) { + bg_check_types bg = bg_check (SIGTTOU); + if (bg <= bg_eof) + return (ssize_t) bg; + + push_process_state process_state (PID_TTYOU); + /* Run and check for ansi sequences */ unsigned const char *src = (unsigned char *) vsrc; unsigned const char *end = src + len; diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 2eb430e14..f55eab21e 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -746,8 +746,14 @@ fhandler_tty_slave::write (const void *ptr, size_t len) { DWORD n, towrite = len; + bg_check_types bg = bg_check (SIGTTOU); + if (bg <= bg_eof) + return (ssize_t) bg; + termios_printf ("tty%d, write(%x, %d)", get_unit (), ptr, len); + push_process_state process_state (PID_TTYOU); + acquire_output_mutex (INFINITE); while (len) @@ -807,8 +813,17 @@ fhandler_tty_slave::read (void *ptr, size_t& len) char peek_buf[INP_BUFFER_SIZE]; DWORD time_to_wait; + bg_check_types bg = bg_check (SIGTTIN); + if (bg <= bg_eof) + { + len = (size_t) bg; + return; + } + termios_printf ("read(%x, %d) handle %p", ptr, len, get_handle ()); + push_process_state process_state (PID_TTYIN); + if (is_nonblocking () || !ptr) /* Indicating tcflush(). */ time_to_wait = 0; else if ((get_ttyp ()->ti.c_lflag & ICANON)) @@ -848,6 +863,7 @@ fhandler_tty_slave::read (void *ptr, size_t& len) totalread = -1; goto out; case WAIT_OBJECT_0 + 2: + process_state.pop (); pthread::static_cancel_self (); /*NOTREACHED*/ case WAIT_TIMEOUT: @@ -885,6 +901,7 @@ fhandler_tty_slave::read (void *ptr, size_t& len) totalread = -1; goto out; case WAIT_OBJECT_0 + 2: + process_state.pop (); pthread::static_cancel_self (); /*NOTREACHED*/ case WAIT_TIMEOUT: @@ -1525,6 +1542,12 @@ fhandler_pty_master::write (const void *ptr, size_t len) char *p = (char *) ptr; termios ti = tc->ti; + bg_check_types bg = bg_check (SIGTTOU); + if (bg <= bg_eof) + return (ssize_t) bg; + + push_process_state process_state (PID_TTYOU); + for (i = 0; i < (int) len; i++) { line_edit_status status = line_edit (p++, 1, ti); @@ -1541,6 +1564,13 @@ fhandler_pty_master::write (const void *ptr, size_t len) void __stdcall fhandler_pty_master::read (void *ptr, size_t& len) { + bg_check_types bg = bg_check (SIGTTIN); + if (bg <= bg_eof) + { + len = (size_t) bg; + return; + } + push_process_state process_state (PID_TTYIN); len = (size_t) process_slave_output ((char *) ptr, len, pktmode); } diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index b47b59f7f..ed8a4aecf 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -224,6 +224,23 @@ cygwin_pid (pid_t pid) void __stdcall pinfo_init (char **, int); extern pinfo myself; +/* Helper class to allow convenient setting and unsetting a process_state + flag in myself. This is used in certain fhandler read/write methods + to set the PID_TTYIN/PID_TTYOU flags in myself->process_state. */ +class push_process_state +{ +private: + int flag; +public: + push_process_state (int add_flag) + { + flag = add_flag; + myself->process_state |= flag; + } + void pop () { myself->process_state &= ~(flag); } + ~push_process_state () { pop (); } +}; + #define _P_VFORK 0 #define _P_SYSTEM 512 /* Add this flag in calls to spawn_guts if the calling function is one of diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index b086554c5..5585b332a 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -994,17 +994,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt) while (1) { - /* Check to see if this is a background read from a "tty", - sending a SIGTTIN, if appropriate */ - res = cfd->bg_check (SIGTTIN); - - if (res > bg_eof) - { - myself->process_state |= PID_TTYIN; - res = cfd->readv (iov, iovcnt, tot); - myself->process_state &= ~PID_TTYIN; - } - + res = cfd->readv (iov, iovcnt, tot); if (res >= 0 || get_errno () != EINTR || !_my_tls.call_signal_handler ()) break; set_errno (e); @@ -1051,14 +1041,7 @@ writev (const int fd, const struct iovec *const iov, const int iovcnt) else syscall_printf ("writev (%d, %p, %d)", fd, iov, iovcnt); - res = cfd->bg_check (SIGTTOU); - - if (res > (int) bg_eof) - { - myself->process_state |= PID_TTYOU; - res = cfd->writev (iov, iovcnt, tot); - myself->process_state &= ~PID_TTYOU; - } + res = cfd->writev (iov, iovcnt, tot); done: if (fd == 1 || fd == 2)