aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c45
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') {