From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7868) id AE1623959C4B; Sun, 20 Nov 2022 09:46:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AE1623959C4B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1668937592; bh=PIXrByPY3sjIdALGgQ+EYYSEAAXDJ/X6I7D97iE3e6A=; h=From:To:Subject:Date:From; b=nEs9WhKUO+5hqn3esePRnySy78VhMHFs/2IFDbgmVyKo45uM8k7v3522eoGTVfnw4 d2dpMyv0pPdSWk/kZC8+UPjjaYDvpdqo4P9Kkf/jp1Bz9oxsKfpX1hYHACdwO8xHmZ DD4xcCtKoL63T79B+Drg39jOKPA8kQqJKwAD+N3I= 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: pty, console: Encapsulate spawn.cc code related to pty/console. X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/master X-Git-Oldrev: c03f0c306244bf73239cb1a318a175682f504dc2 X-Git-Newrev: 32d6a6cb5f1e5a136ae86247e124edd68dc1800e Message-Id: <20221120094632.AE1623959C4B@sourceware.org> Date: Sun, 20 Nov 2022 09:46:32 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D32d6a6cb5f1= e5a136ae86247e124edd68dc1800e commit 32d6a6cb5f1e5a136ae86247e124edd68dc1800e Author: Takashi Yano Date: Sat Nov 19 17:28:15 2022 +0900 Cygwin: pty, console: Encapsulate spawn.cc code related to pty/console. =20 - The codes related to pty and console in spawn.cc have been moved into the new class fhandler_termios::spawn_worker, and make spawn.cc call them. The functionality has not been changed at all. Diff: --- winsup/cygwin/fhandler/termios.cc | 99 +++++++++++++++++++++++++++ winsup/cygwin/fhandler/tty.cc | 5 +- winsup/cygwin/local_includes/fhandler.h | 52 ++++++++++----- winsup/cygwin/spawn.cc | 114 +++-------------------------= ---- 4 files changed, 149 insertions(+), 121 deletions(-) diff --git a/winsup/cygwin/fhandler/termios.cc b/winsup/cygwin/fhandler/ter= mios.cc index 328c73fcd..517e74e77 100644 --- a/winsup/cygwin/fhandler/termios.cc +++ b/winsup/cygwin/fhandler/termios.cc @@ -692,6 +692,29 @@ fhandler_termios::tcgetsid () return -1; } =20 +static bool +is_console_app (const WCHAR *filename) +{ + HANDLE h; + const int id_offset =3D 92; + h =3D CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, 0, NULL); + char buf[1024]; + DWORD n; + ReadFile (h, buf, sizeof (buf), &n, 0); + CloseHandle (h); + char *p =3D (char *) memmem (buf, n, "PE\0\0", 4); + if (p && p + id_offset < buf + n) + return p[id_offset] =3D=3D '\003'; /* 02: GUI, 03: console */ + else + { + wchar_t *e =3D wcsrchr (filename, L'.'); + if (e && (wcscasecmp (e, L".bat") =3D=3D 0 || wcscasecmp (e, L".cmd"= ) =3D=3D 0)) + return true; + } + return false; +} + int fhandler_termios::ioctl (int cmd, void *varg) { @@ -718,3 +741,79 @@ fhandler_termios::ioctl (int cmd, void *varg) myself->set_ctty (this, 0); return 0; } + +void +fhandler_termios::spawn_worker::setup (bool iscygwin, HANDLE h_stdin, + const WCHAR *runpath, bool nopcon, + bool reset_sendsig, + const WCHAR *envblock) +{ + fhandler_pty_slave *ptys_primary =3D NULL; + fhandler_console *cons_native =3D NULL; + + for (int i =3D 0; i < 3; i ++) + { + const int chk_order[] =3D {1, 0, 2}; + int fd =3D chk_order[i]; + fhandler_base *fh =3D ::cygheap->fdtab[fd]; + if (fh && fh->get_major () =3D=3D DEV_PTYS_MAJOR && ptys_primary =3D= =3D NULL) + ptys_primary =3D (fhandler_pty_slave *) fh; + else if (fh && fh->get_major () =3D=3D DEV_CONS_MAJOR + && !iscygwin && cons_native =3D=3D NULL) + cons_native =3D (fhandler_console *) fh; + } + if (cons_native) + { + cons_native->setup_for_non_cygwin_app (); + /* Console handles will be already closed by close_all_files() + when cleaning up, therefore, duplicate them here. */ + cons_native->get_duplicated_handle_set (&cons_handle_set); + cons_need_cleanup =3D true; + } + if (!iscygwin) + { + int fd; + cygheap_fdenum cfd (false); + while ((fd =3D cfd.next ()) >=3D 0) + if (cfd->get_major () =3D=3D DEV_PTYS_MAJOR) + { + fhandler_pty_slave *ptys + =3D (fhandler_pty_slave *)(fhandler_base *) cfd; + ptys->create_invisible_console (); + ptys->setup_locale (); + } + } + if (!iscygwin && ptys_primary && is_console_app (runpath)) + { + if (h_stdin =3D=3D ptys_primary->get_handle_nat ()) + stdin_is_ptys =3D true; + if (reset_sendsig) + myself->sendsig =3D myself->exec_sendsig; + ptys_primary->setup_for_non_cygwin_app (nopcon, envblock, stdin_is_p= tys); + if (reset_sendsig) + myself->sendsig =3D NULL; + ptys_primary->get_duplicated_handle_set (&ptys_handle_set); + ptys_ttyp =3D (tty *) ptys_primary->tc (); + ptys_need_cleanup =3D true; + } +} + +void +fhandler_termios::spawn_worker::cleanup () +{ + if (ptys_need_cleanup) + fhandler_pty_slave::cleanup_for_non_cygwin_app (&ptys_handle_set, + ptys_ttyp, stdin_is_ptys); + if (cons_need_cleanup) + fhandler_console::cleanup_for_non_cygwin_app (&cons_handle_set); + close_handle_set (); +} + +void +fhandler_termios::spawn_worker::close_handle_set () +{ + if (ptys_need_cleanup) + fhandler_pty_slave::close_handle_set (&ptys_handle_set); + if (cons_need_cleanup) + fhandler_console::close_handle_set (&cons_handle_set); +} diff --git a/winsup/cygwin/fhandler/tty.cc b/winsup/cygwin/fhandler/tty.cc index 0f9dec570..7959d4b0a 100644 --- a/winsup/cygwin/fhandler/tty.cc +++ b/winsup/cygwin/fhandler/tty.cc @@ -247,7 +247,7 @@ atexit_func (void) tty *ttyp =3D (tty *) ptys->tc (); bool stdin_is_ptys =3D GetStdHandle (STD_INPUT_HANDLE) =3D=3D ptys->get_handle (); - struct fhandler_pty_slave::handle_set_t handles =3D + fhandler_pty_slave::handle_set_t handles =3D { ptys->get_handle_nat (), ptys->get_input_available_event (), @@ -4096,7 +4096,8 @@ fhandler_pty_slave::close_handle_set (handle_set_t *p) } =20 void -fhandler_pty_slave::setup_for_non_cygwin_app (bool nopcon, PWCHAR envblock, +fhandler_pty_slave::setup_for_non_cygwin_app (bool nopcon, + const WCHAR *envblock, bool stdin_is_ptys) { if (disable_pcon || !term_has_pcon_cap (envblock)) diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_= includes/fhandler.h index b012c6e8f..bc02eae66 100644 --- a/winsup/cygwin/local_includes/fhandler.h +++ b/winsup/cygwin/local_includes/fhandler.h @@ -1989,6 +1989,40 @@ class fhandler_termios: public fhandler_base virtual bool need_console_handler () { return false; } virtual bool need_send_ctrl_c_event () { return true; } virtual DWORD get_helper_pid () { return 0; } + + struct ptys_handle_set_t + { + HANDLE from_master_nat; + HANDLE input_available_event; + HANDLE input_mutex; + HANDLE pipe_sw_mutex; + }; + struct cons_handle_set_t + { + HANDLE input_handle; + HANDLE output_handle; + HANDLE input_mutex; + HANDLE output_mutex; + }; + class spawn_worker + { + private: + ptys_handle_set_t ptys_handle_set; + cons_handle_set_t cons_handle_set; + bool ptys_need_cleanup; + bool cons_need_cleanup; + bool stdin_is_ptys; + tty *ptys_ttyp; + public: + spawn_worker () : + ptys_need_cleanup (false), cons_need_cleanup (false), + stdin_is_ptys (false), ptys_ttyp (NULL) {} + void setup (bool iscygwin, HANDLE h_stdin, const WCHAR *runpath, + bool nopcon, bool reset_sendsig, const WCHAR *envblock); + bool need_cleanup () { return ptys_need_cleanup || cons_need_cleanup; } + void cleanup (); + void close_handle_set (); + }; }; =20 enum ansi_intensity @@ -2133,13 +2167,7 @@ public: input_signalled =3D 2, input_winch =3D 3 }; - struct handle_set_t - { - HANDLE input_handle; - HANDLE output_handle; - HANDLE input_mutex; - HANDLE output_mutex; - }; + typedef cons_handle_set_t handle_set_t; HANDLE thread_sync_event; private: static const unsigned MAX_WRITE_CHARS; @@ -2375,13 +2403,7 @@ class fhandler_pty_slave: public fhandler_pty_common public: pid_t tc_getpgid () { return _tc ? _tc->pgid : 0; } =20 - struct handle_set_t - { - HANDLE from_master_nat; - HANDLE input_available_event; - HANDLE input_mutex; - HANDLE pipe_sw_mutex; - }; + typedef ptys_handle_set_t handle_set_t; =20 /* Constructor */ fhandler_pty_slave (int); @@ -2450,7 +2472,7 @@ class fhandler_pty_slave: public fhandler_pty_common void cleanup_before_exit (); void get_duplicated_handle_set (handle_set_t *p); static void close_handle_set (handle_set_t *p); - void setup_for_non_cygwin_app (bool nopcon, PWCHAR envblock, + void setup_for_non_cygwin_app (bool nopcon, const WCHAR *envblock, bool stdin_is_ptys); static void cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp, bool stdin_is_ptys, diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 01225afe2..32ba5b377 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -211,29 +211,6 @@ handle (int fd, bool writing) return h; } =20 -static bool -is_console_app (WCHAR *filename) -{ - HANDLE h; - const int id_offset =3D 92; - h =3D CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, 0, NULL); - char buf[1024]; - DWORD n; - ReadFile (h, buf, sizeof (buf), &n, 0); - CloseHandle (h); - char *p =3D (char *) memmem (buf, n, "PE\0\0", 4); - if (p && p + id_offset < buf + n) - return p[id_offset] =3D=3D '\003'; /* 02: GUI, 03: console */ - else - { - wchar_t *e =3D wcsrchr (filename, L'.'); - if (e && (wcscasecmp (e, L".bat") =3D=3D 0 || wcscasecmp (e, L".cmd"= ) =3D=3D 0)) - return true; - } - return false; -} - int iscmd (const char *argv0, const char *what) { @@ -345,10 +322,7 @@ child_info_spawn::worker (const char *prog_arg, const = char *const *argv, STARTUPINFOW si =3D {}; int looped =3D 0; =20 - struct fhandler_pty_slave::handle_set_t ptys_handle_set =3D { 0, }; - bool ptys_need_cleanup =3D false; - struct fhandler_console::handle_set_t cons_handle_set =3D { 0, }; - bool cons_need_cleanup =3D false; + fhandler_termios::spawn_worker term_spawn_worker; =20 system_call_handle system_call (mode =3D=3D _P_SYSTEM); =20 @@ -598,29 +572,6 @@ child_info_spawn::worker (const char *prog_arg, const = char *const *argv, PROCESS_QUERY_LIMITED_INFORMATION)) sa =3D &sec_none_nih; =20 - fhandler_pty_slave *ptys_primary =3D NULL; - fhandler_console *cons_native =3D NULL; - for (int i =3D 0; i < 3; i ++) - { - const int chk_order[] =3D {1, 0, 2}; - int fd =3D chk_order[i]; - fhandler_base *fh =3D ::cygheap->fdtab[fd]; - if (fh && fh->get_major () =3D=3D DEV_PTYS_MAJOR && ptys_primary =3D=3D= NULL) - ptys_primary =3D (fhandler_pty_slave *) fh; - else if (fh && fh->get_major () =3D=3D DEV_CONS_MAJOR - && !iscygwin () && cons_native =3D=3D NULL) - cons_native =3D (fhandler_console *) fh; - } - - if (cons_native) - { - cons_native->setup_for_non_cygwin_app (); - /* Console handles will be already closed by close_all_files() - when cleaning up, therefore, duplicate them here. */ - cons_native->get_duplicated_handle_set (&cons_handle_set); - cons_need_cleanup =3D true; - } - int fileno_stdin =3D in__stdin < 0 ? 0 : in__stdin; int fileno_stdout =3D in__stdout < 0 ? 1 : in__stdout; int fileno_stderr =3D 2; @@ -631,14 +582,7 @@ child_info_spawn::worker (const char *prog_arg, const = char *const *argv, int fd; cygheap_fdenum cfd (false); while ((fd =3D cfd.next ()) >=3D 0) - if (cfd->get_major () =3D=3D DEV_PTYS_MAJOR) - { - fhandler_pty_slave *ptys =3D - (fhandler_pty_slave *)(fhandler_base *) cfd; - ptys->create_invisible_console (); - ptys->setup_locale (); - } - else if (cfd->get_dev () =3D=3D FH_PIPEW + if (cfd->get_dev () =3D=3D FH_PIPEW && (fd =3D=3D fileno_stdout || fd =3D=3D fileno_stderr)) { fhandler_pipe *pipe =3D (fhandler_pipe *)(fhandler_base *) cfd; @@ -666,24 +610,9 @@ child_info_spawn::worker (const char *prog_arg, const = char *const *argv, } } =20 - bool stdin_is_ptys =3D false; - tty *ptys_ttyp =3D NULL; - if (!iscygwin () && ptys_primary && is_console_app (runpath)) - { - bool nopcon =3D mode !=3D _P_OVERLAY && mode !=3D _P_WAIT; - HANDLE h_stdin =3D handle (fileno_stdin, false); - if (h_stdin =3D=3D ptys_primary->get_handle_nat ()) - stdin_is_ptys =3D true; - if (reset_sendsig) - myself->sendsig =3D myself->exec_sendsig; - ptys_primary->setup_for_non_cygwin_app (nopcon, envblock, - stdin_is_ptys); - if (reset_sendsig) - myself->sendsig =3D NULL; - ptys_primary->get_duplicated_handle_set (&ptys_handle_set); - ptys_ttyp =3D (tty *) ptys_primary->tc (); - ptys_need_cleanup =3D true; - } + bool no_pcon =3D mode !=3D _P_OVERLAY && mode !=3D _P_WAIT; + term_spawn_worker.setup (iscygwin (), handle (fileno_stdin, false), + runpath, no_pcon, reset_sendsig, envblock); =20 /* Set up needed handles for stdio */ si.dwFlags =3D STARTF_USESTDHANDLES; @@ -844,11 +773,6 @@ child_info_spawn::worker (const char *prog_arg, const = char *const *argv, /* Name the handle similarly to proc_subproc. */ ProtectHandle1 (pi.hProcess, childhProc); =20 - /* Do not touch these terminal instances after here. - They may be destroyed by close_all_files(). */ - ptys_primary =3D NULL; - cons_native =3D NULL; - if (mode =3D=3D _P_OVERLAY) { myself->dwProcessId =3D pi.dwProcessId; @@ -966,7 +890,7 @@ child_info_spawn::worker (const char *prog_arg, const c= har *const *argv, } if (sem) __posix_spawn_sem_release (sem, 0); - if (ptys_need_cleanup || cons_need_cleanup) + if (term_spawn_worker.need_cleanup ()) { LONG prev_sigExeced =3D sigExeced; while (WaitForSingleObject (pi.hProcess, 100) =3D=3D WAIT_TIMEOUT) @@ -975,18 +899,8 @@ child_info_spawn::worker (const char *prog_arg, const = char *const *argv, the signal sigExeced. Therefore, clear sigExeced here. */ prev_sigExeced =3D InterlockedCompareExchange (&sigExeced, 0, prev_sigExeced); - } - if (ptys_need_cleanup) - { - fhandler_pty_slave::cleanup_for_non_cygwin_app (&ptys_handle_set, - ptys_ttyp, - stdin_is_ptys); - fhandler_pty_slave::close_handle_set (&ptys_handle_set); - } - if (cons_need_cleanup) - { - fhandler_console::cleanup_for_non_cygwin_app (&cons_handle_set); - fhandler_console::close_handle_set (&cons_handle_set); + term_spawn_worker.cleanup (); + term_spawn_worker.close_handle_set (); } /* Make sure that ctrl_c_handler() is not on going. Calling init_console_handler(false) locks until returning from @@ -1000,12 +914,7 @@ child_info_spawn::worker (const char *prog_arg, const= char *const *argv, system_call.arm (); if (waitpid (cygpid, &res, 0) !=3D cygpid) res =3D -1; - if (ptys_need_cleanup) - fhandler_pty_slave::cleanup_for_non_cygwin_app (&ptys_handle_set, - ptys_ttyp, - stdin_is_ptys); - if (cons_need_cleanup) - fhandler_console::cleanup_for_non_cygwin_app (&cons_handle_set); + term_spawn_worker.cleanup (); break; case _P_DETACH: res =3D 0; /* Lost all memory of this child. */ @@ -1028,10 +937,7 @@ child_info_spawn::worker (const char *prog_arg, const= char *const *argv, res =3D -1; } __endtry - if (ptys_need_cleanup) - fhandler_pty_slave::close_handle_set (&ptys_handle_set); - if (cons_need_cleanup) - fhandler_console::close_handle_set (&cons_handle_set); + term_spawn_worker.close_handle_set (); this->cleanup (); if (envblock) free (envblock);