diff options
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/shell/hush.c b/shell/hush.c index 4b08232a4..19b97e2a5 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -903,6 +903,7 @@ struct globals { | |||
903 | # define G_x_mode 0 | 903 | # define G_x_mode 0 |
904 | #endif | 904 | #endif |
905 | char opt_s; | 905 | char opt_s; |
906 | char opt_c; | ||
906 | #if ENABLE_HUSH_INTERACTIVE | 907 | #if ENABLE_HUSH_INTERACTIVE |
907 | smallint promptmode; /* 0: PS1, 1: PS2 */ | 908 | smallint promptmode; /* 0: PS1, 1: PS2 */ |
908 | #endif | 909 | #endif |
@@ -1009,7 +1010,7 @@ struct globals { | |||
1009 | int debug_indent; | 1010 | int debug_indent; |
1010 | #endif | 1011 | #endif |
1011 | struct sigaction sa; | 1012 | struct sigaction sa; |
1012 | char optstring_buf[sizeof("eixs")]; | 1013 | char optstring_buf[sizeof("eixcs")]; |
1013 | #if BASH_EPOCH_VARS | 1014 | #if BASH_EPOCH_VARS |
1014 | char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; | 1015 | char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; |
1015 | #endif | 1016 | #endif |
@@ -1397,7 +1398,7 @@ static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg) | |||
1397 | if (msg) | 1398 | if (msg) |
1398 | bb_error_msg("syntax error: %s", msg); | 1399 | bb_error_msg("syntax error: %s", msg); |
1399 | else | 1400 | else |
1400 | bb_error_msg("syntax error"); | 1401 | bb_simple_error_msg("syntax error"); |
1401 | die_if_script(); | 1402 | die_if_script(); |
1402 | } | 1403 | } |
1403 | 1404 | ||
@@ -1636,7 +1637,7 @@ static int refill_HFILE_and_getc(HFILE *fp) | |||
1636 | fp->cur = fp->buf; | 1637 | fp->cur = fp->buf; |
1637 | n = safe_read(fp->fd, fp->buf, sizeof(fp->buf)); | 1638 | n = safe_read(fp->fd, fp->buf, sizeof(fp->buf)); |
1638 | if (n < 0) { | 1639 | if (n < 0) { |
1639 | bb_perror_msg("read error"); | 1640 | bb_simple_perror_msg("read error"); |
1640 | n = 0; | 1641 | n = 0; |
1641 | } | 1642 | } |
1642 | fp->end = fp->buf + n; | 1643 | fp->end = fp->buf + n; |
@@ -2281,7 +2282,7 @@ static int set_local_var(char *str, unsigned flags) | |||
2281 | 2282 | ||
2282 | eq_sign = strchr(str, '='); | 2283 | eq_sign = strchr(str, '='); |
2283 | if (HUSH_DEBUG && !eq_sign) | 2284 | if (HUSH_DEBUG && !eq_sign) |
2284 | bb_error_msg_and_die("BUG in setvar"); | 2285 | bb_simple_error_msg_and_die("BUG in setvar"); |
2285 | 2286 | ||
2286 | name_len = eq_sign - str + 1; /* including '=' */ | 2287 | name_len = eq_sign - str + 1; /* including '=' */ |
2287 | cur_pp = &G.top_var; | 2288 | cur_pp = &G.top_var; |
@@ -2504,7 +2505,7 @@ static void set_vars_and_save_old(char **strings) | |||
2504 | 2505 | ||
2505 | eq = strchr(*s, '='); | 2506 | eq = strchr(*s, '='); |
2506 | if (HUSH_DEBUG && !eq) | 2507 | if (HUSH_DEBUG && !eq) |
2507 | bb_error_msg_and_die("BUG in varexp4"); | 2508 | bb_simple_error_msg_and_die("BUG in varexp4"); |
2508 | var_pp = get_ptr_to_local_var(*s, eq - *s); | 2509 | var_pp = get_ptr_to_local_var(*s, eq - *s); |
2509 | if (var_pp) { | 2510 | if (var_pp) { |
2510 | var_p = *var_pp; | 2511 | var_p = *var_pp; |
@@ -4245,7 +4246,7 @@ static int parse_redir_right_fd(o_string *as_string, struct in_str *input) | |||
4245 | 4246 | ||
4246 | //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2) | 4247 | //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2) |
4247 | 4248 | ||
4248 | bb_error_msg("ambiguous redirect"); | 4249 | bb_simple_error_msg("ambiguous redirect"); |
4249 | return REDIRFD_SYNTAX_ERR; | 4250 | return REDIRFD_SYNTAX_ERR; |
4250 | } | 4251 | } |
4251 | 4252 | ||
@@ -6414,9 +6415,10 @@ static NOINLINE int expand_one_var(o_string *output, int n, | |||
6414 | * commands read but are not executed, | 6415 | * commands read but are not executed, |
6415 | * so $- can not execute too, 'n' is never seen in $-. | 6416 | * so $- can not execute too, 'n' is never seen in $-. |
6416 | */ | 6417 | */ |
6418 | if (G.opt_c) | ||
6419 | *cp++ = 'c'; | ||
6417 | if (G.opt_s) | 6420 | if (G.opt_s) |
6418 | *cp++ = 's'; | 6421 | *cp++ = 's'; |
6419 | //TODO: show 'c' if executed via "hush -c 'CMDS'" (bash only, not ash) | ||
6420 | *cp = '\0'; | 6422 | *cp = '\0'; |
6421 | break; | 6423 | break; |
6422 | } | 6424 | } |
@@ -6954,7 +6956,7 @@ static char *expand_string_to_string(const char *str, int EXP_flags, int do_unba | |||
6954 | } else { | 6956 | } else { |
6955 | if (HUSH_DEBUG) | 6957 | if (HUSH_DEBUG) |
6956 | if (list[1]) | 6958 | if (list[1]) |
6957 | bb_error_msg_and_die("BUG in varexp2"); | 6959 | bb_simple_error_msg_and_die("BUG in varexp2"); |
6958 | /* actually, just move string 2*sizeof(char*) bytes back */ | 6960 | /* actually, just move string 2*sizeof(char*) bytes back */ |
6959 | overlapping_strcpy((char*)list, list[0]); | 6961 | overlapping_strcpy((char*)list, list[0]); |
6960 | if (do_unbackslash) | 6962 | if (do_unbackslash) |
@@ -7215,7 +7217,7 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
7215 | if (argv[0][0] == '/') | 7217 | if (argv[0][0] == '/') |
7216 | execve(argv[0], argv, pp); | 7218 | execve(argv[0], argv, pp); |
7217 | xfunc_error_retval = 127; | 7219 | xfunc_error_retval = 127; |
7218 | bb_error_msg_and_die("can't re-execute the shell"); | 7220 | bb_simple_error_msg_and_die("can't re-execute the shell"); |
7219 | } | 7221 | } |
7220 | #endif /* !BB_MMU */ | 7222 | #endif /* !BB_MMU */ |
7221 | 7223 | ||
@@ -7917,7 +7919,7 @@ static void leave_var_nest_level(void) | |||
7917 | G.var_nest_level--; | 7919 | G.var_nest_level--; |
7918 | debug_printf_env("var_nest_level-- %u\n", G.var_nest_level); | 7920 | debug_printf_env("var_nest_level-- %u\n", G.var_nest_level); |
7919 | if (HUSH_DEBUG && (int)G.var_nest_level < 0) | 7921 | if (HUSH_DEBUG && (int)G.var_nest_level < 0) |
7920 | bb_error_msg_and_die("BUG: nesting underflow"); | 7922 | bb_simple_error_msg_and_die("BUG: nesting underflow"); |
7921 | 7923 | ||
7922 | remove_nested_vars(); | 7924 | remove_nested_vars(); |
7923 | } | 7925 | } |
@@ -8774,7 +8776,7 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid) | |||
8774 | childpid = waitpid(-1, &status, attributes); | 8776 | childpid = waitpid(-1, &status, attributes); |
8775 | if (childpid <= 0) { | 8777 | if (childpid <= 0) { |
8776 | if (childpid && errno != ECHILD) | 8778 | if (childpid && errno != ECHILD) |
8777 | bb_perror_msg("waitpid"); | 8779 | bb_simple_perror_msg("waitpid"); |
8778 | #if ENABLE_HUSH_FAST | 8780 | #if ENABLE_HUSH_FAST |
8779 | else { /* Until next SIGCHLD, waitpid's are useless */ | 8781 | else { /* Until next SIGCHLD, waitpid's are useless */ |
8780 | G.we_have_children = (childpid == 0); | 8782 | G.we_have_children = (childpid == 0); |
@@ -9306,7 +9308,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
9306 | argv_expanded = NULL; | 9308 | argv_expanded = NULL; |
9307 | if (command->pid < 0) { /* [v]fork failed */ | 9309 | if (command->pid < 0) { /* [v]fork failed */ |
9308 | /* Clearly indicate, was it fork or vfork */ | 9310 | /* Clearly indicate, was it fork or vfork */ |
9309 | bb_perror_msg(BB_MMU ? "vfork"+1 : "vfork"); | 9311 | bb_simple_perror_msg(BB_MMU ? "vfork"+1 : "vfork"); |
9310 | } else { | 9312 | } else { |
9311 | pi->alive_cmds++; | 9313 | pi->alive_cmds++; |
9312 | #if ENABLE_HUSH_JOB | 9314 | #if ENABLE_HUSH_JOB |
@@ -9859,7 +9861,6 @@ int hush_main(int argc, char **argv) | |||
9859 | { | 9861 | { |
9860 | enum { | 9862 | enum { |
9861 | OPT_login = (1 << 0), | 9863 | OPT_login = (1 << 0), |
9862 | OPT_s = (1 << 1), | ||
9863 | }; | 9864 | }; |
9864 | unsigned flags; | 9865 | unsigned flags; |
9865 | unsigned builtin_argc; | 9866 | unsigned builtin_argc; |
@@ -10029,6 +10030,7 @@ int hush_main(int argc, char **argv) | |||
10029 | } | 10030 | } |
10030 | goto final_return; | 10031 | goto final_return; |
10031 | } | 10032 | } |
10033 | G.opt_c = 1; | ||
10032 | if (!G.global_argv[0]) { | 10034 | if (!G.global_argv[0]) { |
10033 | /* -c 'script' (no params): prevent empty $0 */ | 10035 | /* -c 'script' (no params): prevent empty $0 */ |
10034 | G.global_argv--; /* points to argv[i] of 'script' */ | 10036 | G.global_argv--; /* points to argv[i] of 'script' */ |
@@ -10044,7 +10046,7 @@ int hush_main(int argc, char **argv) | |||
10044 | /* G_interactive_fd++; */ | 10046 | /* G_interactive_fd++; */ |
10045 | break; | 10047 | break; |
10046 | case 's': | 10048 | case 's': |
10047 | flags |= OPT_s; | 10049 | G.opt_s = 1; |
10048 | break; | 10050 | break; |
10049 | case 'l': | 10051 | case 'l': |
10050 | flags |= OPT_login; | 10052 | flags |= OPT_login; |
@@ -10154,7 +10156,7 @@ int hush_main(int argc, char **argv) | |||
10154 | } | 10156 | } |
10155 | 10157 | ||
10156 | /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ | 10158 | /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ |
10157 | if (!(flags & OPT_s) && G.global_argv[1]) { | 10159 | if (!G.opt_s && G.global_argv[1]) { |
10158 | HFILE *input; | 10160 | HFILE *input; |
10159 | /* | 10161 | /* |
10160 | * "bash <script>" (which is never interactive (unless -i?)) | 10162 | * "bash <script>" (which is never interactive (unless -i?)) |
@@ -10178,6 +10180,7 @@ int hush_main(int argc, char **argv) | |||
10178 | #endif | 10180 | #endif |
10179 | goto final_return; | 10181 | goto final_return; |
10180 | } | 10182 | } |
10183 | /* "implicit" -s: bare interactive hush shows 's' in $- */ | ||
10181 | G.opt_s = 1; | 10184 | G.opt_s = 1; |
10182 | 10185 | ||
10183 | /* Up to here, shell was non-interactive. Now it may become one. | 10186 | /* Up to here, shell was non-interactive. Now it may become one. |
@@ -10614,7 +10617,7 @@ static int FAST_FUNC builtin_read(char **argv) | |||
10614 | } | 10617 | } |
10615 | 10618 | ||
10616 | if ((uintptr_t)r > 1) { | 10619 | if ((uintptr_t)r > 1) { |
10617 | bb_error_msg("%s", r); | 10620 | bb_simple_error_msg(r); |
10618 | r = (char*)(uintptr_t)1; | 10621 | r = (char*)(uintptr_t)1; |
10619 | } | 10622 | } |
10620 | 10623 | ||
@@ -10859,7 +10862,7 @@ static int FAST_FUNC builtin_unset(char **argv) | |||
10859 | if (opts == (unsigned)-1) | 10862 | if (opts == (unsigned)-1) |
10860 | return EXIT_FAILURE; | 10863 | return EXIT_FAILURE; |
10861 | if (opts == 3) { | 10864 | if (opts == 3) { |
10862 | bb_error_msg("unset: -v and -f are exclusive"); | 10865 | bb_simple_error_msg("unset: -v and -f are exclusive"); |
10863 | return EXIT_FAILURE; | 10866 | return EXIT_FAILURE; |
10864 | } | 10867 | } |
10865 | argv += optind; | 10868 | argv += optind; |
@@ -11022,7 +11025,7 @@ Test that VAR is a valid variable name? | |||
11022 | 11025 | ||
11023 | optstring = *++argv; | 11026 | optstring = *++argv; |
11024 | if (!optstring || !(var = *++argv)) { | 11027 | if (!optstring || !(var = *++argv)) { |
11025 | bb_error_msg("usage: getopts OPTSTRING VAR [ARGS]"); | 11028 | bb_simple_error_msg("usage: getopts OPTSTRING VAR [ARGS]"); |
11026 | return EXIT_FAILURE; | 11029 | return EXIT_FAILURE; |
11027 | } | 11030 | } |
11028 | 11031 | ||
@@ -11251,7 +11254,7 @@ static int FAST_FUNC builtin_trap(char **argv) | |||
11251 | } | 11254 | } |
11252 | 11255 | ||
11253 | if (!argv[1]) { /* no second arg */ | 11256 | if (!argv[1]) { /* no second arg */ |
11254 | bb_error_msg("trap: invalid arguments"); | 11257 | bb_simple_error_msg("trap: invalid arguments"); |
11255 | return EXIT_FAILURE; | 11258 | return EXIT_FAILURE; |
11256 | } | 11259 | } |
11257 | 11260 | ||
@@ -11292,7 +11295,7 @@ static struct pipe *parse_jobspec(const char *str) | |||
11292 | /* It is "%%", "%+" or "%" - current job */ | 11295 | /* It is "%%", "%+" or "%" - current job */ |
11293 | jobnum = G.last_jobid; | 11296 | jobnum = G.last_jobid; |
11294 | if (jobnum == 0) { | 11297 | if (jobnum == 0) { |
11295 | bb_error_msg("no current job"); | 11298 | bb_simple_error_msg("no current job"); |
11296 | return NULL; | 11299 | return NULL; |
11297 | } | 11300 | } |
11298 | } | 11301 | } |
@@ -11369,7 +11372,7 @@ static int FAST_FUNC builtin_fg_bg(char **argv) | |||
11369 | delete_finished_job(pi); | 11372 | delete_finished_job(pi); |
11370 | return EXIT_SUCCESS; | 11373 | return EXIT_SUCCESS; |
11371 | } | 11374 | } |
11372 | bb_perror_msg("kill (SIGCONT)"); | 11375 | bb_simple_perror_msg("kill (SIGCONT)"); |
11373 | } | 11376 | } |
11374 | 11377 | ||
11375 | if (argv[0][0] == 'f') { | 11378 | if (argv[0][0] == 'f') { |