From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7868) id 7BFD03858416; Wed, 23 Feb 2022 17:48:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7BFD03858416 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: console: Redesign handling of special keys. X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/master X-Git-Oldrev: 4ed502ba02270adee7c46bb738374cab867baee1 X-Git-Newrev: d2b14c303c04989ae87bf1341357d059d266bf02 Message-Id: <20220223174850.7BFD03858416@sourceware.org> Date: Wed, 23 Feb 2022 17:48:50 +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: Wed, 23 Feb 2022 17:48:50 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Dd2b14c303c0= 4989ae87bf1341357d059d266bf02 commit d2b14c303c04989ae87bf1341357d059d266bf02 Author: Takashi Yano Date: Wed Feb 23 13:24:39 2022 +0900 Cygwin: console: Redesign handling of special keys. =20 - This patch rearranges the cooperation between cons_master_thread, line_edit, and ctrl_c_handler so that only one of them operates at the same time. Since these handle Ctrl-C individually, so the signal may be sent multiple times to the process. This patch fixes the issue. Diff: --- winsup/cygwin/fhandler.h | 7 +++--- winsup/cygwin/fhandler_console.cc | 49 ++++++++++++++++++++++++-----------= ---- winsup/cygwin/fhandler_termios.cc | 29 +++++++++++++---------- winsup/cygwin/sigproc.cc | 3 ++- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f54eae4c9..b252b6e1c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1906,7 +1906,7 @@ class fhandler_termios: public fhandler_base signalled, not_signalled, not_signalled_but_done, - not_signalled_with_cyg_reader + not_signalled_with_nat_reader }; =20 public: @@ -1954,9 +1954,9 @@ 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 () {} virtual void setpgid_aux (pid_t pid) {} + virtual bool need_console_handler () { return false; } }; =20 enum ansi_intensity @@ -2061,6 +2061,7 @@ 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); @@ -2253,6 +2254,7 @@ private: void setup_for_non_cygwin_app (); static void cleanup_for_non_cygwin_app (handle_set_t *p); static void set_console_mode_to_native (); + bool need_console_handler (); =20 friend tty_min * tty_list::get_cttyp (); }; @@ -2489,7 +2491,6 @@ 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 ec33a9d3c..a7516f238 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -195,21 +195,7 @@ fhandler_console::cons_master_thread (handle_set_t *p,= tty *ttyp) DWORD total_read, n, i; INPUT_RECORD input_rec[INREC_SIZE]; =20 - 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) + if (con.disable_master_thread) { cygwait (40); continue; @@ -403,6 +389,7 @@ 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 true; } } =20 @@ -519,6 +506,7 @@ fhandler_console::setup_for_non_cygwin_app () (get_ttyp ()->getpgid ()=3D=3D myself->pgid) ? tty::native : tty::rest= ore; set_input_mode (conmode, &tc ()->ti, get_handle_set ()); set_output_mode (conmode, &tc ()->ti, get_handle_set ()); + con.disable_master_thread =3D true; } =20 void @@ -534,6 +522,7 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_se= t_t *p) (con.owner =3D=3D myself->pid) ? tty::restore : tty::cygwin; set_output_mode (conmode, ti, p); set_input_mode (conmode, ti, p); + con.disable_master_thread =3D (con.owner =3D=3D myself->pid); } =20 /* Return the tty structure associated with a given tty number. If the @@ -707,7 +696,14 @@ fhandler_console::bg_check (int sig, bool dontsignal) cygwin app and other non-cygwin apps are started simultaneously in the same process group. */ if (sig =3D=3D SIGTTIN) - set_input_mode (tty::cygwin, &tc ()->ti, get_handle_set ()); + { + set_input_mode (tty::cygwin, &tc ()->ti, get_handle_set ()); + if (con.disable_master_thread) + { + con.disable_master_thread =3D false; + init_console_handler (false); + } + } if (sig =3D=3D SIGTTOU) set_output_mode (tty::cygwin, &tc ()->ti, get_handle_set ()); =20 @@ -1409,8 +1405,7 @@ bool fhandler_console::open_setup (int flags) { set_flags ((flags & ~O_TEXT) | O_BINARY); - if (myself->set_ctty (this, flags) && !myself->cygstarted) - init_console_handler (true); + myself->set_ctty (this, flags); return fhandler_base::open_setup (flags); } =20 @@ -1419,10 +1414,15 @@ fhandler_console::post_open_setup (int fd) { /* Setting-up console mode for cygwin app started from non-cygwin app. */ if (fd =3D=3D 0) - set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set); + { + set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set); + con.disable_master_thread =3D false; + } else if (fd =3D=3D 1 || fd =3D=3D 2) set_output_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set); =20 + init_console_handler (need_console_handler ()); + fhandler_base::post_open_setup (fd); } =20 @@ -1446,6 +1446,7 @@ fhandler_console::close () /* Cleaning-up console mode for cygwin apps. */ set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set); set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set); + con.disable_master_thread =3D true; } } =20 @@ -3617,6 +3618,7 @@ fhandler_console::set_console_mode_to_native () termios *cons_ti =3D &cons->tc ()->ti; set_input_mode (tty::native, cons_ti, cons->get_handle_set ()); set_output_mode (tty::native, cons_ti, cons->get_handle_set ()); + con.disable_master_thread =3D true; break; } } @@ -3639,6 +3641,7 @@ CreateProcessA_Hooked gdb_inferior_noncygwin =3D !fhandler_termios::path_iscygexec_a (n, c); if (gdb_inferior_noncygwin) fhandler_console::set_console_mode_to_native (); + init_console_handler (false); return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi); } =20 @@ -3653,6 +3656,7 @@ CreateProcessW_Hooked gdb_inferior_noncygwin =3D !fhandler_termios::path_iscygexec_w (n, c); if (gdb_inferior_noncygwin) fhandler_console::set_console_mode_to_native (); + init_console_handler (false); return CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, si, pi); } =20 @@ -3662,6 +3666,7 @@ ContinueDebugEvent_Hooked { if (gdb_inferior_noncygwin) fhandler_console::set_console_mode_to_native (); + init_console_handler (false); return ContinueDebugEvent_Orig (p, t, s); } =20 @@ -3929,3 +3934,9 @@ fhandler_console::close_handle_set (handle_set_t *p) CloseHandle (p->output_mutex); p->output_mutex =3D NULL; } + +bool +fhandler_console::need_console_handler () +{ + return con.disable_master_thread; +} diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_ter= mios.cc index 46c861928..953aeade0 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -315,8 +315,6 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhan= dler_termios *fh) termios &ti =3D ttyp->ti; pid_t pgid =3D ttyp->pgid; =20 - 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; @@ -344,24 +342,31 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fh= andler_termios *fh) FreeConsole (); AttachConsole (p->dwProcessId); } + if (fh && p =3D=3D myself) + { /* Avoid deadlock in gdb on console. */ + fh->tcflush(TCIFLUSH); + fh->release_input_mutex_if_necessary (); + } /* 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_BREAK_EVENT, + p->dwProcessId); + need_discard_input =3D true; + } + else if (!ctrl_c_event_sent) { GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0); ctrl_c_event_sent =3D true; + need_discard_input =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) { @@ -426,8 +431,8 @@ not_a_sig: 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 to_nat =3D !cyg_reader && pg_with_nat; + return to_nat ? not_signalled_with_nat_reader : not_signalled; } =20 bool @@ -479,7 +484,7 @@ fhandler_termios::line_edit (const char *rptr, size_t n= read, termios& ti, =20 if (ti.c_iflag & ISTRIP) c &=3D 0x7f; - bool disable_eof_key =3D true; + bool disable_eof_key =3D false; switch (process_sigs (c, get_ttyp (), this)) { case signalled: @@ -488,8 +493,8 @@ fhandler_termios::line_edit (const char *rptr, size_t n= read, termios& ti, case not_signalled_but_done: get_ttyp ()->output_stopped =3D false; continue; - case not_signalled_with_cyg_reader: - disable_eof_key =3D false; + case not_signalled_with_nat_reader: + disable_eof_key =3D true; break; default: /* Not signalled */ break; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 4d7d273ae..16ea5031b 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -1392,7 +1392,8 @@ wait_sig (VOID *) sig_held =3D true; break; case __SIGSETPGRP: - init_console_handler (true); + if (::cygheap->ctty) + init_console_handler (::cygheap->ctty->need_console_handler ()); break; case __SIGTHREADEXIT: {