diff options
author | Ron Yorston <rmy@pobox.com> | 2023-02-13 10:01:35 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-02-13 10:01:35 +0000 |
commit | 4e5fb4341fddc2b99e815f27ac577d85a57994c2 (patch) | |
tree | c9e2eae6d2752d7e7f907ad39e3797b0fd5c3e02 /shell | |
parent | 0f2feac4b7e518e838b80d7b8ceac8f9699ae997 (diff) | |
parent | 93ae7464e6e460f25b73e4ffefd2d9a6499eae30 (diff) | |
download | busybox-w32-4e5fb4341fddc2b99e815f27ac577d85a57994c2.tar.gz busybox-w32-4e5fb4341fddc2b99e815f27ac577d85a57994c2.tar.bz2 busybox-w32-4e5fb4341fddc2b99e815f27ac577d85a57994c2.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 3 | ||||
-rw-r--r-- | shell/hush.c | 51 |
2 files changed, 37 insertions, 17 deletions
diff --git a/shell/ash.c b/shell/ash.c index 87190c453..94eb49d79 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -11769,7 +11769,8 @@ preadfd(void) | |||
11769 | again: | 11769 | again: |
11770 | /* For shell, LI_INTERRUPTIBLE is set: | 11770 | /* For shell, LI_INTERRUPTIBLE is set: |
11771 | * read_line_input will abort on either | 11771 | * read_line_input will abort on either |
11772 | * getting EINTR in poll(), or if it sees bb_got_signal != 0 | 11772 | * getting EINTR in poll() and bb_got_signal became != 0, |
11773 | * or if it sees bb_got_signal != 0 | ||
11773 | * (IOW: if signal arrives before poll() is reached). | 11774 | * (IOW: if signal arrives before poll() is reached). |
11774 | * Interactive testcases: | 11775 | * Interactive testcases: |
11775 | * (while kill -INT $$; do sleep 1; done) & | 11776 | * (while kill -INT $$; do sleep 1; done) & |
diff --git a/shell/hush.c b/shell/hush.c index d111f0cc5..e6be70078 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1829,7 +1829,13 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
1829 | * SIGQUIT: ignore | 1829 | * SIGQUIT: ignore |
1830 | * SIGTERM (interactive): ignore | 1830 | * SIGTERM (interactive): ignore |
1831 | * SIGHUP (interactive): | 1831 | * SIGHUP (interactive): |
1832 | * send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit | 1832 | * Send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit. |
1833 | * Kernel would do this for us ("orphaned process group" handling | ||
1834 | * according to POSIX) if we are a session leader and thus our death | ||
1835 | * frees the controlling tty, but to be bash-compatible, we also do it | ||
1836 | * for every interactive shell's death by SIGHUP. | ||
1837 | * (Also, we need to restore tty pgrp, otherwise e.g. Midnight Commander | ||
1838 | * backgrounds when hush started from it gets killed by SIGHUP). | ||
1833 | * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore | 1839 | * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore |
1834 | * Note that ^Z is handled not by trapping SIGTSTP, but by seeing | 1840 | * Note that ^Z is handled not by trapping SIGTSTP, but by seeing |
1835 | * that all pipe members are stopped. Try this in bash: | 1841 | * that all pipe members are stopped. Try this in bash: |
@@ -1946,7 +1952,12 @@ static void record_pending_signo(int sig) | |||
1946 | { | 1952 | { |
1947 | sigaddset(&G.pending_set, sig); | 1953 | sigaddset(&G.pending_set, sig); |
1948 | #if ENABLE_FEATURE_EDITING | 1954 | #if ENABLE_FEATURE_EDITING |
1949 | bb_got_signal = sig; /* for read_line_input: "we got a signal" */ | 1955 | if (sig != SIGCHLD |
1956 | || (G_traps && G_traps[SIGCHLD] && G_traps[SIGCHLD][0]) | ||
1957 | /* ^^^ if SIGCHLD, interrupt line reading only if it has a trap */ | ||
1958 | ) { | ||
1959 | bb_got_signal = sig; /* for read_line_input: "we got a signal" */ | ||
1960 | } | ||
1950 | #endif | 1961 | #endif |
1951 | #if ENABLE_HUSH_FAST | 1962 | #if ENABLE_HUSH_FAST |
1952 | if (sig == SIGCHLD) { | 1963 | if (sig == SIGCHLD) { |
@@ -2173,20 +2184,27 @@ static int check_and_run_traps(void) | |||
2173 | break; | 2184 | break; |
2174 | #if ENABLE_HUSH_JOB | 2185 | #if ENABLE_HUSH_JOB |
2175 | case SIGHUP: { | 2186 | case SIGHUP: { |
2176 | //TODO: why are we doing this? ash and dash don't do this, | 2187 | /* if (G_interactive_fd) - no need to check, the handler |
2177 | //they have no handler for SIGHUP at all, | 2188 | * is only installed if we *are* interactive */ |
2178 | //they rely on kernel to send SIGHUP+SIGCONT to orphaned process groups | 2189 | { |
2179 | struct pipe *job; | 2190 | /* bash compat: "Before exiting, an interactive |
2180 | debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig); | 2191 | * shell resends the SIGHUP to all jobs, running |
2181 | /* bash is observed to signal whole process groups, | 2192 | * or stopped. Stopped jobs are sent SIGCONT |
2182 | * not individual processes */ | 2193 | * to ensure that they receive the SIGHUP." |
2183 | for (job = G.job_list; job; job = job->next) { | 2194 | */ |
2184 | if (job->pgrp <= 0) | 2195 | struct pipe *job; |
2185 | continue; | 2196 | debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig); |
2186 | debug_printf_exec("HUPing pgrp %d\n", job->pgrp); | 2197 | /* bash is observed to signal whole process groups, |
2187 | if (kill(- job->pgrp, SIGHUP) == 0) | 2198 | * not individual processes */ |
2188 | kill(- job->pgrp, SIGCONT); | 2199 | for (job = G.job_list; job; job = job->next) { |
2200 | if (job->pgrp <= 0) | ||
2201 | continue; | ||
2202 | debug_printf_exec("HUPing pgrp %d\n", job->pgrp); | ||
2203 | if (kill(- job->pgrp, SIGHUP) == 0) | ||
2204 | kill(- job->pgrp, SIGCONT); | ||
2205 | } | ||
2189 | } | 2206 | } |
2207 | /* this restores tty pgrp, then kills us with SIGHUP */ | ||
2190 | sigexit(SIGHUP); | 2208 | sigexit(SIGHUP); |
2191 | } | 2209 | } |
2192 | #endif | 2210 | #endif |
@@ -2669,7 +2687,8 @@ static int get_user_input(struct in_str *i) | |||
2669 | } else { | 2687 | } else { |
2670 | /* For shell, LI_INTERRUPTIBLE is set: | 2688 | /* For shell, LI_INTERRUPTIBLE is set: |
2671 | * read_line_input will abort on either | 2689 | * read_line_input will abort on either |
2672 | * getting EINTR in poll(), or if it sees bb_got_signal != 0 | 2690 | * getting EINTR in poll() and bb_got_signal became != 0, |
2691 | * or if it sees bb_got_signal != 0 | ||
2673 | * (IOW: if signal arrives before poll() is reached). | 2692 | * (IOW: if signal arrives before poll() is reached). |
2674 | * Interactive testcases: | 2693 | * Interactive testcases: |
2675 | * (while kill -INT $$; do sleep 1; done) & | 2694 | * (while kill -INT $$; do sleep 1; done) & |