diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-12 15:19:31 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-12 15:19:31 +0100 |
| commit | e89a241b9ed76aed22bde93f58311db9c159cde2 (patch) | |
| tree | 703fcdf66e1ceb244fcb4b31b9cf5bb66a0c313f /shell | |
| parent | f3ec0fb1b4ae594c152dd626996f3abdc28b13be (diff) | |
| download | busybox-w32-e89a241b9ed76aed22bde93f58311db9c159cde2.tar.gz busybox-w32-e89a241b9ed76aed22bde93f58311db9c159cde2.tar.bz2 busybox-w32-e89a241b9ed76aed22bde93f58311db9c159cde2.zip | |
hush: fix subshell.tests failure on NOMMU
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 104 | ||||
| -rw-r--r-- | shell/hush_test/hush-trap/subshell.right | 15 | ||||
| -rwxr-xr-x | shell/hush_test/hush-trap/subshell.tests | 10 |
3 files changed, 88 insertions, 41 deletions
diff --git a/shell/hush.c b/shell/hush.c index 7d851ed97..8de8d3c2a 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -520,6 +520,7 @@ struct globals { | |||
| 520 | smalluint last_exitcode; | 520 | smalluint last_exitcode; |
| 521 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ | 521 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ |
| 522 | smalluint global_args_malloced; | 522 | smalluint global_args_malloced; |
| 523 | smalluint inherited_set_is_saved; | ||
| 523 | /* how many non-NULL argv's we have. NB: $# + 1 */ | 524 | /* how many non-NULL argv's we have. NB: $# + 1 */ |
| 524 | int global_argc; | 525 | int global_argc; |
| 525 | char **global_argv; | 526 | char **global_argv; |
| @@ -1050,7 +1051,8 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
| 1050 | * | 1051 | * |
| 1051 | * Trap handlers will execute even within trap handlers. (right?) | 1052 | * Trap handlers will execute even within trap handlers. (right?) |
| 1052 | * | 1053 | * |
| 1053 | * User trap handlers are forgotten when subshell ("(cmd)") is entered. | 1054 | * User trap handlers are forgotten when subshell ("(cmd)") is entered, |
| 1055 | * except for handlers set to '' (empty string). | ||
| 1054 | * | 1056 | * |
| 1055 | * If job control is off, backgrounded commands ("cmd &") | 1057 | * If job control is off, backgrounded commands ("cmd &") |
| 1056 | * have SIGINT, SIGQUIT set to SIG_IGN. | 1058 | * have SIGINT, SIGQUIT set to SIG_IGN. |
| @@ -1106,7 +1108,7 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
| 1106 | * after [v]fork, if we plan to be a shell: | 1108 | * after [v]fork, if we plan to be a shell: |
| 1107 | * unblock signals with special interactive handling | 1109 | * unblock signals with special interactive handling |
| 1108 | * (child shell is not interactive), | 1110 | * (child shell is not interactive), |
| 1109 | * unset all traps (note: regardless of child shell's type - {}, (), etc) | 1111 | * unset all traps except '' (note: regardless of child shell's type - {}, (), etc) |
| 1110 | * after [v]fork, if we plan to exec: | 1112 | * after [v]fork, if we plan to exec: |
| 1111 | * POSIX says fork clears pending signal mask in child - no need to clear it. | 1113 | * POSIX says fork clears pending signal mask in child - no need to clear it. |
| 1112 | * Restore blocked signal set to one inherited by shell just prior to exec. | 1114 | * Restore blocked signal set to one inherited by shell just prior to exec. |
| @@ -1118,7 +1120,7 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
| 1118 | * Note 2 (compat): | 1120 | * Note 2 (compat): |
| 1119 | * Standard says "When a subshell is entered, traps that are not being ignored | 1121 | * Standard says "When a subshell is entered, traps that are not being ignored |
| 1120 | * are set to the default actions". bash interprets it so that traps which | 1122 | * are set to the default actions". bash interprets it so that traps which |
| 1121 | * are set to "" (ignore) are NOT reset to defaults. We do the same. | 1123 | * are set to '' (ignore) are NOT reset to defaults. We do the same. |
| 1122 | */ | 1124 | */ |
| 1123 | enum { | 1125 | enum { |
| 1124 | SPECIAL_INTERACTIVE_SIGS = 0 | 1126 | SPECIAL_INTERACTIVE_SIGS = 0 |
| @@ -2925,6 +2927,7 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
| 2925 | # endif | 2927 | # endif |
| 2926 | char **argv, **pp; | 2928 | char **argv, **pp; |
| 2927 | unsigned cnt; | 2929 | unsigned cnt; |
| 2930 | unsigned long long empty_trap_mask; | ||
| 2928 | 2931 | ||
| 2929 | if (!g_argv0) { /* heredoc */ | 2932 | if (!g_argv0) { /* heredoc */ |
| 2930 | argv = heredoc_argv; | 2933 | argv = heredoc_argv; |
| @@ -2941,12 +2944,22 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
| 2941 | if (pp) while (*pp++) | 2944 | if (pp) while (*pp++) |
| 2942 | cnt++; | 2945 | cnt++; |
| 2943 | 2946 | ||
| 2944 | sprintf(param_buf, "-$%x:%x:%x:%x:%x" IF_HUSH_LOOPS(":%x") | 2947 | empty_trap_mask = 0; |
| 2948 | if (G.traps) { | ||
| 2949 | int sig; | ||
| 2950 | for (sig = 1; sig < NSIG; sig++) { | ||
| 2951 | if (G.traps[sig] && !G.traps[sig][0]) | ||
| 2952 | empty_trap_mask |= 1LL << sig; | ||
| 2953 | } | ||
| 2954 | } | ||
| 2955 | |||
| 2956 | sprintf(param_buf, "-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x") | ||
| 2945 | , (unsigned) G.root_pid | 2957 | , (unsigned) G.root_pid |
| 2946 | , (unsigned) G.root_ppid | 2958 | , (unsigned) G.root_ppid |
| 2947 | , (unsigned) G.last_bg_pid | 2959 | , (unsigned) G.last_bg_pid |
| 2948 | , (unsigned) G.last_exitcode | 2960 | , (unsigned) G.last_exitcode |
| 2949 | , cnt | 2961 | , cnt |
| 2962 | , empty_trap_mask | ||
| 2950 | IF_HUSH_LOOPS(, G.depth_of_loop) | 2963 | IF_HUSH_LOOPS(, G.depth_of_loop) |
| 2951 | ); | 2964 | ); |
| 2952 | /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<depth> <vars...> <funcs...> | 2965 | /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<depth> <vars...> <funcs...> |
| @@ -3002,7 +3015,9 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
| 3002 | * _inside_ group (just before echo 1), it works. | 3015 | * _inside_ group (just before echo 1), it works. |
| 3003 | * | 3016 | * |
| 3004 | * I conclude it means we don't need to pass active traps here. | 3017 | * I conclude it means we don't need to pass active traps here. |
| 3005 | * exec syscall below resets them to SIG_DFL for us. | 3018 | * Even if we would use signal handlers instead of signal masking |
| 3019 | * in order to implement trap handling, | ||
| 3020 | * exec syscall below resets signals to SIG_DFL for us. | ||
| 3006 | */ | 3021 | */ |
| 3007 | *pp++ = (char *) "-c"; | 3022 | *pp++ = (char *) "-c"; |
| 3008 | *pp++ = (char *) s; | 3023 | *pp++ = (char *) s; |
| @@ -5447,7 +5462,7 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p) | |||
| 5447 | pid_t pid; | 5462 | pid_t pid; |
| 5448 | int channel[2]; | 5463 | int channel[2]; |
| 5449 | # if !BB_MMU | 5464 | # if !BB_MMU |
| 5450 | char **to_free; | 5465 | char **to_free = NULL; |
| 5451 | # endif | 5466 | # endif |
| 5452 | 5467 | ||
| 5453 | xpipe(channel); | 5468 | xpipe(channel); |
| @@ -6677,10 +6692,17 @@ static void parse_and_run_file(FILE *f) | |||
| 6677 | } | 6692 | } |
| 6678 | 6693 | ||
| 6679 | /* Called a few times only (or even once if "sh -c") */ | 6694 | /* Called a few times only (or even once if "sh -c") */ |
| 6680 | static void block_signals(int second_time) | 6695 | static void init_sigmasks(void) |
| 6681 | { | 6696 | { |
| 6682 | unsigned sig; | 6697 | unsigned sig; |
| 6683 | unsigned mask; | 6698 | unsigned mask; |
| 6699 | sigset_t old_blocked_set; | ||
| 6700 | |||
| 6701 | if (!G.inherited_set_is_saved) { | ||
| 6702 | sigprocmask(SIG_SETMASK, NULL, &G.blocked_set); | ||
| 6703 | G.inherited_set = G.blocked_set; | ||
| 6704 | } | ||
| 6705 | old_blocked_set = G.blocked_set; | ||
| 6684 | 6706 | ||
| 6685 | mask = (1 << SIGQUIT); | 6707 | mask = (1 << SIGQUIT); |
| 6686 | if (G_interactive_fd) { | 6708 | if (G_interactive_fd) { |
| @@ -6690,8 +6712,6 @@ static void block_signals(int second_time) | |||
| 6690 | } | 6712 | } |
| 6691 | G.non_DFL_mask = mask; | 6713 | G.non_DFL_mask = mask; |
| 6692 | 6714 | ||
| 6693 | if (!second_time) | ||
| 6694 | sigprocmask(SIG_SETMASK, NULL, &G.blocked_set); | ||
| 6695 | sig = 0; | 6715 | sig = 0; |
| 6696 | while (mask) { | 6716 | while (mask) { |
| 6697 | if (mask & 1) | 6717 | if (mask & 1) |
| @@ -6701,18 +6721,21 @@ static void block_signals(int second_time) | |||
| 6701 | } | 6721 | } |
| 6702 | sigdelset(&G.blocked_set, SIGCHLD); | 6722 | sigdelset(&G.blocked_set, SIGCHLD); |
| 6703 | 6723 | ||
| 6704 | sigprocmask(SIG_SETMASK, &G.blocked_set, | 6724 | if (memcmp(&old_blocked_set, &G.blocked_set, sizeof(old_blocked_set)) != 0) |
| 6705 | second_time ? NULL : &G.inherited_set); | 6725 | sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); |
| 6726 | |||
| 6706 | /* POSIX allows shell to re-enable SIGCHLD | 6727 | /* POSIX allows shell to re-enable SIGCHLD |
| 6707 | * even if it was SIG_IGN on entry */ | 6728 | * even if it was SIG_IGN on entry */ |
| 6708 | #if ENABLE_HUSH_FAST | 6729 | #if ENABLE_HUSH_FAST |
| 6709 | G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */ | 6730 | G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */ |
| 6710 | if (!second_time) | 6731 | if (!G.inherited_set_is_saved) |
| 6711 | signal(SIGCHLD, SIGCHLD_handler); | 6732 | signal(SIGCHLD, SIGCHLD_handler); |
| 6712 | #else | 6733 | #else |
| 6713 | if (!second_time) | 6734 | if (!G.inherited_set_is_saved) |
| 6714 | signal(SIGCHLD, SIG_DFL); | 6735 | signal(SIGCHLD, SIG_DFL); |
| 6715 | #endif | 6736 | #endif |
| 6737 | |||
| 6738 | G.inherited_set_is_saved = 1; | ||
| 6716 | } | 6739 | } |
| 6717 | 6740 | ||
| 6718 | #if ENABLE_HUSH_JOB | 6741 | #if ENABLE_HUSH_JOB |
| @@ -6774,7 +6797,6 @@ int hush_main(int argc, char **argv) | |||
| 6774 | .flg_export = 1, | 6797 | .flg_export = 1, |
| 6775 | .flg_read_only = 1, | 6798 | .flg_read_only = 1, |
| 6776 | }; | 6799 | }; |
| 6777 | int signal_mask_is_inited = 0; | ||
| 6778 | int opt; | 6800 | int opt; |
| 6779 | unsigned builtin_argc; | 6801 | unsigned builtin_argc; |
| 6780 | char **e; | 6802 | char **e; |
| @@ -6865,10 +6887,9 @@ int hush_main(int argc, char **argv) | |||
| 6865 | } | 6887 | } |
| 6866 | 6888 | ||
| 6867 | /* Shell is non-interactive at first. We need to call | 6889 | /* Shell is non-interactive at first. We need to call |
| 6868 | * block_signals(0) if we are going to execute "sh <script>", | 6890 | * init_sigmasks() if we are going to execute "sh <script>", |
| 6869 | * "sh -c <cmds>" or login shell's /etc/profile and friends. | 6891 | * "sh -c <cmds>" or login shell's /etc/profile and friends. |
| 6870 | * If we later decide that we are interactive, we run block_signals(0) | 6892 | * If we later decide that we are interactive, we run init_sigmasks() |
| 6871 | * (or re-run block_signals(1) if we ran block_signals(0) before) | ||
| 6872 | * in order to intercept (more) signals. | 6893 | * in order to intercept (more) signals. |
| 6873 | */ | 6894 | */ |
| 6874 | 6895 | ||
| @@ -6908,7 +6929,7 @@ int hush_main(int argc, char **argv) | |||
| 6908 | /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ | 6929 | /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ |
| 6909 | const struct built_in_command *x; | 6930 | const struct built_in_command *x; |
| 6910 | 6931 | ||
| 6911 | block_signals(0); /* 0: called 1st time */ | 6932 | init_sigmasks(); |
| 6912 | x = find_builtin(optarg); | 6933 | x = find_builtin(optarg); |
| 6913 | if (x) { /* paranoia */ | 6934 | if (x) { /* paranoia */ |
| 6914 | G.global_argc -= builtin_argc; /* skip [BARGV...] "" */ | 6935 | G.global_argc -= builtin_argc; /* skip [BARGV...] "" */ |
| @@ -6924,7 +6945,7 @@ int hush_main(int argc, char **argv) | |||
| 6924 | G.global_argv[0] = argv[0]; | 6945 | G.global_argv[0] = argv[0]; |
| 6925 | G.global_argc--; | 6946 | G.global_argc--; |
| 6926 | } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ | 6947 | } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ |
| 6927 | block_signals(0); /* 0: called 1st time */ | 6948 | init_sigmasks(); |
| 6928 | parse_and_run_string(optarg); | 6949 | parse_and_run_string(optarg); |
| 6929 | goto final_return; | 6950 | goto final_return; |
| 6930 | case 'i': | 6951 | case 'i': |
| @@ -6940,7 +6961,9 @@ int hush_main(int argc, char **argv) | |||
| 6940 | case '<': /* "big heredoc" support */ | 6961 | case '<': /* "big heredoc" support */ |
| 6941 | full_write(STDOUT_FILENO, optarg, strlen(optarg)); | 6962 | full_write(STDOUT_FILENO, optarg, strlen(optarg)); |
| 6942 | _exit(0); | 6963 | _exit(0); |
| 6943 | case '$': | 6964 | case '$': { |
| 6965 | unsigned long long empty_trap_mask; | ||
| 6966 | |||
| 6944 | G.root_pid = bb_strtou(optarg, &optarg, 16); | 6967 | G.root_pid = bb_strtou(optarg, &optarg, 16); |
| 6945 | optarg++; | 6968 | optarg++; |
| 6946 | G.root_ppid = bb_strtou(optarg, &optarg, 16); | 6969 | G.root_ppid = bb_strtou(optarg, &optarg, 16); |
| @@ -6950,11 +6973,26 @@ int hush_main(int argc, char **argv) | |||
| 6950 | G.last_exitcode = bb_strtou(optarg, &optarg, 16); | 6973 | G.last_exitcode = bb_strtou(optarg, &optarg, 16); |
| 6951 | optarg++; | 6974 | optarg++; |
| 6952 | builtin_argc = bb_strtou(optarg, &optarg, 16); | 6975 | builtin_argc = bb_strtou(optarg, &optarg, 16); |
| 6976 | optarg++; | ||
| 6977 | empty_trap_mask = bb_strtoull(optarg, &optarg, 16); | ||
| 6978 | if (empty_trap_mask != 0) { | ||
| 6979 | int sig; | ||
| 6980 | init_sigmasks(); | ||
| 6981 | G.traps = xzalloc(sizeof(G.traps[0]) * NSIG); | ||
| 6982 | for (sig = 1; sig < NSIG; sig++) { | ||
| 6983 | if (empty_trap_mask & (1LL << sig)) { | ||
| 6984 | G.traps[sig] = xzalloc(1); /* == xstrdup(""); */ | ||
| 6985 | sigaddset(&G.blocked_set, sig); | ||
| 6986 | } | ||
| 6987 | } | ||
| 6988 | sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); | ||
| 6989 | } | ||
| 6953 | # if ENABLE_HUSH_LOOPS | 6990 | # if ENABLE_HUSH_LOOPS |
| 6954 | optarg++; | 6991 | optarg++; |
| 6955 | G.depth_of_loop = bb_strtou(optarg, &optarg, 16); | 6992 | G.depth_of_loop = bb_strtou(optarg, &optarg, 16); |
| 6956 | # endif | 6993 | # endif |
| 6957 | break; | 6994 | break; |
| 6995 | } | ||
| 6958 | case 'R': | 6996 | case 'R': |
| 6959 | case 'V': | 6997 | case 'V': |
| 6960 | set_local_var(xstrdup(optarg), /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ opt == 'R'); | 6998 | set_local_var(xstrdup(optarg), /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ opt == 'R'); |
| @@ -6997,8 +7035,7 @@ int hush_main(int argc, char **argv) | |||
| 6997 | input = fopen_for_read("/etc/profile"); | 7035 | input = fopen_for_read("/etc/profile"); |
| 6998 | if (input != NULL) { | 7036 | if (input != NULL) { |
| 6999 | close_on_exec_on(fileno(input)); | 7037 | close_on_exec_on(fileno(input)); |
| 7000 | block_signals(0); /* 0: called 1st time */ | 7038 | init_sigmasks(); |
| 7001 | signal_mask_is_inited = 1; | ||
| 7002 | parse_and_run_file(input); | 7039 | parse_and_run_file(input); |
| 7003 | fclose(input); | 7040 | fclose(input); |
| 7004 | } | 7041 | } |
| @@ -7023,8 +7060,7 @@ int hush_main(int argc, char **argv) | |||
| 7023 | G.global_argc = argc - optind; | 7060 | G.global_argc = argc - optind; |
| 7024 | input = xfopen_for_read(argv[optind]); | 7061 | input = xfopen_for_read(argv[optind]); |
| 7025 | close_on_exec_on(fileno(input)); | 7062 | close_on_exec_on(fileno(input)); |
| 7026 | if (!signal_mask_is_inited) | 7063 | init_sigmasks(); |
| 7027 | block_signals(0); /* 0: called 1st time */ | ||
| 7028 | parse_and_run_file(input); | 7064 | parse_and_run_file(input); |
| 7029 | #if ENABLE_FEATURE_CLEAN_UP | 7065 | #if ENABLE_FEATURE_CLEAN_UP |
| 7030 | fclose(input); | 7066 | fclose(input); |
| @@ -7033,7 +7069,7 @@ int hush_main(int argc, char **argv) | |||
| 7033 | } | 7069 | } |
| 7034 | 7070 | ||
| 7035 | /* Up to here, shell was non-interactive. Now it may become one. | 7071 | /* Up to here, shell was non-interactive. Now it may become one. |
| 7036 | * NB: don't forget to (re)run block_signals(0/1) as needed. | 7072 | * NB: don't forget to (re)run init_sigmasks() as needed. |
| 7037 | */ | 7073 | */ |
| 7038 | 7074 | ||
| 7039 | /* A shell is interactive if the '-i' flag was given, | 7075 | /* A shell is interactive if the '-i' flag was given, |
| @@ -7086,7 +7122,7 @@ int hush_main(int argc, char **argv) | |||
| 7086 | } | 7122 | } |
| 7087 | 7123 | ||
| 7088 | /* Block some signals */ | 7124 | /* Block some signals */ |
| 7089 | block_signals(signal_mask_is_inited); | 7125 | init_sigmasks(); |
| 7090 | 7126 | ||
| 7091 | if (G_saved_tty_pgrp) { | 7127 | if (G_saved_tty_pgrp) { |
| 7092 | /* Set other signals to restore saved_tty_pgrp */ | 7128 | /* Set other signals to restore saved_tty_pgrp */ |
| @@ -7100,9 +7136,9 @@ int hush_main(int argc, char **argv) | |||
| 7100 | /* -1 is special - makes xfuncs longjmp, not exit | 7136 | /* -1 is special - makes xfuncs longjmp, not exit |
| 7101 | * (we reset die_sleep = 0 whereever we [v]fork) */ | 7137 | * (we reset die_sleep = 0 whereever we [v]fork) */ |
| 7102 | enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ | 7138 | enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ |
| 7103 | } else if (!signal_mask_is_inited) { | 7139 | } else { |
| 7104 | block_signals(0); /* 0: called 1st time */ | 7140 | init_sigmasks(); |
| 7105 | } /* else: block_signals(0) was done before */ | 7141 | } |
| 7106 | #elif ENABLE_HUSH_INTERACTIVE | 7142 | #elif ENABLE_HUSH_INTERACTIVE |
| 7107 | /* No job control compiled in, only prompt/line editing */ | 7143 | /* No job control compiled in, only prompt/line editing */ |
| 7108 | if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { | 7144 | if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { |
| @@ -7117,15 +7153,11 @@ int hush_main(int argc, char **argv) | |||
| 7117 | } | 7153 | } |
| 7118 | if (G_interactive_fd) { | 7154 | if (G_interactive_fd) { |
| 7119 | close_on_exec_on(G_interactive_fd); | 7155 | close_on_exec_on(G_interactive_fd); |
| 7120 | block_signals(signal_mask_is_inited); | ||
| 7121 | } else if (!signal_mask_is_inited) { | ||
| 7122 | block_signals(0); | ||
| 7123 | } | 7156 | } |
| 7157 | init_sigmasks(); | ||
| 7124 | #else | 7158 | #else |
| 7125 | /* We have interactiveness code disabled */ | 7159 | /* We have interactiveness code disabled */ |
| 7126 | if (!signal_mask_is_inited) { | 7160 | init_sigmasks(); |
| 7127 | block_signals(0); | ||
| 7128 | } | ||
| 7129 | #endif | 7161 | #endif |
| 7130 | /* bash: | 7162 | /* bash: |
| 7131 | * if interactive but not a login shell, sources ~/.bashrc | 7163 | * if interactive but not a login shell, sources ~/.bashrc |
| @@ -7471,7 +7503,7 @@ static int FAST_FUNC builtin_trap(char **argv) | |||
| 7471 | free(G.traps[sig]); | 7503 | free(G.traps[sig]); |
| 7472 | G.traps[sig] = xstrdup(new_cmd); | 7504 | G.traps[sig] = xstrdup(new_cmd); |
| 7473 | 7505 | ||
| 7474 | debug_printf("trap: setting SIG%s (%i) to '%s'", | 7506 | debug_printf("trap: setting SIG%s (%i) to '%s'\n", |
| 7475 | get_signame(sig), sig, G.traps[sig]); | 7507 | get_signame(sig), sig, G.traps[sig]); |
| 7476 | 7508 | ||
| 7477 | /* There is no signal for 0 (EXIT) */ | 7509 | /* There is no signal for 0 (EXIT) */ |
diff --git a/shell/hush_test/hush-trap/subshell.right b/shell/hush_test/hush-trap/subshell.right index 0d20ed4e9..f865b932b 100644 --- a/shell/hush_test/hush-trap/subshell.right +++ b/shell/hush_test/hush-trap/subshell.right | |||
| @@ -1,6 +1,21 @@ | |||
| 1 | trap -- '' HUP | ||
| 2 | trap -- '' QUIT | ||
| 3 | trap -- '' SYS | ||
| 1 | Ok | 4 | Ok |
| 5 | trap -- '' HUP | ||
| 6 | trap -- '' QUIT | ||
| 7 | trap -- '' SYS | ||
| 2 | Ok | 8 | Ok |
| 9 | trap -- '' HUP | ||
| 10 | trap -- '' QUIT | ||
| 11 | trap -- '' SYS | ||
| 3 | Ok | 12 | Ok |
| 13 | trap -- '' HUP | ||
| 14 | trap -- '' QUIT | ||
| 15 | trap -- '' SYS | ||
| 4 | Ok | 16 | Ok |
| 17 | trap -- '' HUP | ||
| 18 | trap -- '' QUIT | ||
| 19 | trap -- '' SYS | ||
| 5 | TERM | 20 | TERM |
| 6 | Done | 21 | Done |
diff --git a/shell/hush_test/hush-trap/subshell.tests b/shell/hush_test/hush-trap/subshell.tests index 4564c2ee2..045294bf4 100755 --- a/shell/hush_test/hush-trap/subshell.tests +++ b/shell/hush_test/hush-trap/subshell.tests | |||
| @@ -12,9 +12,9 @@ trap 'bad: caught WINCH' WINCH | |||
| 12 | trap 'bad: caught TERM' TERM | 12 | trap 'bad: caught TERM' TERM |
| 13 | 13 | ||
| 14 | # using bash, because we don't have $PPID (yet) | 14 | # using bash, because we don't have $PPID (yet) |
| 15 | (bash -c 'kill -HUP $PPID'; echo Ok) | 15 | (trap; bash -c 'kill -HUP $PPID'; echo Ok) |
| 16 | (bash -c 'kill -QUIT $PPID'; echo Ok) | 16 | (trap; bash -c 'kill -QUIT $PPID'; echo Ok) |
| 17 | (bash -c 'kill -SYS $PPID'; echo Ok) | 17 | (trap; bash -c 'kill -SYS $PPID'; echo Ok) |
| 18 | (bash -c 'kill -WINCH $PPID'; echo Ok) | 18 | (trap; bash -c 'kill -WINCH $PPID'; echo Ok) |
| 19 | (bash -c 'kill -TERM $PPID'; echo Bad: TERM is not reset) | 19 | (trap; bash -c 'kill -TERM $PPID'; echo Bad: TERM is not reset) |
| 20 | echo Done | 20 | echo Done |
