From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7868) id 2950C3858D35; Sun, 20 Feb 2022 11:17:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2950C3858D35 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Takashi Yano To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/cygwin-3_3-branch] Cygwin: pty, console: Refactor the code processing special keys. X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/cygwin-3_3-branch X-Git-Oldrev: 6b676704090110efe653bb465eef00c59a565ba2 X-Git-Newrev: ba7b912feba3178e530a484afea4cb127e7f2ae7 Message-Id: <20220220111753.2950C3858D35@sourceware.org> Date: Sun, 20 Feb 2022 11:17:53 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Feb 2022 11:17:53 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Dba7b912feba= 3178e530a484afea4cb127e7f2ae7 commit ba7b912feba3178e530a484afea4cb127e7f2ae7 Author: Takashi Yano Date: Tue Feb 15 23:23:50 2022 +0900 Cygwin: pty, console: Refactor the code processing special keys. =20 - This patch commonize the code which processes special keys in pty and console to improve maintanancibility. As a result, some small bugs have been fixed. Diff: --- winsup/cygwin/dtable.cc | 1 + winsup/cygwin/exceptions.cc | 15 +++ winsup/cygwin/fhandler.h | 17 ++- winsup/cygwin/fhandler_console.cc | 135 ++++++++------------ winsup/cygwin/fhandler_termios.cc | 259 ++++++++++++++++++++++++----------= ---- winsup/cygwin/fhandler_tty.cc | 55 +++----- winsup/cygwin/tty.h | 2 +- 7 files changed, 264 insertions(+), 220 deletions(-) diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index d57cbb355..ce5f6411b 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -419,6 +419,7 @@ dtable::init_std_file_from_handle (int fd, HANDLE handl= e) cygheap->fdtab[fd]->inc_refcnt (); set_std_handle (fd); paranoid_printf ("fd %d, handle %p", fd, handle); + fh->post_open_setup (fd); } } =20 diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index a914110fe..356d69d6a 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1147,6 +1147,19 @@ ctrl_c_handler (DWORD type) return TRUE; =20 tty_min *t =3D cygwin_shared->tty.get_cttyp (); + + /* If process group leader is non-cygwin process or not exist, + send signal to myself. */ + pinfo pi (t->getpgid ()); + if ((!pi || (pi->process_state & PID_NOTCYGWIN)) + && (!have_execed || have_execed_cygwin) + && t->getpgid () =3D=3D myself->pgid + && type =3D=3D CTRL_C_EVENT) + { + t->output_stopped =3D false; + sig_send(myself, SIGINT); + } + /* Ignore this if we're not the process group leader since it should be handled *by* the process group leader. */ if (t && (!have_execed || have_execed_cygwin) @@ -1556,6 +1569,8 @@ dosig: if (have_execed) { sigproc_printf ("terminating captive process"); + if (::cygheap->ctty) + ::cygheap->ctty->cleanup_before_exit (); TerminateProcess (ch_spawn, sigExeced =3D si.si_signo); } /* Dispatch to the appropriate function. */ diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index c2d91ea11..f764eccd3 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -356,6 +356,7 @@ class fhandler_base virtual int open (int, mode_t); virtual fhandler_base *fd_reopen (int, mode_t); virtual bool open_setup (int flags); + virtual void post_open_setup (int fd) {} void set_unique_id (int64_t u) { unique_id =3D u; } void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); } =20 @@ -1901,6 +1902,13 @@ class fhandler_termios: public fhandler_base virtual void release_input_mutex_if_necessary (void) {}; virtual void discard_input () {}; =20 + enum process_sig_state { + signalled, + not_signalled, + not_signalled_but_done, + not_signalled_with_cyg_reader + }; + public: tty_min*& tc () {return _tc;} fhandler_termios () : @@ -1910,6 +1918,9 @@ class fhandler_termios: public fhandler_base } HANDLE& get_output_handle () { return output_handle; } HANDLE& get_output_handle_nat () { return output_handle; } + static process_sig_state process_sigs (char c, tty *ttyp, + fhandler_termios *fh); + static bool process_stop_start (char c, tty *ttyp, bool on_ixany); line_edit_status line_edit (const char *rptr, size_t nread, termios&, ssize_t *bytes_read =3D NULL); void set_output_handle (HANDLE h) { output_handle =3D h; } @@ -1943,6 +1954,8 @@ class fhandler_termios: public fhandler_base } static bool path_iscygexec_a (LPCSTR n, LPSTR c); static bool path_iscygexec_w (LPCWSTR n, LPWSTR c); + virtual bool is_pty_master_with_pcon () { return false; } + virtual void cleanup_before_exit () {} }; =20 enum ansi_intensity @@ -2047,7 +2060,6 @@ class dev_console char cons_rabuf[40]; // cannot get longer than char buf[40] in char_com= mand char *cons_rapoi; bool cursor_key_app_mode; - bool disable_master_thread; =20 inline UINT get_console_cp (); DWORD con_to_str (char *d, int dlen, WCHAR w); @@ -2147,6 +2159,7 @@ private: =20 int open (int flags, mode_t mode); bool open_setup (int flags); + void post_open_setup (int fd); int dup (fhandler_base *, int); =20 void __reg3 read (void *ptr, size_t& len); @@ -2370,6 +2383,7 @@ class fhandler_pty_slave: public fhandler_pty_common HANDLE input_available_event); HANDLE get_input_available_event (void) { return input_available_event; } bool pcon_activated (void) { return get_ttyp ()->pcon_activated; } + void cleanup_before_exit (); }; =20 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit)) @@ -2457,6 +2471,7 @@ public: void get_master_thread_param (master_thread_param_t *p); void get_master_fwd_thread_param (master_fwd_thread_param_t *p); void set_mask_flusho (bool m) { get_ttyp ()->mask_flusho =3D m; } + bool is_pty_master_with_pcon () { return get_ttyp ()->pcon_activated; } }; =20 class fhandler_dev_null: public fhandler_base diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_con= sole.cc index 9373e2602..d58ecfde6 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -188,13 +188,28 @@ cons_master_thread (VOID *arg) void fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp) { + termios &ti =3D ttyp->ti; DWORD output_stopped_at =3D 0; while (con.owner =3D=3D myself->pid) { DWORD total_read, n, i; INPUT_RECORD input_rec[INREC_SIZE]; =20 - if (con.disable_master_thread) + bool nat_fg =3D false; + bool nat_child_fg =3D false; + winpids pids ((DWORD) 0); + for (unsigned i =3D 0; i < pids.npids; i++) + { + _pinfo *pi =3D pids[i]; + if (pi && pi->ctty =3D=3D ttyp->ntty && pi->pgid =3D=3D ttyp->getpgid () + && (pi->process_state & PID_NOTCYGWIN) + && !(pi->process_state & PID_NEW_PG)) + nat_fg =3D true; + if (pi && pi->ctty =3D=3D ttyp->ntty && pi->pgid =3D=3D ttyp->getpgid () + && !(pi->process_state & PID_CYGPARENT)) + nat_child_fg =3D true; + } + if (nat_fg && !nat_child_fg) { cygwait (40); continue; @@ -233,90 +248,35 @@ fhandler_console::cons_master_thread (handle_set_t *p= , tty *ttyp) } for (i =3D 0; i < total_read; i++) { - const wchar_t wc =3D input_rec[i].Event.KeyEvent.uChar.UnicodeChar; - if ((wint_t) wc >=3D 0x80) - continue; - char c =3D (char) wc; + wchar_t wc; + char c; + bool was_output_stopped; bool processed =3D false; - termios &ti =3D ttyp->ti; - pinfo pi (ttyp->getpgid ()); - if (pi && pi->ctty =3D=3D ttyp->ntty - && (pi->process_state & PID_NOTCYGWIN) - && input_rec[i].EventType =3D=3D KEY_EVENT && c =3D=3D '\003') - { - bool not_a_sig =3D false; - if (!CCEQ (ti.c_cc[VINTR], c) - && !CCEQ (ti.c_cc[VQUIT], c) - && !CCEQ (ti.c_cc[VSUSP], c)) - not_a_sig =3D true; - if (input_rec[i].Event.KeyEvent.bKeyDown) - { - /* CTRL_C_EVENT does not work for the process started with - CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT - instead. */ - if (pi->process_state & PID_NEW_PG) - GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, - pi->dwProcessId); - else - GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0); - if (not_a_sig) - goto skip_writeback; - } - processed =3D true; - if (not_a_sig) - goto remove_record; - } switch (input_rec[i].EventType) { case KEY_EVENT: - if (ti.c_lflag & ISIG) - { - int sig =3D 0; - if (CCEQ (ti.c_cc[VINTR], c)) - sig =3D SIGINT; - else if (CCEQ (ti.c_cc[VQUIT], c)) - sig =3D SIGQUIT; - else if (CCEQ (ti.c_cc[VSUSP], c)) - sig =3D SIGTSTP; - if (sig && input_rec[i].Event.KeyEvent.bKeyDown) - { - ttyp->kill_pgrp (sig); - ttyp->output_stopped =3D false; - ti.c_lflag &=3D ~FLUSHO; - /* Discard type ahead input */ - goto skip_writeback; - } - } - if (ti.c_iflag & IXON) - { - if (CCEQ (ti.c_cc[VSTOP], c)) - { - if (!ttyp->output_stopped - && input_rec[i].Event.KeyEvent.bKeyDown) - { - ttyp->output_stopped =3D true; - output_stopped_at =3D i; - } - processed =3D true; - } - else if (CCEQ (ti.c_cc[VSTART], c)) - { - restart_output: - if (input_rec[i].Event.KeyEvent.bKeyDown) - ttyp->output_stopped =3D false; - processed =3D true; - } - else if ((ti.c_iflag & IXANY) && ttyp->output_stopped - && c && i >=3D output_stopped_at) - goto restart_output; - } - if ((ti.c_lflag & ICANON) && (ti.c_lflag & IEXTEN) - && CCEQ (ti.c_cc[VDISCARD], c)) + if (!input_rec[i].Event.KeyEvent.bKeyDown) + continue; + wc =3D input_rec[i].Event.KeyEvent.uChar.UnicodeChar; + if (!wc || (wint_t) wc >=3D 0x80) + continue; + c =3D (char) wc; + switch (process_sigs (c, ttyp, NULL)) { - if (input_rec[i].Event.KeyEvent.bKeyDown) - ti.c_lflag ^=3D FLUSHO; + case signalled: + case not_signalled_but_done: processed =3D true; + ttyp->output_stopped =3D false; + if (ti.c_lflag & NOFLSH) + goto remove_record; + goto skip_writeback; + default: /* not signalled */ + break; } + was_output_stopped =3D ttyp->output_stopped; + processed =3D process_stop_start (c, ttyp, i > output_stopped_at); + if (!was_output_stopped && ttyp->output_stopped) + output_stopped_at =3D i; break; case WINDOW_BUFFER_SIZE_EVENT: SHORT y =3D con.dwWinSize.Y; @@ -447,7 +407,6 @@ fhandler_console::setup () con.cons_rapoi =3D NULL; shared_console_info->tty_min_state.is_console =3D true; con.cursor_key_app_mode =3D false; - con.disable_master_thread =3D false; } } =20 @@ -503,8 +462,6 @@ fhandler_console::set_input_mode (tty::cons_mode m, con= st termios *t, flags |=3D ENABLE_VIRTUAL_TERMINAL_INPUT; else flags |=3D ENABLE_MOUSE_INPUT; - if (shared_console_info) - con.disable_master_thread =3D false; break; case tty::native: if (t->c_lflag & ECHO) @@ -517,8 +474,6 @@ fhandler_console::set_input_mode (tty::cons_mode m, con= st termios *t, flags &=3D ~ENABLE_ECHO_INPUT; if (t->c_lflag & ISIG) flags |=3D ENABLE_PROCESSED_INPUT; - if (shared_console_info) - con.disable_master_thread =3D true; break; } SetConsoleMode (p->input_handle, flags); @@ -1394,9 +1349,6 @@ fhandler_console::open (int flags, mode_t) setenv ("TERM", "cygwin", 1); } =20 - set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set); - set_output_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set); - debug_printf ("opened conin$ %p, conout$ %p", get_handle (), get_output_handle ()); =20 @@ -1421,6 +1373,17 @@ fhandler_console::open_setup (int flags) return fhandler_base::open_setup (flags); } =20 +void +fhandler_console::post_open_setup (int fd) +{ + if (fd =3D=3D 0) + set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set); + else if (fd =3D=3D 1 || fd =3D=3D 2) + set_output_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set); + + fhandler_base::post_open_setup (fd); +} + int fhandler_console::close () { diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_ter= mios.cc index b935a70bc..46c861928 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -130,8 +130,9 @@ is_flush_sig (int sig) } =20 void -tty_min::kill_pgrp (int sig) +tty_min::kill_pgrp (int sig, pid_t target_pgid) { + target_pgid =3D target_pgid ?: pgid; bool killself =3D false; if (is_flush_sig (sig) && cygheap->ctty) cygheap->ctty->sigflush (); @@ -145,7 +146,7 @@ tty_min::kill_pgrp (int sig) for (unsigned i =3D 0; i < pids.npids; i++) { _pinfo *p =3D pids[i]; - if (!p || !p->exists () || p->ctty !=3D ntty || p->pgid !=3D pgid) + if (!p || !p->exists () || p->ctty !=3D ntty || p->pgid !=3D target_= pgid) continue; if (p->process_state & PID_NOTCYGWIN) continue; @@ -308,6 +309,156 @@ fhandler_termios::echo_erase (int force) doecho ("\b \b", 3); } =20 +fhandler_termios::process_sig_state +fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh) +{ + termios &ti =3D ttyp->ti; + pid_t pgid =3D ttyp->pgid; + + pinfo leader (pgid); + bool cyg_leader =3D leader && !(leader->process_state & PID_NOTCYGWIN); + bool ctrl_c_event_sent =3D false; + bool need_discard_input =3D false; + bool pg_with_nat =3D false; + bool need_send_sig =3D false; + bool nat_shell =3D false; + bool cyg_reader =3D false; + + winpids pids ((DWORD) 0); + for (unsigned i =3D 0; i < pids.npids; i++) + { + _pinfo *p =3D pids[i]; + if (c =3D=3D '\003' && p && p->ctty =3D=3D ttyp->ntty && p->pgid =3D= =3D pgid + && ((p->process_state & PID_NOTCYGWIN) + || !(p->process_state & PID_CYGPARENT))) + { + pinfo pinfo_resume =3D pinfo (myself->ppid); + DWORD resume_pid =3D 0; + if (pinfo_resume) + resume_pid =3D pinfo_resume->dwProcessId; + else + resume_pid =3D fhandler_pty_common::get_console_process_id + (myself->dwProcessId, false); + if (resume_pid && fh && !fh->is_console ()) + { + FreeConsole (); + AttachConsole (p->dwProcessId); + } + /* CTRL_C_EVENT does not work for the process started with + CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT + instead. */ + if (p->process_state & PID_NEW_PG) + GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, + p->dwProcessId); + else if ((!fh || !fh->is_pty_master_with_pcon () || cyg_leader) + && !ctrl_c_event_sent) + { + GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0); + ctrl_c_event_sent =3D true; + } + if (resume_pid && fh && !fh->is_console ()) + { + FreeConsole (); + AttachConsole (resume_pid); + } + need_discard_input =3D true; + } + if (p && p->ctty =3D=3D ttyp->ntty && p->pgid =3D=3D pgid) + { + if (p->process_state & PID_NOTCYGWIN) + pg_with_nat =3D true; + if (!(p->process_state & PID_NOTCYGWIN)) + need_send_sig =3D true; + if (!p->cygstarted) + nat_shell =3D true; + if (p->process_state & PID_TTYIN) + cyg_reader =3D true; + } + } + /* Send SIGQUIT to non-cygwin process. */ + if ((ti.c_lflag & ISIG) && CCEQ (ti.c_cc[VQUIT], c) + && pg_with_nat && need_send_sig && !nat_shell) + { + for (unsigned i =3D 0; i < pids.npids; i++) + { + _pinfo *p =3D pids[i]; + if (p && p->ctty =3D=3D ttyp->ntty && p->pgid =3D=3D pgid + && (p->process_state & PID_NOTCYGWIN)) + sig_send (p, SIGQUIT); + } + } + if ((ti.c_lflag & ISIG) && need_send_sig) + { + int sig; + if (CCEQ (ti.c_cc[VINTR], c)) + sig =3D SIGINT; + else if (CCEQ (ti.c_cc[VQUIT], c)) + sig =3D SIGQUIT; + else if (pg_with_nat) + goto not_a_sig; + else if (CCEQ (ti.c_cc[VSUSP], c)) + sig =3D SIGTSTP; + else + goto not_a_sig; + + termios_printf ("got interrupt %d, sending signal %d", c, sig); + if (!(ti.c_lflag & NOFLSH) && fh) + { + fh->eat_readahead (-1); + fh->discard_input (); + } + if (fh) + fh->release_input_mutex_if_necessary (); + ttyp->kill_pgrp (sig, pgid); + if (fh) + fh->acquire_input_mutex_if_necessary (mutex_timeout); + ti.c_lflag &=3D ~FLUSHO; + return signalled; + } +not_a_sig: + if (need_discard_input) + { + if (!(ti.c_lflag & NOFLSH) && fh) + { + fh->eat_readahead (-1); + fh->discard_input (); + } + ti.c_lflag &=3D ~FLUSHO; + return not_signalled_but_done; + } + bool to_cyg =3D cyg_reader || !pg_with_nat; + return to_cyg ? not_signalled_with_cyg_reader : not_signalled; +} + +bool +fhandler_termios::process_stop_start (char c, tty *ttyp, bool on_ixany) +{ + termios &ti =3D ttyp->ti; + if (ti.c_iflag & IXON) + { + if (CCEQ (ti.c_cc[VSTOP], c)) + { + ttyp->output_stopped =3D true; + return true; + } + else if (CCEQ (ti.c_cc[VSTART], c)) + { +restart_output: + ttyp->output_stopped =3D false; + return true; + } + else if ((ti.c_iflag & IXANY) && ttyp->output_stopped && on_ixany) + goto restart_output; + } + if ((ti.c_lflag & ICANON) && (ti.c_lflag & IEXTEN) + && CCEQ (ti.c_cc[VDISCARD], c)) + { + ti.c_lflag ^=3D FLUSHO; + return true; + } + return false; +} + line_edit_status fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti, ssize_t *bytes_read) @@ -328,92 +479,24 @@ fhandler_termios::line_edit (const char *rptr, size_t= nread, termios& ti, =20 if (ti.c_iflag & ISTRIP) c &=3D 0x7f; - winpids pids ((DWORD) 0); - bool need_check_sigs =3D get_ttyp ()->pcon_input_state_eq (tty::to_c= yg); - if (get_ttyp ()->pcon_input_state_eq (tty::to_nat)) + bool disable_eof_key =3D true; + switch (process_sigs (c, get_ttyp (), this)) { - bool need_discard_input =3D false; - for (unsigned i =3D 0; i < pids.npids; i++) - { - _pinfo *p =3D pids[i]; - if (c =3D=3D '\003' && p && p->ctty =3D=3D tc ()->ntty - && p->pgid =3D=3D tc ()->getpgid () - && (p->process_state & PID_NOTCYGWIN)) - { - /* CTRL_C_EVENT does not work for the process started with - CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT - instead. */ - if (p->process_state & PID_NEW_PG) - GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, - p->dwProcessId); - else - GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0); - need_discard_input =3D true; - } - if (p->ctty =3D=3D get_ttyp ()->ntty - && p->pgid =3D=3D get_ttyp ()->getpgid () && !p->cygstarted) - need_check_sigs =3D true; - } - if (!CCEQ (ti.c_cc[VINTR], c) - && !CCEQ (ti.c_cc[VQUIT], c) - && !CCEQ (ti.c_cc[VSUSP], c)) - need_check_sigs =3D false; - if (need_discard_input && !need_check_sigs) - { - if (!(ti.c_lflag & NOFLSH)) - { - eat_readahead (-1); - discard_input (); - } - ti.c_lflag &=3D ~FLUSHO; - continue; - } - } - if ((ti.c_lflag & ISIG) && need_check_sigs) - { - int sig; - if (CCEQ (ti.c_cc[VINTR], c)) - sig =3D SIGINT; - else if (CCEQ (ti.c_cc[VQUIT], c)) - sig =3D SIGQUIT; - else if (CCEQ (ti.c_cc[VSUSP], c)) - sig =3D SIGTSTP; - else - goto not_a_sig; - - termios_printf ("got interrupt %d, sending signal %d", c, sig); - if (!(ti.c_lflag & NOFLSH)) - { - eat_readahead (-1); - discard_input (); - } - release_input_mutex_if_necessary (); - tc ()->kill_pgrp (sig); - acquire_input_mutex_if_necessary (mutex_timeout); - ti.c_lflag &=3D ~FLUSHO; + case signalled: sawsig =3D true; - goto restart_output; - } - not_a_sig: - if (ti.c_iflag & IXON) - { - if (CCEQ (ti.c_cc[VSTOP], c)) - { - if (!tc ()->output_stopped) - tc ()->output_stopped =3D true; - continue; - } - else if (CCEQ (ti.c_cc[VSTART], c)) - { - restart_output: - tc ()->output_stopped =3D false; - continue; - } - else if ((ti.c_iflag & IXANY) && tc ()->output_stopped) - goto restart_output; + fallthrough; + case not_signalled_but_done: + get_ttyp ()->output_stopped =3D false; + continue; + case not_signalled_with_cyg_reader: + disable_eof_key =3D false; + break; + default: /* Not signalled */ + break; } + if (process_stop_start (c, get_ttyp (), true)) + continue; /* Check for special chars */ - if (c =3D=3D '\r') { if (ti.c_iflag & IGNCR) @@ -432,12 +515,6 @@ fhandler_termios::line_edit (const char *rptr, size_t = nread, termios& ti, set_input_done (iscanon); } =20 - if (iscanon && ti.c_lflag & IEXTEN && CCEQ (ti.c_cc[VDISCARD], c)) - { - ti.c_lflag ^=3D FLUSHO; - continue; - } - if (!iscanon) /* nothing */; else if (CCEQ (ti.c_cc[VERASE], c)) @@ -474,7 +551,7 @@ fhandler_termios::line_edit (const char *rptr, size_t n= read, termios& ti, } continue; } - else if (CCEQ (ti.c_cc[VEOF], c) && need_check_sigs) + else if (CCEQ (ti.c_cc[VEOF], c) && !disable_eof_key) { termios_printf ("EOF"); accept_input (); diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 5ba50cc73..a25690a0e 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -2291,47 +2291,12 @@ fhandler_pty_master::write (const void *ptr, size_t= len) &mbp); } =20 - if ((ti.c_lflag & ISIG) && memchr (buf, '\003', nlen)) - { - /* If the process is started with CREATE_NEW_PROCESS_GROUP - flag, Ctrl-C will not be sent to that process. Therefore, - send Ctrl-break event to that process here. */ - DWORD wpid =3D 0; - winpids pids ((DWORD) 0); - for (unsigned i =3D 0; i < pids.npids; i++) - { - _pinfo *p =3D pids[i]; - if (p->ctty =3D=3D get_ttyp ()->ntty - && p->pgid =3D=3D get_ttyp ()->getpgid () - && (p->process_state & PID_NOTCYGWIN) - && (p->process_state & PID_NEW_PG)) - { - wpid =3D p->dwProcessId; - break; - } - } - pinfo pinfo_resume =3D pinfo (myself->ppid); - DWORD resume_pid; - if (pinfo_resume) - resume_pid =3D pinfo_resume->dwProcessId; - else - resume_pid =3D get_console_process_id (myself->dwProcessId, false); - if (wpid && resume_pid) - { - WaitForSingleObject (pcon_mutex, INFINITE); - FreeConsole (); - AttachConsole (wpid); - /* CTRL_C_EVENT does not work for the process started with - CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT - instead. */ - GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, wpid); - FreeConsole (); - AttachConsole (resume_pid); - ReleaseMutex (pcon_mutex); - } - if (!(ti.c_lflag & NOFLSH)) - get_ttyp ()->discard_input =3D true; + for (size_t i =3D 0; i < nlen; i++) + { + fhandler_termios::process_sigs (buf[i], get_ttyp (), this); + process_stop_start (buf[i], get_ttyp (), true); } + DWORD n; WriteFile (to_slave_nat, buf, nlen, &n, NULL); ReleaseMutex (input_mutex); @@ -2885,7 +2850,8 @@ fhandler_pty_master::pty_master_fwd_thread (const mas= ter_fwd_thread_param_t *p) WaitForSingleObject (p->output_mutex, mutex_timeout); while (rlen>0) { - if (!process_opost_output (p->to_master, ptr, wlen, false, + if (!process_opost_output (p->to_master, ptr, wlen, + true /* disable output_stopped */, p->ttyp, false)) { termios_printf ("WriteFile for forwarding failed, %E"); @@ -4006,3 +3972,10 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir di= r, HANDLE from, tty *ttyp, ttyp->pcon_input_state =3D dir; ttyp->discard_input =3D false; } + +void +fhandler_pty_slave::cleanup_before_exit () +{ + if (myself->process_state & PID_NOTCYGWIN) + get_ttyp ()->wait_pcon_fwd (); +} diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index 2cd12a665..87ff43ea2 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -75,7 +75,7 @@ public: void setpgid (int pid); int getsid () const {return sid;} void setsid (pid_t tsid) {sid =3D tsid;} - void kill_pgrp (int); + void kill_pgrp (int, pid_t target_pgid =3D 0); int is_orphaned_process_group (int); const __reg1 char *ttyname () __attribute (()); };