From 445a03527d9974a5c6dd6a460627babc5c9c794f Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 22 Jan 2015 17:43:45 -0600 Subject: [PATCH] Fix to make ^Z work for suspending processes when hush is the login shell. The issue is that GNO's login (and other BSD-derived versions) start up the login shell with SIGTSTP ignored. Hush was recording this configuration and propagating it to its child processes, causing ^Z not to work. The fix is to not do that (for login shells only). Also, set the system vector to run hush before running any of the startup scripts, in case something run in them uses it. --- shell/hush.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 4baa3aad8..89ebeb78b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -879,6 +879,13 @@ static struct globals G; } while (0) #endif +/* Flags set in hush_main */ +enum { + OPT_login = (1 << 0), + OPT_decode = (1 << 1) +}; +static unsigned flags; + /* Used by lineedit. */ struct lineedit_statics; struct lineedit_statics *lineedit_ptr_to_statics; @@ -8269,6 +8276,13 @@ static void install_sighandlers(unsigned long mask) */ if (sig == SIGCHLD) continue; + /* Some versions of login start the login shell with SIGTSTP + * ignored. If we mark it as ignored on entry, this will be + * propagated to hush's children and cause ^Z not to work, so + * don't do that. + */ + if (sig == SIGTSTP && (flags & OPT_login)) + continue; if (old_handler == SIG_IGN) { /* oops... restore back to IGN, and record this fact */ install_sighandler(sig, old_handler); @@ -8431,11 +8445,6 @@ static const char* const user_rcs[] = { int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int hush_main(int argc, char **argv) { - enum { - OPT_login = (1 << 0), - OPT_decode = (1 << 1) - }; - unsigned flags; int opt; unsigned builtin_argc; char **e; @@ -8735,6 +8744,14 @@ int hush_main(int argc, char **argv) G.root_ppid = getppid(); } +#ifdef __GNO__ + if (flags & OPT_login) { + /* If we're the login shell, set ourselves up to process + * system() and ORCA shell-style Execute calls. */ + setsystemvector(systemvec); + } +#endif + if (G.root_pid == getpid()) { source_startup_file(global_env); source_user_startup_files(user_envs); @@ -8742,11 +8759,6 @@ int hush_main(int argc, char **argv) /* If we are login shell... */ if (flags & OPT_login) { -#ifdef __GNO__ - /* If we're the login shell, set ourselves up to process - * system() and ORCA shell-style Execute calls. */ - setsystemvector(systemvec); -#endif debug_printf(("sourcing /etc/profile\n")); source_startup_file(global_profile); /* bash: after sourcing /etc/profile,