aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 6d472337f..6a27b1634 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -339,7 +339,7 @@
339 * therefore we don't show them either. 339 * therefore we don't show them either.
340 */ 340 */
341//usage:#define hush_trivial_usage 341//usage:#define hush_trivial_usage
342//usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]" 342//usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]"
343//usage:#define hush_full_usage "\n\n" 343//usage:#define hush_full_usage "\n\n"
344//usage: "Unix shell interpreter" 344//usage: "Unix shell interpreter"
345 345
@@ -373,7 +373,7 @@
373# define F_DUPFD_CLOEXEC F_DUPFD 373# define F_DUPFD_CLOEXEC F_DUPFD
374#endif 374#endif
375 375
376#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH) 376#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !ENABLE_SHELL_ASH
377# include "embedded_scripts.h" 377# include "embedded_scripts.h"
378#else 378#else
379# define NUM_SCRIPTS 0 379# define NUM_SCRIPTS 0
@@ -3360,7 +3360,7 @@ static int glob_brace(char *pattern, o_string *o, int n)
3360 * NEXT points past the terminator of the first element, and REST 3360 * NEXT points past the terminator of the first element, and REST
3361 * points past the final }. We will accumulate result names from 3361 * points past the final }. We will accumulate result names from
3362 * recursive runs for each brace alternative in the buffer using 3362 * recursive runs for each brace alternative in the buffer using
3363 * GLOB_APPEND. */ 3363 * GLOB_APPEND. */
3364 3364
3365 p = begin + 1; 3365 p = begin + 1;
3366 while (1) { 3366 while (1) {
@@ -6311,7 +6311,7 @@ static char *encode_then_expand_vararg(const char *str, int handle_squotes, int
6311 6311
6312/* Expanding ARG in ${var+ARG}, ${var-ARG} 6312/* Expanding ARG in ${var+ARG}, ${var-ARG}
6313 */ 6313 */
6314static int encode_then_append_var_plusminus(o_string *output, int n, 6314static NOINLINE int encode_then_append_var_plusminus(o_string *output, int n,
6315 char *str, int dquoted) 6315 char *str, int dquoted)
6316{ 6316{
6317 struct in_str input; 6317 struct in_str input;
@@ -6472,16 +6472,21 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
6472/* ${var/[/]pattern[/repl]} helpers */ 6472/* ${var/[/]pattern[/repl]} helpers */
6473static char *strstr_pattern(char *val, const char *pattern, int *size) 6473static char *strstr_pattern(char *val, const char *pattern, int *size)
6474{ 6474{
6475 int sz = strcspn(pattern, "*?[\\"); 6475 int first_escaped = (pattern[0] == '\\' && pattern[1]);
6476 if (pattern[sz] == '\0') { 6476 /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars"
6477 * as literal too (as it is semi-common, and easy to accomodate
6478 * by just using str + 1).
6479 */
6480 int sz = strcspn(pattern + first_escaped * 2, "*?[\\");
6481 if ((pattern + first_escaped * 2)[sz] == '\0') {
6477 /* Optimization for trivial patterns. 6482 /* Optimization for trivial patterns.
6478 * Testcase for very slow replace (performs about 22k replaces): 6483 * Testcase for very slow replace (performs about 22k replaces):
6479 * x=:::::::::::::::::::::: 6484 * x=::::::::::::::::::::::
6480 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} 6485 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x}
6481 * echo "${x//:/|}" 6486 * echo "${x//:/|}"
6482 */ 6487 */
6483 *size = sz; 6488 *size = sz + first_escaped;
6484 return strstr(val, pattern); 6489 return strstr(val, pattern + first_escaped);
6485 } 6490 }
6486 6491
6487 while (1) { 6492 while (1) {
@@ -10220,7 +10225,7 @@ int hush_main(int argc, char **argv)
10220 10225
10221 cached_getpid = getpid(); /* for tcsetpgrp() during init */ 10226 cached_getpid = getpid(); /* for tcsetpgrp() during init */
10222 G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ 10227 G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */
10223 G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */ 10228 G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */
10224 10229
10225 /* Deal with HUSH_VERSION */ 10230 /* Deal with HUSH_VERSION */
10226 debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); 10231 debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
@@ -10351,6 +10356,29 @@ int hush_main(int argc, char **argv)
10351 /* Well, we cannot just declare interactiveness, 10356 /* Well, we cannot just declare interactiveness,
10352 * we have to have some stuff (ctty, etc) */ 10357 * we have to have some stuff (ctty, etc) */
10353 /* G_interactive_fd++; */ 10358 /* G_interactive_fd++; */
10359//There are a few cases where bash -i -c 'SCRIPT'
10360//has visible effect (differs from bash -c 'SCRIPT'):
10361//it ignores TERM:
10362// bash -i -c 'kill $$; echo ALIVE'
10363// ALIVE
10364//it resets SIG_INGed HUP to SIG_DFL:
10365// trap '' hup; bash -i -c 'kill -hup $$; echo ALIVE'
10366// Hangup [the message is not printed by bash, it's the shell which started it]
10367//is talkative about jobs and exiting:
10368// bash -i -c 'sleep 1 & exit'
10369// [1] 16170
10370// exit
10371//includes $ENV file (only if run as "sh"):
10372// echo last >/tmp/ENV; ENV=/tmp/ENV sh -i -c 'echo HERE'
10373// last: cannot open /var/log/wtmp: No such file or directory
10374// HERE
10375//(under "bash", it's the opposite: it runs $BASH_ENV file only *without* -i).
10376//
10377//ash -i -c 'sleep 3; sleep 3', on ^C, drops into a prompt instead of exiting
10378//(this may be a bug, bash does not do this).
10379//(ash -i -c 'sleep 3' won't show this, the last command gets auto-"exec"ed)
10380//
10381//None of the above feel like useful features people would rely on.
10354 break; 10382 break;
10355 case 's': 10383 case 's':
10356 G.opt_s = 1; 10384 G.opt_s = 1;
@@ -11727,7 +11755,7 @@ static int FAST_FUNC builtin_fg_bg(char **argv)
11727 /* TODO: bash prints a string representation 11755 /* TODO: bash prints a string representation
11728 * of job being foregrounded (like "sleep 1 | cat") */ 11756 * of job being foregrounded (like "sleep 1 | cat") */
11729 if (argv[0][0] == 'f' && G_saved_tty_pgrp) { 11757 if (argv[0][0] == 'f' && G_saved_tty_pgrp) {
11730 /* Put the job into the foreground. */ 11758 /* Put the job into the foreground. */
11731 tcsetpgrp(G_interactive_fd, pi->pgrp); 11759 tcsetpgrp(G_interactive_fd, pi->pgrp);
11732 } 11760 }
11733 11761