diff options
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/shell/hush.c b/shell/hush.c index 9b15efb30..8baccf246 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -39,25 +39,28 @@ | |||
39 | * | 39 | * |
40 | * POSIX syntax not implemented: | 40 | * POSIX syntax not implemented: |
41 | * aliases | 41 | * aliases |
42 | * <(list) and >(list) Process Substitution | ||
43 | * Tilde Expansion | 42 | * Tilde Expansion |
44 | * | 43 | * |
45 | * Bash stuff (optionally enabled): | 44 | * Bash compat TODO: |
46 | * &> and >& redirection of stdout+stderr | 45 | * redirection of stdout+stderr: &> and >& |
47 | * Brace Expansion | 46 | * brace expansion: one/{two,three,four} |
48 | * reserved words: [[ ]] function select | 47 | * reserved words: function select |
49 | * substrings ${var:1:5} | 48 | * advanced test: [[ ]] |
49 | * substrings: ${var:1:5} | ||
50 | * process substitution: <(list) and >(list) | ||
51 | * =~: regex operator | ||
50 | * let EXPR [EXPR...] | 52 | * let EXPR [EXPR...] |
51 | * Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION) | 53 | * Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION) |
52 | * If the last arg evaluates to 0, let returns 1; 0 otherwise. | 54 | * If the last arg evaluates to 0, let returns 1; 0 otherwise. |
53 | * NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used) | 55 | * NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used) |
54 | * ((EXPR)) | 56 | * ((EXPR)) |
55 | * The EXPR is evaluated according to ARITHMETIC EVALUATION. | 57 | * The EXPR is evaluated according to ARITHMETIC EVALUATION. |
56 | * This is exactly equivalent to let "expression". | 58 | * This is exactly equivalent to let "EXPR". |
59 | * $[EXPR]: synonym for $((EXPR)) | ||
57 | * | 60 | * |
58 | * TODOs: | 61 | * TODOs: |
59 | * grep for "TODO" and fix (some of them are easy) | 62 | * grep for "TODO" and fix (some of them are easy) |
60 | * special variables (done: PWD) | 63 | * special variables (done: PWD, PPID, RANDOM) |
61 | * follow IFS rules more precisely, including update semantics | 64 | * follow IFS rules more precisely, including update semantics |
62 | * export builtin should be special, its arguments are assignments | 65 | * export builtin should be special, its arguments are assignments |
63 | * and therefore expansion of them should be "one-word" expansion: | 66 | * and therefore expansion of them should be "one-word" expansion: |
@@ -673,6 +676,9 @@ static const struct built_in_command bltins1[] = { | |||
673 | #endif | 676 | #endif |
674 | BLTIN("set" , builtin_set , "Set/unset positional parameters"), | 677 | BLTIN("set" , builtin_set , "Set/unset positional parameters"), |
675 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), | 678 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), |
679 | #if ENABLE_HUSH_BASH_COMPAT | ||
680 | BLTIN("source" , builtin_source , "Run commands in a file"), | ||
681 | #endif | ||
676 | BLTIN("trap" , builtin_trap , "Trap signals"), | 682 | BLTIN("trap" , builtin_trap , "Trap signals"), |
677 | BLTIN("type" , builtin_type , "Show command type"), | 683 | BLTIN("type" , builtin_type , "Show command type"), |
678 | BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"), | 684 | BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"), |
@@ -6232,10 +6238,15 @@ static struct pipe *parse_stream(char **pstring, | |||
6232 | is_special = "{}<>;&|()#'" /* special outside of "str" */ | 6238 | is_special = "{}<>;&|()#'" /* special outside of "str" */ |
6233 | "\\$\"" IF_HUSH_TICK("`"); /* always special */ | 6239 | "\\$\"" IF_HUSH_TICK("`"); /* always special */ |
6234 | /* Are { and } special here? */ | 6240 | /* Are { and } special here? */ |
6235 | if (ctx.command->argv /* word [word]{... */ | 6241 | if (ctx.command->argv /* word [word]{... - non-special */ |
6236 | || dest.length /* word{... */ | 6242 | || dest.length /* word{... - non-special */ |
6237 | || dest.o_quoted /* ""{... */ | 6243 | || dest.o_quoted /* ""{... - non-special */ |
6238 | || (next != ';' && next != ')' && !strchr(G.ifs, next)) /* {word */ | 6244 | || (next != ';' /* }; - special */ |
6245 | && next != ')' /* }) - special */ | ||
6246 | && next != '&' /* }& and }&& ... - special */ | ||
6247 | && next != '|' /* }|| ... - special */ | ||
6248 | && !strchr(G.ifs, next) /* {word - non-special */ | ||
6249 | ) | ||
6239 | ) { | 6250 | ) { |
6240 | /* They are not special, skip "{}" */ | 6251 | /* They are not special, skip "{}" */ |
6241 | is_special += 2; | 6252 | is_special += 2; |
@@ -7859,21 +7870,26 @@ static int FAST_FUNC builtin_shift(char **argv) | |||
7859 | 7870 | ||
7860 | static int FAST_FUNC builtin_source(char **argv) | 7871 | static int FAST_FUNC builtin_source(char **argv) |
7861 | { | 7872 | { |
7862 | char *arg_path; | 7873 | char *arg_path, *filename; |
7863 | FILE *input; | 7874 | FILE *input; |
7864 | save_arg_t sv; | 7875 | save_arg_t sv; |
7865 | #if ENABLE_HUSH_FUNCTIONS | 7876 | #if ENABLE_HUSH_FUNCTIONS |
7866 | smallint sv_flg; | 7877 | smallint sv_flg; |
7867 | #endif | 7878 | #endif |
7868 | 7879 | ||
7869 | if (*++argv == NULL) | 7880 | arg_path = NULL; |
7870 | return EXIT_FAILURE; | 7881 | filename = *++argv; |
7871 | 7882 | if (!filename) { | |
7872 | if (strchr(*argv, '/') == NULL && (arg_path = find_in_path(*argv)) != NULL) { | 7883 | /* bash says: "bash: .: filename argument required" */ |
7873 | input = fopen_for_read(arg_path); | 7884 | return 2; /* bash compat */ |
7874 | free(arg_path); | 7885 | } |
7875 | } else | 7886 | if (!strchr(filename, '/')) { |
7876 | input = fopen_or_warn(*argv, "r"); | 7887 | arg_path = find_in_path(filename); |
7888 | if (arg_path) | ||
7889 | filename = arg_path; | ||
7890 | } | ||
7891 | input = fopen_or_warn(filename, "r"); | ||
7892 | free(arg_path); | ||
7877 | if (!input) { | 7893 | if (!input) { |
7878 | /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ | 7894 | /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ |
7879 | return EXIT_FAILURE; | 7895 | return EXIT_FAILURE; |