Magellan Linux

Contents of /trunk/mkinitrd-magellan/busybox/shell/hush.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 989 - (show annotations) (download)
Sun May 30 11:41:34 2010 UTC (13 years, 11 months ago) by niro
File MIME type: text/plain
File size: 220236 byte(s)
-added upstream hush patch
1 /* vi: set sw=4 ts=4: */
2 /*
3 * A prototype Bourne shell grammar parser.
4 * Intended to follow the original Thompson and Ritchie
5 * "small and simple is beautiful" philosophy, which
6 * incidentally is a good match to today's BusyBox.
7 *
8 * Copyright (C) 2000,2001 Larry Doolittle <larry@doolittle.boa.org>
9 * Copyright (C) 2008,2009 Denys Vlasenko <vda.linux@googlemail.com>
10 *
11 * Credits:
12 * The parser routines proper are all original material, first
13 * written Dec 2000 and Jan 2001 by Larry Doolittle. The
14 * execution engine, the builtins, and much of the underlying
15 * support has been adapted from busybox-0.49pre's lash, which is
16 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
17 * written by Erik Andersen <andersen@codepoet.org>. That, in turn,
18 * is based in part on ladsh.c, by Michael K. Johnson and Erik W.
19 * Troan, which they placed in the public domain. I don't know
20 * how much of the Johnson/Troan code has survived the repeated
21 * rewrites.
22 *
23 * Other credits:
24 * o_addchr derived from similar w_addchar function in glibc-2.2.
25 * parse_redirect, redirect_opt_num, and big chunks of main
26 * and many builtins derived from contributions by Erik Andersen.
27 * Miscellaneous bugfixes from Matt Kraai.
28 *
29 * There are two big (and related) architecture differences between
30 * this parser and the lash parser. One is that this version is
31 * actually designed from the ground up to understand nearly all
32 * of the Bourne grammar. The second, consequential change is that
33 * the parser and input reader have been turned inside out. Now,
34 * the parser is in control, and asks for input as needed. The old
35 * way had the input reader in control, and it asked for parsing to
36 * take place as needed. The new way makes it much easier to properly
37 * handle the recursion implicit in the various substitutions, especially
38 * across continuation lines.
39 *
40 * POSIX syntax not implemented:
41 * aliases
42 * <(list) and >(list) Process Substitution
43 * Tilde Expansion
44 *
45 * Bash stuff (optionally enabled):
46 * &> and >& redirection of stdout+stderr
47 * Brace Expansion
48 * reserved words: [[ ]] function select
49 * substrings ${var:1:5}
50 * let EXPR [EXPR...]
51 * Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION)
52 * 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)
54 * ((EXPR))
55 * The EXPR is evaluated according to ARITHMETIC EVALUATION.
56 * This is exactly equivalent to let "expression".
57 *
58 * TODOs:
59 * grep for "TODO" and fix (some of them are easy)
60 * builtins: ulimit
61 * special variables (done: PWD)
62 * follow IFS rules more precisely, including update semantics
63 * export builtin should be special, its arguments are assignments
64 * and therefore expansion of them should be "one-word" expansion:
65 * $ export i=`echo 'a b'` # export has one arg: "i=a b"
66 * compare with:
67 * $ ls i=`echo 'a b'` # ls has two args: "i=a" and "b"
68 * ls: cannot access i=a: No such file or directory
69 * ls: cannot access b: No such file or directory
70 * Note1: same applies to local builtin.
71 * Note2: bash 3.2.33(1) does this only if export word itself
72 * is not quoted:
73 * $ export i=`echo 'aaa bbb'`; echo "$i"
74 * aaa bbb
75 * $ "export" i=`echo 'aaa bbb'`; echo "$i"
76 * aaa
77 *
78 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
79 */
80 #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */
81 #include <malloc.h> /* for malloc_trim */
82 #include <glob.h>
83 /* #include <dmalloc.h> */
84 #if ENABLE_HUSH_CASE
85 # include <fnmatch.h>
86 #endif
87
88 #include "shell_common.h"
89 #include "builtin_read.h"
90 #include "math.h"
91 #include "match.h"
92 #if ENABLE_HUSH_RANDOM_SUPPORT
93 # include "random.h"
94 #else
95 # define CLEAR_RANDOM_T(rnd) ((void)0)
96 #endif
97 #ifndef PIPE_BUF
98 # define PIPE_BUF 4096 /* amount of buffering in a pipe */
99 #endif
100
101
102 /* Build knobs */
103 #define LEAK_HUNTING 0
104 #define BUILD_AS_NOMMU 0
105 /* Enable/disable sanity checks. Ok to enable in production,
106 * only adds a bit of bloat. Set to >1 to get non-production level verbosity.
107 * Keeping 1 for now even in released versions.
108 */
109 #define HUSH_DEBUG 1
110 /* Slightly bigger (+200 bytes), but faster hush.
111 * So far it only enables a trick with counting SIGCHLDs and forks,
112 * which allows us to do fewer waitpid's.
113 * (we can detect a case where neither forks were done nor SIGCHLDs happened
114 * and therefore waitpid will return the same result as last time)
115 */
116 #define ENABLE_HUSH_FAST 0
117
118
119 #if BUILD_AS_NOMMU
120 # undef BB_MMU
121 # undef USE_FOR_NOMMU
122 # undef USE_FOR_MMU
123 # define BB_MMU 0
124 # define USE_FOR_NOMMU(...) __VA_ARGS__
125 # define USE_FOR_MMU(...)
126 #endif
127
128 #define SKIP_definitions 1
129 #include "applet_tables.h"
130 #undef SKIP_definitions
131 #if NUM_APPLETS == 1
132 /* STANDALONE does not make sense, and won't compile */
133 # undef CONFIG_FEATURE_SH_STANDALONE
134 # undef ENABLE_FEATURE_SH_STANDALONE
135 # undef IF_FEATURE_SH_STANDALONE
136 # undef IF_NOT_FEATURE_SH_STANDALONE
137 # define ENABLE_FEATURE_SH_STANDALONE 0
138 # define IF_FEATURE_SH_STANDALONE(...)
139 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
140 #endif
141
142 #if !ENABLE_HUSH_INTERACTIVE
143 # undef ENABLE_FEATURE_EDITING
144 # define ENABLE_FEATURE_EDITING 0
145 # undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
146 # define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
147 #endif
148
149 /* Do we support ANY keywords? */
150 #if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
151 # define HAS_KEYWORDS 1
152 # define IF_HAS_KEYWORDS(...) __VA_ARGS__
153 # define IF_HAS_NO_KEYWORDS(...)
154 #else
155 # define HAS_KEYWORDS 0
156 # define IF_HAS_KEYWORDS(...)
157 # define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
158 #endif
159
160 /* If you comment out one of these below, it will be #defined later
161 * to perform debug printfs to stderr: */
162 #define debug_printf(...) do {} while (0)
163 /* Finer-grained debug switches */
164 #define debug_printf_parse(...) do {} while (0)
165 #define debug_print_tree(a, b) do {} while (0)
166 #define debug_printf_exec(...) do {} while (0)
167 #define debug_printf_env(...) do {} while (0)
168 #define debug_printf_jobs(...) do {} while (0)
169 #define debug_printf_expand(...) do {} while (0)
170 #define debug_printf_glob(...) do {} while (0)
171 #define debug_printf_list(...) do {} while (0)
172 #define debug_printf_subst(...) do {} while (0)
173 #define debug_printf_clean(...) do {} while (0)
174
175 #define ERR_PTR ((void*)(long)1)
176
177 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
178
179 #define SPECIAL_VAR_SYMBOL 3
180
181 struct variable;
182
183 static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER;
184
185 /* This supports saving pointers malloced in vfork child,
186 * to be freed in the parent.
187 */
188 #if !BB_MMU
189 typedef struct nommu_save_t {
190 char **new_env;
191 struct variable *old_vars;
192 char **argv;
193 char **argv_from_re_execing;
194 } nommu_save_t;
195 #endif
196
197 typedef enum reserved_style {
198 RES_NONE = 0,
199 #if ENABLE_HUSH_IF
200 RES_IF ,
201 RES_THEN ,
202 RES_ELIF ,
203 RES_ELSE ,
204 RES_FI ,
205 #endif
206 #if ENABLE_HUSH_LOOPS
207 RES_FOR ,
208 RES_WHILE ,
209 RES_UNTIL ,
210 RES_DO ,
211 RES_DONE ,
212 #endif
213 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
214 RES_IN ,
215 #endif
216 #if ENABLE_HUSH_CASE
217 RES_CASE ,
218 /* three pseudo-keywords support contrived "case" syntax: */
219 RES_CASE_IN, /* "case ... IN", turns into RES_MATCH when IN is observed */
220 RES_MATCH , /* "word)" */
221 RES_CASE_BODY, /* "this command is inside CASE" */
222 RES_ESAC ,
223 #endif
224 RES_XXXX ,
225 RES_SNTX
226 } reserved_style;
227
228 typedef struct o_string {
229 char *data;
230 int length; /* position where data is appended */
231 int maxlen;
232 /* Protect newly added chars against globbing
233 * (by prepending \ to *, ?, [, \) */
234 smallint o_escape;
235 smallint o_glob;
236 /* At least some part of the string was inside '' or "",
237 * possibly empty one: word"", wo''rd etc. */
238 smallint o_quoted;
239 smallint has_empty_slot;
240 smallint o_assignment; /* 0:maybe, 1:yes, 2:no */
241 } o_string;
242 enum {
243 MAYBE_ASSIGNMENT = 0,
244 DEFINITELY_ASSIGNMENT = 1,
245 NOT_ASSIGNMENT = 2,
246 WORD_IS_KEYWORD = 3, /* not assigment, but next word may be: "if v=xyz cmd;" */
247 };
248 /* Used for initialization: o_string foo = NULL_O_STRING; */
249 #define NULL_O_STRING { NULL }
250
251 /* I can almost use ordinary FILE*. Is open_memstream() universally
252 * available? Where is it documented? */
253 typedef struct in_str {
254 const char *p;
255 /* eof_flag=1: last char in ->p is really an EOF */
256 char eof_flag; /* meaningless if ->p == NULL */
257 char peek_buf[2];
258 #if ENABLE_HUSH_INTERACTIVE
259 smallint promptme;
260 smallint promptmode; /* 0: PS1, 1: PS2 */
261 #endif
262 FILE *file;
263 int (*get) (struct in_str *) FAST_FUNC;
264 int (*peek) (struct in_str *) FAST_FUNC;
265 } in_str;
266 #define i_getch(input) ((input)->get(input))
267 #define i_peek(input) ((input)->peek(input))
268
269 /* The descrip member of this structure is only used to make
270 * debugging output pretty */
271 static const struct {
272 int mode;
273 signed char default_fd;
274 char descrip[3];
275 } redir_table[] = {
276 { O_RDONLY, 0, "<" },
277 { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" },
278 { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
279 { O_CREAT|O_RDWR, 1, "<>" },
280 { O_RDONLY, 0, "<<" },
281 /* Should not be needed. Bogus default_fd helps in debugging */
282 /* { O_RDONLY, 77, "<<" }, */
283 };
284
285 struct redir_struct {
286 struct redir_struct *next;
287 char *rd_filename; /* filename */
288 int rd_fd; /* fd to redirect */
289 /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */
290 int rd_dup;
291 smallint rd_type; /* (enum redir_type) */
292 /* note: for heredocs, rd_filename contains heredoc delimiter,
293 * and subsequently heredoc itself; and rd_dup is a bitmask:
294 * bit 0: do we need to trim leading tabs?
295 * bit 1: is heredoc quoted (<<'delim' syntax) ?
296 */
297 };
298 typedef enum redir_type {
299 REDIRECT_INPUT = 0,
300 REDIRECT_OVERWRITE = 1,
301 REDIRECT_APPEND = 2,
302 REDIRECT_IO = 3,
303 REDIRECT_HEREDOC = 4,
304 REDIRECT_HEREDOC2 = 5, /* REDIRECT_HEREDOC after heredoc is loaded */
305
306 REDIRFD_CLOSE = -3,
307 REDIRFD_SYNTAX_ERR = -2,
308 REDIRFD_TO_FILE = -1,
309 /* otherwise, rd_fd is redirected to rd_dup */
310
311 HEREDOC_SKIPTABS = 1,
312 HEREDOC_QUOTED = 2,
313 } redir_type;
314
315
316 struct command {
317 pid_t pid; /* 0 if exited */
318 int assignment_cnt; /* how many argv[i] are assignments? */
319 smallint is_stopped; /* is the command currently running? */
320 smallint cmd_type; /* CMD_xxx */
321 #define CMD_NORMAL 0
322 #define CMD_SUBSHELL 1
323
324 /* used for "[[ EXPR ]]" */
325 #if ENABLE_HUSH_BASH_COMPAT
326 # define CMD_SINGLEWORD_NOGLOB 2
327 #endif
328
329 /* used for "export noglob=* glob* a=`echo a b`" */
330 //#define CMD_SINGLEWORD_NOGLOB_COND 3
331 // It is hard to implement correctly, it adds significant amounts of tricky code,
332 // and all this is only useful for really obscure export statements
333 // almost nobody would use anyway. #ifdef CMD_SINGLEWORD_NOGLOB_COND
334 // guards the code which implements it, but I have doubts it works
335 // in all cases (especially with mixed globbed/non-globbed arguments)
336
337 #if ENABLE_HUSH_FUNCTIONS
338 # define CMD_FUNCDEF 3
339 #endif
340
341 /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
342 struct pipe *group;
343 #if !BB_MMU
344 char *group_as_string;
345 #endif
346 #if ENABLE_HUSH_FUNCTIONS
347 struct function *child_func;
348 /* This field is used to prevent a bug here:
349 * while...do f1() {a;}; f1; f1() {b;}; f1; done
350 * When we execute "f1() {a;}" cmd, we create new function and clear
351 * cmd->group, cmd->group_as_string, cmd->argv[0].
352 * When we execute "f1() {b;}", we notice that f1 exists,
353 * and that its "parent cmd" struct is still "alive",
354 * we put those fields back into cmd->xxx
355 * (struct function has ->parent_cmd ptr to facilitate that).
356 * When we loop back, we can execute "f1() {a;}" again and set f1 correctly.
357 * Without this trick, loop would execute a;b;b;b;...
358 * instead of correct sequence a;b;a;b;...
359 * When command is freed, it severs the link
360 * (sets ->child_func->parent_cmd to NULL).
361 */
362 #endif
363 char **argv; /* command name and arguments */
364 /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
365 * and on execution these are substituted with their values.
366 * Substitution can make _several_ words out of one argv[n]!
367 * Example: argv[0]=='.^C*^C.' here: echo .$*.
368 * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
369 */
370 struct redir_struct *redirects; /* I/O redirections */
371 };
372 /* Is there anything in this command at all? */
373 #define IS_NULL_CMD(cmd) \
374 (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects)
375
376
377 struct pipe {
378 struct pipe *next;
379 int num_cmds; /* total number of commands in pipe */
380 int alive_cmds; /* number of commands running (not exited) */
381 int stopped_cmds; /* number of commands alive, but stopped */
382 #if ENABLE_HUSH_JOB
383 int jobid; /* job number */
384 pid_t pgrp; /* process group ID for the job */
385 char *cmdtext; /* name of job */
386 #endif
387 struct command *cmds; /* array of commands in pipe */
388 smallint followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
389 IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
390 IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
391 };
392 typedef enum pipe_style {
393 PIPE_SEQ = 1,
394 PIPE_AND = 2,
395 PIPE_OR = 3,
396 PIPE_BG = 4,
397 } pipe_style;
398 /* Is there anything in this pipe at all? */
399 #define IS_NULL_PIPE(pi) \
400 ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE))
401
402 /* This holds pointers to the various results of parsing */
403 struct parse_context {
404 /* linked list of pipes */
405 struct pipe *list_head;
406 /* last pipe (being constructed right now) */
407 struct pipe *pipe;
408 /* last command in pipe (being constructed right now) */
409 struct command *command;
410 /* last redirect in command->redirects list */
411 struct redir_struct *pending_redirect;
412 #if !BB_MMU
413 o_string as_string;
414 #endif
415 #if HAS_KEYWORDS
416 smallint ctx_res_w;
417 smallint ctx_inverted; /* "! cmd | cmd" */
418 #if ENABLE_HUSH_CASE
419 smallint ctx_dsemicolon; /* ";;" seen */
420 #endif
421 /* bitmask of FLAG_xxx, for figuring out valid reserved words */
422 int old_flag;
423 /* group we are enclosed in:
424 * example: "if pipe1; pipe2; then pipe3; fi"
425 * when we see "if" or "then", we malloc and copy current context,
426 * and make ->stack point to it. then we parse pipeN.
427 * when closing "then" / fi" / whatever is found,
428 * we move list_head into ->stack->command->group,
429 * copy ->stack into current context, and delete ->stack.
430 * (parsing of { list } and ( list ) doesn't use this method)
431 */
432 struct parse_context *stack;
433 #endif
434 };
435
436 /* On program start, environ points to initial environment.
437 * putenv adds new pointers into it, unsetenv removes them.
438 * Neither of these (de)allocates the strings.
439 * setenv allocates new strings in malloc space and does putenv,
440 * and thus setenv is unusable (leaky) for shell's purposes */
441 #define setenv(...) setenv_is_leaky_dont_use()
442 struct variable {
443 struct variable *next;
444 char *varstr; /* points to "name=" portion */
445 #if ENABLE_HUSH_LOCAL
446 unsigned func_nest_level;
447 #endif
448 int max_len; /* if > 0, name is part of initial env; else name is malloced */
449 smallint flg_export; /* putenv should be done on this var */
450 smallint flg_read_only;
451 };
452
453 enum {
454 BC_BREAK = 1,
455 BC_CONTINUE = 2,
456 };
457
458 #if ENABLE_HUSH_FUNCTIONS
459 struct function {
460 struct function *next;
461 char *name;
462 struct command *parent_cmd;
463 struct pipe *body;
464 # if !BB_MMU
465 char *body_as_string;
466 # endif
467 };
468 #endif
469
470
471 /* "Globals" within this file */
472 /* Sorted roughly by size (smaller offsets == smaller code) */
473 struct globals {
474 /* interactive_fd != 0 means we are an interactive shell.
475 * If we are, then saved_tty_pgrp can also be != 0, meaning
476 * that controlling tty is available. With saved_tty_pgrp == 0,
477 * job control still works, but terminal signals
478 * (^C, ^Z, ^Y, ^\) won't work at all, and background
479 * process groups can only be created with "cmd &".
480 * With saved_tty_pgrp != 0, hush will use tcsetpgrp()
481 * to give tty to the foreground process group,
482 * and will take it back when the group is stopped (^Z)
483 * or killed (^C).
484 */
485 #if ENABLE_HUSH_INTERACTIVE
486 /* 'interactive_fd' is a fd# open to ctty, if we have one
487 * _AND_ if we decided to act interactively */
488 int interactive_fd;
489 const char *PS1;
490 const char *PS2;
491 # define G_interactive_fd (G.interactive_fd)
492 #else
493 # define G_interactive_fd 0
494 #endif
495 #if ENABLE_FEATURE_EDITING
496 line_input_t *line_input_state;
497 #endif
498 pid_t root_pid;
499 pid_t root_ppid;
500 pid_t last_bg_pid;
501 #if ENABLE_HUSH_RANDOM_SUPPORT
502 random_t random_gen;
503 #endif
504 #if ENABLE_HUSH_JOB
505 int run_list_level;
506 int last_jobid;
507 pid_t saved_tty_pgrp;
508 struct pipe *job_list;
509 # define G_saved_tty_pgrp (G.saved_tty_pgrp)
510 #else
511 # define G_saved_tty_pgrp 0
512 #endif
513 smallint flag_SIGINT;
514 #if ENABLE_HUSH_LOOPS
515 smallint flag_break_continue;
516 #endif
517 #if ENABLE_HUSH_FUNCTIONS
518 /* 0: outside of a function (or sourced file)
519 * -1: inside of a function, ok to use return builtin
520 * 1: return is invoked, skip all till end of func
521 */
522 smallint flag_return_in_progress;
523 #endif
524 smallint fake_mode;
525 smallint exiting; /* used to prevent EXIT trap recursion */
526 /* These four support $?, $#, and $1 */
527 smalluint last_exitcode;
528 /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */
529 smalluint global_args_malloced;
530 smalluint inherited_set_is_saved;
531 /* how many non-NULL argv's we have. NB: $# + 1 */
532 int global_argc;
533 char **global_argv;
534 #if !BB_MMU
535 char *argv0_for_re_execing;
536 #endif
537 #if ENABLE_HUSH_LOOPS
538 unsigned depth_break_continue;
539 unsigned depth_of_loop;
540 #endif
541 const char *ifs;
542 const char *cwd;
543 struct variable *top_var; /* = &G.shell_ver (set in main()) */
544 struct variable shell_ver;
545 #if ENABLE_HUSH_FUNCTIONS
546 struct function *top_func;
547 # if ENABLE_HUSH_LOCAL
548 struct variable **shadowed_vars_pp;
549 unsigned func_nest_level;
550 # endif
551 #endif
552 /* Signal and trap handling */
553 #if ENABLE_HUSH_FAST
554 unsigned count_SIGCHLD;
555 unsigned handled_SIGCHLD;
556 smallint we_have_children;
557 #endif
558 /* which signals have non-DFL handler (even with no traps set)? */
559 unsigned non_DFL_mask;
560 char **traps; /* char *traps[NSIG] */
561 sigset_t blocked_set;
562 sigset_t inherited_set;
563 #if HUSH_DEBUG
564 unsigned long memleak_value;
565 int debug_indent;
566 #endif
567 char user_input_buf[ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 2];
568 };
569 #define G (*ptr_to_globals)
570 /* Not #defining name to G.name - this quickly gets unwieldy
571 * (too many defines). Also, I actually prefer to see when a variable
572 * is global, thus "G." prefix is a useful hint */
573 #define INIT_G() do { \
574 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
575 } while (0)
576
577
578 /* Function prototypes for builtins */
579 static int builtin_cd(char **argv) FAST_FUNC;
580 static int builtin_echo(char **argv) FAST_FUNC;
581 static int builtin_eval(char **argv) FAST_FUNC;
582 static int builtin_exec(char **argv) FAST_FUNC;
583 static int builtin_exit(char **argv) FAST_FUNC;
584 static int builtin_export(char **argv) FAST_FUNC;
585 #if ENABLE_HUSH_JOB
586 static int builtin_fg_bg(char **argv) FAST_FUNC;
587 static int builtin_jobs(char **argv) FAST_FUNC;
588 #endif
589 #if ENABLE_HUSH_HELP
590 static int builtin_help(char **argv) FAST_FUNC;
591 #endif
592 #if ENABLE_HUSH_LOCAL
593 static int builtin_local(char **argv) FAST_FUNC;
594 #endif
595 #if HUSH_DEBUG
596 static int builtin_memleak(char **argv) FAST_FUNC;
597 #endif
598 #if ENABLE_PRINTF
599 static int builtin_printf(char **argv) FAST_FUNC;
600 #endif
601 static int builtin_pwd(char **argv) FAST_FUNC;
602 static int builtin_read(char **argv) FAST_FUNC;
603 static int builtin_set(char **argv) FAST_FUNC;
604 static int builtin_shift(char **argv) FAST_FUNC;
605 static int builtin_source(char **argv) FAST_FUNC;
606 static int builtin_test(char **argv) FAST_FUNC;
607 static int builtin_trap(char **argv) FAST_FUNC;
608 static int builtin_type(char **argv) FAST_FUNC;
609 static int builtin_true(char **argv) FAST_FUNC;
610 static int builtin_umask(char **argv) FAST_FUNC;
611 static int builtin_unset(char **argv) FAST_FUNC;
612 static int builtin_wait(char **argv) FAST_FUNC;
613 #if ENABLE_HUSH_LOOPS
614 static int builtin_break(char **argv) FAST_FUNC;
615 static int builtin_continue(char **argv) FAST_FUNC;
616 #endif
617 #if ENABLE_HUSH_FUNCTIONS
618 static int builtin_return(char **argv) FAST_FUNC;
619 #endif
620
621 /* Table of built-in functions. They can be forked or not, depending on
622 * context: within pipes, they fork. As simple commands, they do not.
623 * When used in non-forking context, they can change global variables
624 * in the parent shell process. If forked, of course they cannot.
625 * For example, 'unset foo | whatever' will parse and run, but foo will
626 * still be set at the end. */
627 struct built_in_command {
628 const char *cmd;
629 int (*function)(char **argv) FAST_FUNC;
630 #if ENABLE_HUSH_HELP
631 const char *descr;
632 # define BLTIN(cmd, func, help) { cmd, func, help }
633 #else
634 # define BLTIN(cmd, func, help) { cmd, func }
635 #endif
636 };
637
638 static const struct built_in_command bltins1[] = {
639 BLTIN("." , builtin_source , "Run commands in a file"),
640 BLTIN(":" , builtin_true , NULL),
641 #if ENABLE_HUSH_JOB
642 BLTIN("bg" , builtin_fg_bg , "Resume a job in the background"),
643 #endif
644 #if ENABLE_HUSH_LOOPS
645 BLTIN("break" , builtin_break , "Exit from a loop"),
646 #endif
647 BLTIN("cd" , builtin_cd , "Change directory"),
648 #if ENABLE_HUSH_LOOPS
649 BLTIN("continue" , builtin_continue, "Start new loop iteration"),
650 #endif
651 BLTIN("eval" , builtin_eval , "Construct and run shell command"),
652 BLTIN("exec" , builtin_exec , "Execute command, don't return to shell"),
653 BLTIN("exit" , builtin_exit , "Exit"),
654 BLTIN("export" , builtin_export , "Set environment variables"),
655 #if ENABLE_HUSH_JOB
656 BLTIN("fg" , builtin_fg_bg , "Bring job into the foreground"),
657 #endif
658 #if ENABLE_HUSH_HELP
659 BLTIN("help" , builtin_help , NULL),
660 #endif
661 #if ENABLE_HUSH_JOB
662 BLTIN("jobs" , builtin_jobs , "List jobs"),
663 #endif
664 #if ENABLE_HUSH_LOCAL
665 BLTIN("local" , builtin_local , "Set local variables"),
666 #endif
667 #if HUSH_DEBUG
668 BLTIN("memleak" , builtin_memleak , NULL),
669 #endif
670 BLTIN("read" , builtin_read , "Input into variable"),
671 #if ENABLE_HUSH_FUNCTIONS
672 BLTIN("return" , builtin_return , "Return from a function"),
673 #endif
674 BLTIN("set" , builtin_set , "Set/unset positional parameters"),
675 BLTIN("shift" , builtin_shift , "Shift positional parameters"),
676 BLTIN("trap" , builtin_trap , "Trap signals"),
677 BLTIN("type" , builtin_type , "Write a description of command type"),
678 // BLTIN("ulimit" , builtin_ulimit , "Control resource limits"),
679 BLTIN("umask" , builtin_umask , "Set file creation mask"),
680 BLTIN("unset" , builtin_unset , "Unset variables"),
681 BLTIN("wait" , builtin_wait , "Wait for process"),
682 };
683 /* For now, echo and test are unconditionally enabled.
684 * Maybe make it configurable? */
685 static const struct built_in_command bltins2[] = {
686 BLTIN("[" , builtin_test , NULL),
687 BLTIN("echo" , builtin_echo , NULL),
688 #if ENABLE_PRINTF
689 BLTIN("printf" , builtin_printf , NULL),
690 #endif
691 BLTIN("pwd" , builtin_pwd , NULL),
692 BLTIN("test" , builtin_test , NULL),
693 };
694
695
696 /* Debug printouts.
697 */
698 #if HUSH_DEBUG
699 /* prevent disasters with G.debug_indent < 0 */
700 # define indent() fprintf(stderr, "%*s", (G.debug_indent * 2) & 0xff, "")
701 # define debug_enter() (G.debug_indent++)
702 # define debug_leave() (G.debug_indent--)
703 #else
704 # define indent() ((void)0)
705 # define debug_enter() ((void)0)
706 # define debug_leave() ((void)0)
707 #endif
708
709 #ifndef debug_printf
710 # define debug_printf(...) (indent(), fprintf(stderr, __VA_ARGS__))
711 #endif
712
713 #ifndef debug_printf_parse
714 # define debug_printf_parse(...) (indent(), fprintf(stderr, __VA_ARGS__))
715 #endif
716
717 #ifndef debug_printf_exec
718 #define debug_printf_exec(...) (indent(), fprintf(stderr, __VA_ARGS__))
719 #endif
720
721 #ifndef debug_printf_env
722 # define debug_printf_env(...) (indent(), fprintf(stderr, __VA_ARGS__))
723 #endif
724
725 #ifndef debug_printf_jobs
726 # define debug_printf_jobs(...) (indent(), fprintf(stderr, __VA_ARGS__))
727 # define DEBUG_JOBS 1
728 #else
729 # define DEBUG_JOBS 0
730 #endif
731
732 #ifndef debug_printf_expand
733 # define debug_printf_expand(...) (indent(), fprintf(stderr, __VA_ARGS__))
734 # define DEBUG_EXPAND 1
735 #else
736 # define DEBUG_EXPAND 0
737 #endif
738
739 #ifndef debug_printf_glob
740 # define debug_printf_glob(...) (indent(), fprintf(stderr, __VA_ARGS__))
741 # define DEBUG_GLOB 1
742 #else
743 # define DEBUG_GLOB 0
744 #endif
745
746 #ifndef debug_printf_list
747 # define debug_printf_list(...) (indent(), fprintf(stderr, __VA_ARGS__))
748 #endif
749
750 #ifndef debug_printf_subst
751 # define debug_printf_subst(...) (indent(), fprintf(stderr, __VA_ARGS__))
752 #endif
753
754 #ifndef debug_printf_clean
755 # define debug_printf_clean(...) (indent(), fprintf(stderr, __VA_ARGS__))
756 # define DEBUG_CLEAN 1
757 #else
758 # define DEBUG_CLEAN 0
759 #endif
760
761 #if DEBUG_EXPAND
762 static void debug_print_strings(const char *prefix, char **vv)
763 {
764 indent();
765 fprintf(stderr, "%s:\n", prefix);
766 while (*vv)
767 fprintf(stderr, " '%s'\n", *vv++);
768 }
769 #else
770 # define debug_print_strings(prefix, vv) ((void)0)
771 #endif
772
773
774 /* Leak hunting. Use hush_leaktool.sh for post-processing.
775 */
776 #if LEAK_HUNTING
777 static void *xxmalloc(int lineno, size_t size)
778 {
779 void *ptr = xmalloc((size + 0xff) & ~0xff);
780 fdprintf(2, "line %d: malloc %p\n", lineno, ptr);
781 return ptr;
782 }
783 static void *xxrealloc(int lineno, void *ptr, size_t size)
784 {
785 ptr = xrealloc(ptr, (size + 0xff) & ~0xff);
786 fdprintf(2, "line %d: realloc %p\n", lineno, ptr);
787 return ptr;
788 }
789 static char *xxstrdup(int lineno, const char *str)
790 {
791 char *ptr = xstrdup(str);
792 fdprintf(2, "line %d: strdup %p\n", lineno, ptr);
793 return ptr;
794 }
795 static void xxfree(void *ptr)
796 {
797 fdprintf(2, "free %p\n", ptr);
798 free(ptr);
799 }
800 #define xmalloc(s) xxmalloc(__LINE__, s)
801 #define xrealloc(p, s) xxrealloc(__LINE__, p, s)
802 #define xstrdup(s) xxstrdup(__LINE__, s)
803 #define free(p) xxfree(p)
804 #endif
805
806
807 /* Syntax and runtime errors. They always abort scripts.
808 * In interactive use they usually discard unparsed and/or unexecuted commands
809 * and return to the prompt.
810 * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
811 */
812 #if HUSH_DEBUG < 2
813 # define die_if_script(lineno, ...) die_if_script(__VA_ARGS__)
814 # define syntax_error(lineno, msg) syntax_error(msg)
815 # define syntax_error_at(lineno, msg) syntax_error_at(msg)
816 # define syntax_error_unterm_ch(lineno, ch) syntax_error_unterm_ch(ch)
817 # define syntax_error_unterm_str(lineno, s) syntax_error_unterm_str(s)
818 # define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch)
819 #endif
820
821 static void die_if_script(unsigned lineno, const char *fmt, ...)
822 {
823 va_list p;
824
825 #if HUSH_DEBUG >= 2
826 bb_error_msg("hush.c:%u", lineno);
827 #endif
828 va_start(p, fmt);
829 bb_verror_msg(fmt, p, NULL);
830 va_end(p);
831 if (!G_interactive_fd)
832 xfunc_die();
833 }
834
835 static void syntax_error(unsigned lineno, const char *msg)
836 {
837 if (msg)
838 die_if_script(lineno, "syntax error: %s", msg);
839 else
840 die_if_script(lineno, "syntax error", NULL);
841 }
842
843 static void syntax_error_at(unsigned lineno, const char *msg)
844 {
845 die_if_script(lineno, "syntax error at '%s'", msg);
846 }
847
848 static void syntax_error_unterm_str(unsigned lineno, const char *s)
849 {
850 die_if_script(lineno, "syntax error: unterminated %s", s);
851 }
852
853 /* It so happens that all such cases are totally fatal
854 * even if shell is interactive: EOF while looking for closing
855 * delimiter. There is nowhere to read stuff from after that,
856 * it's EOF! The only choice is to terminate.
857 */
858 static void syntax_error_unterm_ch(unsigned lineno, char ch) NORETURN;
859 static void syntax_error_unterm_ch(unsigned lineno, char ch)
860 {
861 char msg[2] = { ch, '\0' };
862 syntax_error_unterm_str(lineno, msg);
863 xfunc_die();
864 }
865
866 static void syntax_error_unexpected_ch(unsigned lineno, int ch)
867 {
868 char msg[2];
869 msg[0] = ch;
870 msg[1] = '\0';
871 die_if_script(lineno, "syntax error: unexpected %s", ch == EOF ? "EOF" : msg);
872 }
873
874 #if HUSH_DEBUG < 2
875 # undef die_if_script
876 # undef syntax_error
877 # undef syntax_error_at
878 # undef syntax_error_unterm_ch
879 # undef syntax_error_unterm_str
880 # undef syntax_error_unexpected_ch
881 #else
882 # define die_if_script(...) die_if_script(__LINE__, __VA_ARGS__)
883 # define syntax_error(msg) syntax_error(__LINE__, msg)
884 # define syntax_error_at(msg) syntax_error_at(__LINE__, msg)
885 # define syntax_error_unterm_ch(ch) syntax_error_unterm_ch(__LINE__, ch)
886 # define syntax_error_unterm_str(s) syntax_error_unterm_str(__LINE__, s)
887 # define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch)
888 #endif
889
890
891 #if ENABLE_HUSH_INTERACTIVE
892 static void cmdedit_update_prompt(void);
893 #else
894 # define cmdedit_update_prompt() ((void)0)
895 #endif
896
897
898 /* Utility functions
899 */
900 /* Replace each \x with x in place, return ptr past NUL. */
901 static char *unbackslash(char *src)
902 {
903 char *dst = src = strchrnul(src, '\\');
904 while (1) {
905 if (*src == '\\')
906 src++;
907 if ((*dst++ = *src++) == '\0')
908 break;
909 }
910 return dst;
911 }
912
913 static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
914 {
915 int i;
916 unsigned count1;
917 unsigned count2;
918 char **v;
919
920 v = strings;
921 count1 = 0;
922 if (v) {
923 while (*v) {
924 count1++;
925 v++;
926 }
927 }
928 count2 = 0;
929 v = add;
930 while (*v) {
931 count2++;
932 v++;
933 }
934 v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*));
935 v[count1 + count2] = NULL;
936 i = count2;
937 while (--i >= 0)
938 v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
939 return v;
940 }
941 #if LEAK_HUNTING
942 static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup)
943 {
944 char **ptr = add_strings_to_strings(strings, add, need_to_dup);
945 fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr);
946 return ptr;
947 }
948 #define add_strings_to_strings(strings, add, need_to_dup) \
949 xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup)
950 #endif
951
952 /* Note: takes ownership of "add" ptr (it is not strdup'ed) */
953 static char **add_string_to_strings(char **strings, char *add)
954 {
955 char *v[2];
956 v[0] = add;
957 v[1] = NULL;
958 return add_strings_to_strings(strings, v, /*dup:*/ 0);
959 }
960 #if LEAK_HUNTING
961 static char **xx_add_string_to_strings(int lineno, char **strings, char *add)
962 {
963 char **ptr = add_string_to_strings(strings, add);
964 fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr);
965 return ptr;
966 }
967 #define add_string_to_strings(strings, add) \
968 xx_add_string_to_strings(__LINE__, strings, add)
969 #endif
970
971 static void free_strings(char **strings)
972 {
973 char **v;
974
975 if (!strings)
976 return;
977 v = strings;
978 while (*v) {
979 free(*v);
980 v++;
981 }
982 free(strings);
983 }
984
985
986 /* Helpers for setting new $n and restoring them back
987 */
988 typedef struct save_arg_t {
989 char *sv_argv0;
990 char **sv_g_argv;
991 int sv_g_argc;
992 smallint sv_g_malloced;
993 } save_arg_t;
994
995 static void save_and_replace_G_args(save_arg_t *sv, char **argv)
996 {
997 int n;
998
999 sv->sv_argv0 = argv[0];
1000 sv->sv_g_argv = G.global_argv;
1001 sv->sv_g_argc = G.global_argc;
1002 sv->sv_g_malloced = G.global_args_malloced;
1003
1004 argv[0] = G.global_argv[0]; /* retain $0 */
1005 G.global_argv = argv;
1006 G.global_args_malloced = 0;
1007
1008 n = 1;
1009 while (*++argv)
1010 n++;
1011 G.global_argc = n;
1012 }
1013
1014 static void restore_G_args(save_arg_t *sv, char **argv)
1015 {
1016 char **pp;
1017
1018 if (G.global_args_malloced) {
1019 /* someone ran "set -- arg1 arg2 ...", undo */
1020 pp = G.global_argv;
1021 while (*++pp) /* note: does not free $0 */
1022 free(*pp);
1023 free(G.global_argv);
1024 }
1025 argv[0] = sv->sv_argv0;
1026 G.global_argv = sv->sv_g_argv;
1027 G.global_argc = sv->sv_g_argc;
1028 G.global_args_malloced = sv->sv_g_malloced;
1029 }
1030
1031
1032 /* Basic theory of signal handling in shell
1033 * ========================================
1034 * This does not describe what hush does, rather, it is current understanding
1035 * what it _should_ do. If it doesn't, it's a bug.
1036 * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
1037 *
1038 * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
1039 * is finished or backgrounded. It is the same in interactive and
1040 * non-interactive shells, and is the same regardless of whether
1041 * a user trap handler is installed or a shell special one is in effect.
1042 * ^C or ^Z from keyboard seems to execute "at once" because it usually
1043 * backgrounds (i.e. stops) or kills all members of currently running
1044 * pipe.
1045 *
1046 * Wait builtin in interruptible by signals for which user trap is set
1047 * or by SIGINT in interactive shell.
1048 *
1049 * Trap handlers will execute even within trap handlers. (right?)
1050 *
1051 * User trap handlers are forgotten when subshell ("(cmd)") is entered,
1052 * except for handlers set to '' (empty string).
1053 *
1054 * If job control is off, backgrounded commands ("cmd &")
1055 * have SIGINT, SIGQUIT set to SIG_IGN.
1056 *
1057 * Commands which are run in command substitution ("`cmd`")
1058 * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
1059 *
1060 * Ordinary commands have signals set to SIG_IGN/DFL as inherited
1061 * by the shell from its parent.
1062 *
1063 * Signals which differ from SIG_DFL action
1064 * (note: child (i.e., [v]forked) shell is not an interactive shell):
1065 *
1066 * SIGQUIT: ignore
1067 * SIGTERM (interactive): ignore
1068 * SIGHUP (interactive):
1069 * send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit
1070 * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
1071 * Note that ^Z is handled not by trapping SIGTSTP, but by seeing
1072 * that all pipe members are stopped. Try this in bash:
1073 * while :; do :; done - ^Z does not background it
1074 * (while :; do :; done) - ^Z backgrounds it
1075 * SIGINT (interactive): wait for last pipe, ignore the rest
1076 * of the command line, show prompt. NB: ^C does not send SIGINT
1077 * to interactive shell while shell is waiting for a pipe,
1078 * since shell is bg'ed (is not in foreground process group).
1079 * Example 1: this waits 5 sec, but does not execute ls:
1080 * "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
1081 * Example 2: this does not wait and does not execute ls:
1082 * "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1083 * Example 3: this does not wait 5 sec, but executes ls:
1084 * "sleep 5; ls -l" + press ^C
1085 *
1086 * (What happens to signals which are IGN on shell start?)
1087 * (What happens with signal mask on shell start?)
1088 *
1089 * Implementation in hush
1090 * ======================
1091 * We use in-kernel pending signal mask to determine which signals were sent.
1092 * We block all signals which we don't want to take action immediately,
1093 * i.e. we block all signals which need to have special handling as described
1094 * above, and all signals which have traps set.
1095 * After each pipe execution, we extract any pending signals via sigtimedwait()
1096 * and act on them.
1097 *
1098 * unsigned non_DFL_mask: a mask of such "special" signals
1099 * sigset_t blocked_set: current blocked signal set
1100 *
1101 * "trap - SIGxxx":
1102 * clear bit in blocked_set unless it is also in non_DFL_mask
1103 * "trap 'cmd' SIGxxx":
1104 * set bit in blocked_set (even if 'cmd' is '')
1105 * after [v]fork, if we plan to be a shell:
1106 * unblock signals with special interactive handling
1107 * (child shell is not interactive),
1108 * unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1109 * after [v]fork, if we plan to exec:
1110 * POSIX says fork clears pending signal mask in child - no need to clear it.
1111 * Restore blocked signal set to one inherited by shell just prior to exec.
1112 *
1113 * Note: as a result, we do not use signal handlers much. The only uses
1114 * are to count SIGCHLDs
1115 * and to restore tty pgrp on signal-induced exit.
1116 *
1117 * Note 2 (compat):
1118 * Standard says "When a subshell is entered, traps that are not being ignored
1119 * are set to the default actions". bash interprets it so that traps which
1120 * are set to '' (ignore) are NOT reset to defaults. We do the same.
1121 */
1122 enum {
1123 SPECIAL_INTERACTIVE_SIGS = 0
1124 | (1 << SIGTERM)
1125 | (1 << SIGINT)
1126 | (1 << SIGHUP)
1127 ,
1128 SPECIAL_JOB_SIGS = 0
1129 #if ENABLE_HUSH_JOB
1130 | (1 << SIGTTIN)
1131 | (1 << SIGTTOU)
1132 | (1 << SIGTSTP)
1133 #endif
1134 };
1135
1136 #if ENABLE_HUSH_FAST
1137 static void SIGCHLD_handler(int sig UNUSED_PARAM)
1138 {
1139 G.count_SIGCHLD++;
1140 //bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1141 }
1142 #endif
1143
1144 #if ENABLE_HUSH_JOB
1145
1146 /* After [v]fork, in child: do not restore tty pgrp on xfunc death */
1147 #define disable_restore_tty_pgrp_on_exit() (die_sleep = 0)
1148 /* After [v]fork, in parent: restore tty pgrp on xfunc death */
1149 #define enable_restore_tty_pgrp_on_exit() (die_sleep = -1)
1150
1151 /* Restores tty foreground process group, and exits.
1152 * May be called as signal handler for fatal signal
1153 * (will resend signal to itself, producing correct exit state)
1154 * or called directly with -EXITCODE.
1155 * We also call it if xfunc is exiting. */
1156 static void sigexit(int sig) NORETURN;
1157 static void sigexit(int sig)
1158 {
1159 /* Disable all signals: job control, SIGPIPE, etc. */
1160 sigprocmask_allsigs(SIG_BLOCK);
1161
1162 /* Careful: we can end up here after [v]fork. Do not restore
1163 * tty pgrp then, only top-level shell process does that */
1164 if (G_saved_tty_pgrp && getpid() == G.root_pid)
1165 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
1166
1167 /* Not a signal, just exit */
1168 if (sig <= 0)
1169 _exit(- sig);
1170
1171 kill_myself_with_sig(sig); /* does not return */
1172 }
1173 #else
1174
1175 #define disable_restore_tty_pgrp_on_exit() ((void)0)
1176 #define enable_restore_tty_pgrp_on_exit() ((void)0)
1177
1178 #endif
1179
1180 /* Restores tty foreground process group, and exits. */
1181 static void hush_exit(int exitcode) NORETURN;
1182 static void hush_exit(int exitcode)
1183 {
1184 if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) {
1185 /* Prevent recursion:
1186 * trap "echo Hi; exit" EXIT; exit
1187 */
1188 char *argv[] = { NULL, G.traps[0], NULL };
1189 G.traps[0] = NULL;
1190 G.exiting = 1;
1191 builtin_eval(argv);
1192 free(argv[1]);
1193 }
1194
1195 #if ENABLE_HUSH_JOB
1196 fflush_all();
1197 sigexit(- (exitcode & 0xff));
1198 #else
1199 exit(exitcode);
1200 #endif
1201 }
1202
1203 static int check_and_run_traps(int sig)
1204 {
1205 static const struct timespec zero_timespec = { 0, 0 };
1206 smalluint save_rcode;
1207 int last_sig = 0;
1208
1209 if (sig)
1210 goto jump_in;
1211 while (1) {
1212 sig = sigtimedwait(&G.blocked_set, NULL, &zero_timespec);
1213 if (sig <= 0)
1214 break;
1215 jump_in:
1216 last_sig = sig;
1217 if (G.traps && G.traps[sig]) {
1218 if (G.traps[sig][0]) {
1219 /* We have user-defined handler */
1220 char *argv[] = { NULL, xstrdup(G.traps[sig]), NULL };
1221 save_rcode = G.last_exitcode;
1222 builtin_eval(argv);
1223 free(argv[1]);
1224 G.last_exitcode = save_rcode;
1225 } /* else: "" trap, ignoring signal */
1226 continue;
1227 }
1228 /* not a trap: special action */
1229 switch (sig) {
1230 #if ENABLE_HUSH_FAST
1231 case SIGCHLD:
1232 G.count_SIGCHLD++;
1233 //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1234 break;
1235 #endif
1236 case SIGINT:
1237 /* Builtin was ^C'ed, make it look prettier: */
1238 bb_putchar('\n');
1239 G.flag_SIGINT = 1;
1240 break;
1241 #if ENABLE_HUSH_JOB
1242 case SIGHUP: {
1243 struct pipe *job;
1244 /* bash is observed to signal whole process groups,
1245 * not individual processes */
1246 for (job = G.job_list; job; job = job->next) {
1247 if (job->pgrp <= 0)
1248 continue;
1249 debug_printf_exec("HUPing pgrp %d\n", job->pgrp);
1250 if (kill(- job->pgrp, SIGHUP) == 0)
1251 kill(- job->pgrp, SIGCONT);
1252 }
1253 sigexit(SIGHUP);
1254 }
1255 #endif
1256 default: /* ignored: */
1257 /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
1258 break;
1259 }
1260 }
1261 return last_sig;
1262 }
1263
1264
1265 static const char *get_cwd(int force)
1266 {
1267 if (force || G.cwd == NULL) {
1268 /* xrealloc_getcwd_or_warn(arg) calls free(arg),
1269 * we must not try to free(bb_msg_unknown) */
1270 if (G.cwd == bb_msg_unknown)
1271 G.cwd = NULL;
1272 G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd);
1273 if (!G.cwd)
1274 G.cwd = bb_msg_unknown;
1275 }
1276 return G.cwd;
1277 }
1278
1279
1280 /*
1281 * Shell and environment variable support
1282 */
1283 static struct variable **get_ptr_to_local_var(const char *name)
1284 {
1285 struct variable **pp;
1286 struct variable *cur;
1287 int len;
1288
1289 len = strlen(name);
1290 pp = &G.top_var;
1291 while ((cur = *pp) != NULL) {
1292 if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
1293 return pp;
1294 pp = &cur->next;
1295 }
1296 return NULL;
1297 }
1298
1299 static struct variable *get_local_var(const char *name)
1300 {
1301 struct variable **pp = get_ptr_to_local_var(name);
1302 if (pp)
1303 return *pp;
1304 return NULL;
1305 }
1306
1307 static const char* FAST_FUNC get_local_var_value(const char *name)
1308 {
1309 struct variable **pp = get_ptr_to_local_var(name);
1310 if (pp)
1311 return strchr((*pp)->varstr, '=') + 1;
1312 if (strcmp(name, "PPID") == 0)
1313 return utoa(G.root_ppid);
1314 // bash compat: UID? EUID?
1315 #if ENABLE_HUSH_RANDOM_SUPPORT
1316 if (strcmp(name, "RANDOM") == 0) {
1317 return utoa(next_random(&G.random_gen));
1318 }
1319 #endif
1320 return NULL;
1321 }
1322
1323 /* str holds "NAME=VAL" and is expected to be malloced.
1324 * We take ownership of it.
1325 * flg_export:
1326 * 0: do not change export flag
1327 * (if creating new variable, flag will be 0)
1328 * 1: set export flag and putenv the variable
1329 * -1: clear export flag and unsetenv the variable
1330 * flg_read_only is set only when we handle -R var=val
1331 */
1332 #if !BB_MMU && ENABLE_HUSH_LOCAL
1333 /* all params are used */
1334 #elif BB_MMU && ENABLE_HUSH_LOCAL
1335 #define set_local_var(str, flg_export, local_lvl, flg_read_only) \
1336 set_local_var(str, flg_export, local_lvl)
1337 #elif BB_MMU && !ENABLE_HUSH_LOCAL
1338 #define set_local_var(str, flg_export, local_lvl, flg_read_only) \
1339 set_local_var(str, flg_export)
1340 #elif !BB_MMU && !ENABLE_HUSH_LOCAL
1341 #define set_local_var(str, flg_export, local_lvl, flg_read_only) \
1342 set_local_var(str, flg_export, flg_read_only)
1343 #endif
1344 static int set_local_var(char *str, int flg_export, int local_lvl, int flg_read_only)
1345 {
1346 struct variable **var_pp;
1347 struct variable *cur;
1348 char *eq_sign;
1349 int name_len;
1350
1351 eq_sign = strchr(str, '=');
1352 if (!eq_sign) { /* not expected to ever happen? */
1353 free(str);
1354 return -1;
1355 }
1356
1357 name_len = eq_sign - str + 1; /* including '=' */
1358 var_pp = &G.top_var;
1359 while ((cur = *var_pp) != NULL) {
1360 if (strncmp(cur->varstr, str, name_len) != 0) {
1361 var_pp = &cur->next;
1362 continue;
1363 }
1364 /* We found an existing var with this name */
1365 if (cur->flg_read_only) {
1366 #if !BB_MMU
1367 if (!flg_read_only)
1368 #endif
1369 bb_error_msg("%s: readonly variable", str);
1370 free(str);
1371 return -1;
1372 }
1373 if (flg_export == -1) { // "&& cur->flg_export" ?
1374 debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
1375 *eq_sign = '\0';
1376 unsetenv(str);
1377 *eq_sign = '=';
1378 }
1379 #if ENABLE_HUSH_LOCAL
1380 if (cur->func_nest_level < local_lvl) {
1381 /* New variable is declared as local,
1382 * and existing one is global, or local
1383 * from enclosing function.
1384 * Remove and save old one: */
1385 *var_pp = cur->next;
1386 cur->next = *G.shadowed_vars_pp;
1387 *G.shadowed_vars_pp = cur;
1388 /* bash 3.2.33(1) and exported vars:
1389 * # export z=z
1390 * # f() { local z=a; env | grep ^z; }
1391 * # f
1392 * z=a
1393 * # env | grep ^z
1394 * z=z
1395 */
1396 if (cur->flg_export)
1397 flg_export = 1;
1398 break;
1399 }
1400 #endif
1401 if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) {
1402 free_and_exp:
1403 free(str);
1404 goto exp;
1405 }
1406 if (cur->max_len != 0) {
1407 if (cur->max_len >= strlen(str)) {
1408 /* This one is from startup env, reuse space */
1409 strcpy(cur->varstr, str);
1410 goto free_and_exp;
1411 }
1412 } else {
1413 /* max_len == 0 signifies "malloced" var, which we can
1414 * (and has to) free */
1415 free(cur->varstr);
1416 }
1417 cur->max_len = 0;
1418 goto set_str_and_exp;
1419 }
1420
1421 /* Not found - create new variable struct */
1422 cur = xzalloc(sizeof(*cur));
1423 #if ENABLE_HUSH_LOCAL
1424 cur->func_nest_level = local_lvl;
1425 #endif
1426 cur->next = *var_pp;
1427 *var_pp = cur;
1428
1429 set_str_and_exp:
1430 cur->varstr = str;
1431 #if !BB_MMU
1432 cur->flg_read_only = flg_read_only;
1433 #endif
1434 exp:
1435 if (flg_export == 1)
1436 cur->flg_export = 1;
1437 if (name_len == 4 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S')
1438 cmdedit_update_prompt();
1439 if (cur->flg_export) {
1440 if (flg_export == -1) {
1441 cur->flg_export = 0;
1442 /* unsetenv was already done */
1443 } else {
1444 debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr);
1445 return putenv(cur->varstr);
1446 }
1447 }
1448 return 0;
1449 }
1450
1451 /* Used at startup and after each cd */
1452 static void set_pwd_var(int exp)
1453 {
1454 set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)),
1455 /*exp:*/ exp, /*lvl:*/ 0, /*ro:*/ 0);
1456 }
1457
1458 static int unset_local_var_len(const char *name, int name_len)
1459 {
1460 struct variable *cur;
1461 struct variable **var_pp;
1462
1463 if (!name)
1464 return EXIT_SUCCESS;
1465 var_pp = &G.top_var;
1466 while ((cur = *var_pp) != NULL) {
1467 if (strncmp(cur->varstr, name, name_len) == 0 && cur->varstr[name_len] == '=') {
1468 if (cur->flg_read_only) {
1469 bb_error_msg("%s: readonly variable", name);
1470 return EXIT_FAILURE;
1471 }
1472 *var_pp = cur->next;
1473 debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
1474 bb_unsetenv(cur->varstr);
1475 if (name_len == 3 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S')
1476 cmdedit_update_prompt();
1477 if (!cur->max_len)
1478 free(cur->varstr);
1479 free(cur);
1480 return EXIT_SUCCESS;
1481 }
1482 var_pp = &cur->next;
1483 }
1484 return EXIT_SUCCESS;
1485 }
1486
1487 static int unset_local_var(const char *name)
1488 {
1489 return unset_local_var_len(name, strlen(name));
1490 }
1491
1492 static void unset_vars(char **strings)
1493 {
1494 char **v;
1495
1496 if (!strings)
1497 return;
1498 v = strings;
1499 while (*v) {
1500 const char *eq = strchrnul(*v, '=');
1501 unset_local_var_len(*v, (int)(eq - *v));
1502 v++;
1503 }
1504 free(strings);
1505 }
1506
1507 #if ENABLE_SH_MATH_SUPPORT
1508 #define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
1509 #define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
1510 static char* FAST_FUNC endofname(const char *name)
1511 {
1512 char *p;
1513
1514 p = (char *) name;
1515 if (!is_name(*p))
1516 return p;
1517 while (*++p) {
1518 if (!is_in_name(*p))
1519 break;
1520 }
1521 return p;
1522 }
1523 #endif
1524
1525 static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val)
1526 {
1527 char *var = xasprintf("%s=%s", name, val);
1528 set_local_var(var, /*flags:*/ 0, /*lvl:*/ 0, /*ro:*/ 0);
1529 }
1530
1531
1532 /*
1533 * Helpers for "var1=val1 var2=val2 cmd" feature
1534 */
1535 static void add_vars(struct variable *var)
1536 {
1537 struct variable *next;
1538
1539 while (var) {
1540 next = var->next;
1541 var->next = G.top_var;
1542 G.top_var = var;
1543 if (var->flg_export) {
1544 debug_printf_env("%s: restoring exported '%s'\n", __func__, var->varstr);
1545 putenv(var->varstr);
1546 } else {
1547 debug_printf_env("%s: restoring variable '%s'\n", __func__, var->varstr);
1548 }
1549 var = next;
1550 }
1551 }
1552
1553 static struct variable *set_vars_and_save_old(char **strings)
1554 {
1555 char **s;
1556 struct variable *old = NULL;
1557
1558 if (!strings)
1559 return old;
1560 s = strings;
1561 while (*s) {
1562 struct variable *var_p;
1563 struct variable **var_pp;
1564 char *eq;
1565
1566 eq = strchr(*s, '=');
1567 if (eq) {
1568 *eq = '\0';
1569 var_pp = get_ptr_to_local_var(*s);
1570 *eq = '=';
1571 if (var_pp) {
1572 /* Remove variable from global linked list */
1573 var_p = *var_pp;
1574 debug_printf_env("%s: removing '%s'\n", __func__, var_p->varstr);
1575 *var_pp = var_p->next;
1576 /* Add it to returned list */
1577 var_p->next = old;
1578 old = var_p;
1579 }
1580 set_local_var(*s, /*exp:*/ 1, /*lvl:*/ 0, /*ro:*/ 0);
1581 }
1582 s++;
1583 }
1584 return old;
1585 }
1586
1587
1588 /*
1589 * in_str support
1590 */
1591 static int FAST_FUNC static_get(struct in_str *i)
1592 {
1593 int ch = *i->p++;
1594 if (ch != '\0')
1595 return ch;
1596 i->p--;
1597 return EOF;
1598 }
1599
1600 static int FAST_FUNC static_peek(struct in_str *i)
1601 {
1602 return *i->p;
1603 }
1604
1605 #if ENABLE_HUSH_INTERACTIVE
1606
1607 static void cmdedit_update_prompt(void)
1608 {
1609 if (ENABLE_FEATURE_EDITING_FANCY_PROMPT) {
1610 G.PS1 = get_local_var_value("PS1");
1611 if (G.PS1 == NULL)
1612 G.PS1 = "\\w \\$ ";
1613 G.PS2 = get_local_var_value("PS2");
1614 } else {
1615 G.PS1 = NULL;
1616 }
1617 if (G.PS2 == NULL)
1618 G.PS2 = "> ";
1619 }
1620
1621 static const char* setup_prompt_string(int promptmode)
1622 {
1623 const char *prompt_str;
1624 debug_printf("setup_prompt_string %d ", promptmode);
1625 if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT) {
1626 /* Set up the prompt */
1627 if (promptmode == 0) { /* PS1 */
1628 free((char*)G.PS1);
1629 /* bash uses $PWD value, even if it is set by user.
1630 * It uses current dir only if PWD is unset.
1631 * We always use current dir. */
1632 G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
1633 prompt_str = G.PS1;
1634 } else
1635 prompt_str = G.PS2;
1636 } else
1637 prompt_str = (promptmode == 0) ? G.PS1 : G.PS2;
1638 debug_printf("result '%s'\n", prompt_str);
1639 return prompt_str;
1640 }
1641
1642 static void get_user_input(struct in_str *i)
1643 {
1644 int r;
1645 const char *prompt_str;
1646
1647 prompt_str = setup_prompt_string(i->promptmode);
1648 #if ENABLE_FEATURE_EDITING
1649 /* Enable command line editing only while a command line
1650 * is actually being read */
1651 do {
1652 G.flag_SIGINT = 0;
1653 /* buglet: SIGINT will not make new prompt to appear _at once_,
1654 * only after <Enter>. (^C will work) */
1655 r = read_line_input(prompt_str, G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1, G.line_input_state);
1656 /* catch *SIGINT* etc (^C is handled by read_line_input) */
1657 check_and_run_traps(0);
1658 } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */
1659 i->eof_flag = (r < 0);
1660 if (i->eof_flag) { /* EOF/error detected */
1661 G.user_input_buf[0] = EOF; /* yes, it will be truncated, it's ok */
1662 G.user_input_buf[1] = '\0';
1663 }
1664 #else
1665 do {
1666 G.flag_SIGINT = 0;
1667 fputs(prompt_str, stdout);
1668 fflush_all();
1669 G.user_input_buf[0] = r = fgetc(i->file);
1670 /*G.user_input_buf[1] = '\0'; - already is and never changed */
1671 //do we need check_and_run_traps(0)? (maybe only if stdin)
1672 } while (G.flag_SIGINT);
1673 i->eof_flag = (r == EOF);
1674 #endif
1675 i->p = G.user_input_buf;
1676 }
1677
1678 #endif /* INTERACTIVE */
1679
1680 /* This is the magic location that prints prompts
1681 * and gets data back from the user */
1682 static int FAST_FUNC file_get(struct in_str *i)
1683 {
1684 int ch;
1685
1686 /* If there is data waiting, eat it up */
1687 if (i->p && *i->p) {
1688 #if ENABLE_HUSH_INTERACTIVE
1689 take_cached:
1690 #endif
1691 ch = *i->p++;
1692 if (i->eof_flag && !*i->p)
1693 ch = EOF;
1694 /* note: ch is never NUL */
1695 } else {
1696 /* need to double check i->file because we might be doing something
1697 * more complicated by now, like sourcing or substituting. */
1698 #if ENABLE_HUSH_INTERACTIVE
1699 if (G_interactive_fd && i->promptme && i->file == stdin) {
1700 do {
1701 get_user_input(i);
1702 } while (!*i->p); /* need non-empty line */
1703 i->promptmode = 1; /* PS2 */
1704 i->promptme = 0;
1705 goto take_cached;
1706 }
1707 #endif
1708 do ch = fgetc(i->file); while (ch == '\0');
1709 }
1710 debug_printf("file_get: got '%c' %d\n", ch, ch);
1711 #if ENABLE_HUSH_INTERACTIVE
1712 if (ch == '\n')
1713 i->promptme = 1;
1714 #endif
1715 return ch;
1716 }
1717
1718 /* All callers guarantee this routine will never
1719 * be used right after a newline, so prompting is not needed.
1720 */
1721 static int FAST_FUNC file_peek(struct in_str *i)
1722 {
1723 int ch;
1724 if (i->p && *i->p) {
1725 if (i->eof_flag && !i->p[1])
1726 return EOF;
1727 return *i->p;
1728 /* note: ch is never NUL */
1729 }
1730 do ch = fgetc(i->file); while (ch == '\0');
1731 i->eof_flag = (ch == EOF);
1732 i->peek_buf[0] = ch;
1733 i->peek_buf[1] = '\0';
1734 i->p = i->peek_buf;
1735 debug_printf("file_peek: got '%c' %d\n", ch, ch);
1736 return ch;
1737 }
1738
1739 static void setup_file_in_str(struct in_str *i, FILE *f)
1740 {
1741 i->peek = file_peek;
1742 i->get = file_get;
1743 #if ENABLE_HUSH_INTERACTIVE
1744 i->promptme = 1;
1745 i->promptmode = 0; /* PS1 */
1746 #endif
1747 i->file = f;
1748 i->p = NULL;
1749 }
1750
1751 static void setup_string_in_str(struct in_str *i, const char *s)
1752 {
1753 i->peek = static_peek;
1754 i->get = static_get;
1755 #if ENABLE_HUSH_INTERACTIVE
1756 i->promptme = 1;
1757 i->promptmode = 0; /* PS1 */
1758 #endif
1759 i->p = s;
1760 i->eof_flag = 0;
1761 }
1762
1763
1764 /*
1765 * o_string support
1766 */
1767 #define B_CHUNK (32 * sizeof(char*))
1768
1769 static void o_reset_to_empty_unquoted(o_string *o)
1770 {
1771 o->length = 0;
1772 o->o_quoted = 0;
1773 if (o->data)
1774 o->data[0] = '\0';
1775 }
1776
1777 static void o_free(o_string *o)
1778 {
1779 free(o->data);
1780 memset(o, 0, sizeof(*o));
1781 }
1782
1783 static ALWAYS_INLINE void o_free_unsafe(o_string *o)
1784 {
1785 free(o->data);
1786 }
1787
1788 static void o_grow_by(o_string *o, int len)
1789 {
1790 if (o->length + len > o->maxlen) {
1791 o->maxlen += (2*len > B_CHUNK ? 2*len : B_CHUNK);
1792 o->data = xrealloc(o->data, 1 + o->maxlen);
1793 }
1794 }
1795
1796 static void o_addchr(o_string *o, int ch)
1797 {
1798 debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
1799 o_grow_by(o, 1);
1800 o->data[o->length] = ch;
1801 o->length++;
1802 o->data[o->length] = '\0';
1803 }
1804
1805 static void o_addblock(o_string *o, const char *str, int len)
1806 {
1807 o_grow_by(o, len);
1808 memcpy(&o->data[o->length], str, len);
1809 o->length += len;
1810 o->data[o->length] = '\0';
1811 }
1812
1813 #if !BB_MMU
1814 static void o_addstr(o_string *o, const char *str)
1815 {
1816 o_addblock(o, str, strlen(str));
1817 }
1818 static void nommu_addchr(o_string *o, int ch)
1819 {
1820 if (o)
1821 o_addchr(o, ch);
1822 }
1823 #else
1824 # define nommu_addchr(o, str) ((void)0)
1825 #endif
1826
1827 static void o_addstr_with_NUL(o_string *o, const char *str)
1828 {
1829 o_addblock(o, str, strlen(str) + 1);
1830 }
1831
1832 static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len)
1833 {
1834 while (len) {
1835 o_addchr(o, *str);
1836 if (*str++ == '\\'
1837 && (*str != '*' && *str != '?' && *str != '[')
1838 ) {
1839 o_addchr(o, '\\');
1840 }
1841 len--;
1842 }
1843 }
1844
1845 #undef HUSH_BRACE_EXP
1846 /*
1847 * HUSH_BRACE_EXP code needs corresponding quoting on variable expansion side.
1848 * Currently, "v='{q,w}'; echo $v" erroneously expands braces in $v.
1849 * Apparently, on unquoted $v bash still does globbing
1850 * ("v='*.txt'; echo $v" prints all .txt files),
1851 * but NOT brace expansion! Thus, there should be TWO independent
1852 * quoting mechanisms on $v expansion side: one protects
1853 * $v from brace expansion, and other additionally protects "$v" against globbing.
1854 * We have only second one.
1855 */
1856
1857 #ifdef HUSH_BRACE_EXP
1858 # define MAYBE_BRACES "{}"
1859 #else
1860 # define MAYBE_BRACES ""
1861 #endif
1862
1863 /* My analysis of quoting semantics tells me that state information
1864 * is associated with a destination, not a source.
1865 */
1866 static void o_addqchr(o_string *o, int ch)
1867 {
1868 int sz = 1;
1869 char *found = strchr("*?[\\" MAYBE_BRACES, ch);
1870 if (found)
1871 sz++;
1872 o_grow_by(o, sz);
1873 if (found) {
1874 o->data[o->length] = '\\';
1875 o->length++;
1876 }
1877 o->data[o->length] = ch;
1878 o->length++;
1879 o->data[o->length] = '\0';
1880 }
1881
1882 static void o_addQchr(o_string *o, int ch)
1883 {
1884 int sz = 1;
1885 if (o->o_escape && strchr("*?[\\" MAYBE_BRACES, ch)) {
1886 sz++;
1887 o->data[o->length] = '\\';
1888 o->length++;
1889 }
1890 o_grow_by(o, sz);
1891 o->data[o->length] = ch;
1892 o->length++;
1893 o->data[o->length] = '\0';
1894 }
1895
1896 static void o_addQstr(o_string *o, const char *str, int len)
1897 {
1898 if (!o->o_escape) {
1899 o_addblock(o, str, len);
1900 return;
1901 }
1902 while (len) {
1903 char ch;
1904 int sz;
1905 int ordinary_cnt = strcspn(str, "*?[\\" MAYBE_BRACES);
1906 if (ordinary_cnt > len) /* paranoia */
1907 ordinary_cnt = len;
1908 o_addblock(o, str, ordinary_cnt);
1909 if (ordinary_cnt == len)
1910 return;
1911 str += ordinary_cnt;
1912 len -= ordinary_cnt + 1; /* we are processing + 1 char below */
1913
1914 ch = *str++;
1915 sz = 1;
1916 if (ch) { /* it is necessarily one of "*?[\\" MAYBE_BRACES */
1917 sz++;
1918 o->data[o->length] = '\\';
1919 o->length++;
1920 }
1921 o_grow_by(o, sz);
1922 o->data[o->length] = ch;
1923 o->length++;
1924 o->data[o->length] = '\0';
1925 }
1926 }
1927
1928 /* A special kind of o_string for $VAR and `cmd` expansion.
1929 * It contains char* list[] at the beginning, which is grown in 16 element
1930 * increments. Actual string data starts at the next multiple of 16 * (char*).
1931 * list[i] contains an INDEX (int!) into this string data.
1932 * It means that if list[] needs to grow, data needs to be moved higher up
1933 * but list[i]'s need not be modified.
1934 * NB: remembering how many list[i]'s you have there is crucial.
1935 * o_finalize_list() operation post-processes this structure - calculates
1936 * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
1937 */
1938 #if DEBUG_EXPAND || DEBUG_GLOB
1939 static void debug_print_list(const char *prefix, o_string *o, int n)
1940 {
1941 char **list = (char**)o->data;
1942 int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
1943 int i = 0;
1944
1945 indent();
1946 fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d\n",
1947 prefix, list, n, string_start, o->length, o->maxlen);
1948 while (i < n) {
1949 indent();
1950 fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i],
1951 o->data + (int)list[i] + string_start,
1952 o->data + (int)list[i] + string_start);
1953 i++;
1954 }
1955 if (n) {
1956 const char *p = o->data + (int)list[n - 1] + string_start;
1957 indent();
1958 fprintf(stderr, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
1959 }
1960 }
1961 #else
1962 # define debug_print_list(prefix, o, n) ((void)0)
1963 #endif
1964
1965 /* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
1966 * in list[n] so that it points past last stored byte so far.
1967 * It returns n+1. */
1968 static int o_save_ptr_helper(o_string *o, int n)
1969 {
1970 char **list = (char**)o->data;
1971 int string_start;
1972 int string_len;
1973
1974 if (!o->has_empty_slot) {
1975 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
1976 string_len = o->length - string_start;
1977 if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */
1978 debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start);
1979 /* list[n] points to string_start, make space for 16 more pointers */
1980 o->maxlen += 0x10 * sizeof(list[0]);
1981 o->data = xrealloc(o->data, o->maxlen + 1);
1982 list = (char**)o->data;
1983 memmove(list + n + 0x10, list + n, string_len);
1984 o->length += 0x10 * sizeof(list[0]);
1985 } else {
1986 debug_printf_list("list[%d]=%d string_start=%d\n",
1987 n, string_len, string_start);
1988 }
1989 } else {
1990 /* We have empty slot at list[n], reuse without growth */
1991 string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
1992 string_len = o->length - string_start;
1993 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
1994 n, string_len, string_start);
1995 o->has_empty_slot = 0;
1996 }
1997 list[n] = (char*)(ptrdiff_t)string_len;
1998 return n + 1;
1999 }
2000
2001 /* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
2002 static int o_get_last_ptr(o_string *o, int n)
2003 {
2004 char **list = (char**)o->data;
2005 int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
2006
2007 return ((int)(ptrdiff_t)list[n-1]) + string_start;
2008 }
2009
2010 #ifdef HUSH_BRACE_EXP
2011 /* There in a GNU extension, GLOB_BRACE, but it is not usable:
2012 * first, it processes even {a} (no commas), second,
2013 * I didn't manage to make it return strings when they don't match
2014 * existing files. Need to re-implement it.
2015 */
2016
2017 /* Helper */
2018 static int glob_needed(const char *s)
2019 {
2020 while (*s) {
2021 if (*s == '\\') {
2022 if (!s[1])
2023 return 0;
2024 s += 2;
2025 continue;
2026 }
2027 if (*s == '*' || *s == '[' || *s == '?' || *s == '{')
2028 return 1;
2029 s++;
2030 }
2031 return 0;
2032 }
2033 /* Return pointer to next closing brace or to comma */
2034 static const char *next_brace_sub(const char *cp)
2035 {
2036 unsigned depth = 0;
2037 cp++;
2038 while (*cp != '\0') {
2039 if (*cp == '\\') {
2040 if (*++cp == '\0')
2041 break;
2042 cp++;
2043 continue;
2044 }
2045 /*{*/ if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
2046 break;
2047 if (*cp++ == '{') /*}*/
2048 depth++;
2049 }
2050
2051 return *cp != '\0' ? cp : NULL;
2052 }
2053 /* Recursive brace globber. Note: may garble pattern[]. */
2054 static int glob_brace(char *pattern, o_string *o, int n)
2055 {
2056 char *new_pattern_buf;
2057 const char *begin;
2058 const char *next;
2059 const char *rest;
2060 const char *p;
2061 size_t rest_len;
2062
2063 debug_printf_glob("glob_brace('%s')\n", pattern);
2064
2065 begin = pattern;
2066 while (1) {
2067 if (*begin == '\0')
2068 goto simple_glob;
2069 if (*begin == '{') /*}*/ {
2070 /* Find the first sub-pattern and at the same time
2071 * find the rest after the closing brace */
2072 next = next_brace_sub(begin);
2073 if (next == NULL) {
2074 /* An illegal expression */
2075 goto simple_glob;
2076 }
2077 /*{*/ if (*next == '}') {
2078 /* "{abc}" with no commas - illegal
2079 * brace expr, disregard and skip it */
2080 begin = next + 1;
2081 continue;
2082 }
2083 break;
2084 }
2085 if (*begin == '\\' && begin[1] != '\0')
2086 begin++;
2087 begin++;
2088 }
2089 debug_printf_glob("begin:%s\n", begin);
2090 debug_printf_glob("next:%s\n", next);
2091
2092 /* Now find the end of the whole brace expression */
2093 rest = next;
2094 /*{*/ while (*rest != '}') {
2095 rest = next_brace_sub(rest);
2096 if (rest == NULL) {
2097 /* An illegal expression */
2098 goto simple_glob;
2099 }
2100 debug_printf_glob("rest:%s\n", rest);
2101 }
2102 rest_len = strlen(++rest) + 1;
2103
2104 /* We are sure the brace expression is well-formed */
2105
2106 /* Allocate working buffer large enough for our work */
2107 new_pattern_buf = xmalloc(strlen(pattern));
2108
2109 /* We have a brace expression. BEGIN points to the opening {,
2110 * NEXT points past the terminator of the first element, and REST
2111 * points past the final }. We will accumulate result names from
2112 * recursive runs for each brace alternative in the buffer using
2113 * GLOB_APPEND. */
2114
2115 p = begin + 1;
2116 while (1) {
2117 /* Construct the new glob expression */
2118 memcpy(
2119 mempcpy(
2120 mempcpy(new_pattern_buf,
2121 /* We know the prefix for all sub-patterns */
2122 pattern, begin - pattern),
2123 p, next - p),
2124 rest, rest_len);
2125
2126 /* Note: glob_brace() may garble new_pattern_buf[].
2127 * That's why we re-copy prefix every time (1st memcpy above).
2128 */
2129 n = glob_brace(new_pattern_buf, o, n);
2130 /*{*/ if (*next == '}') {
2131 /* We saw the last entry */
2132 break;
2133 }
2134 p = next + 1;
2135 next = next_brace_sub(next);
2136 }
2137 free(new_pattern_buf);
2138 return n;
2139
2140 simple_glob:
2141 {
2142 int gr;
2143 glob_t globdata;
2144
2145 memset(&globdata, 0, sizeof(globdata));
2146 gr = glob(pattern, 0, NULL, &globdata);
2147 debug_printf_glob("glob('%s'):%d\n", pattern, gr);
2148 if (gr != 0) {
2149 if (gr == GLOB_NOMATCH) {
2150 globfree(&globdata);
2151 /* NB: garbles parameter */
2152 unbackslash(pattern);
2153 o_addstr_with_NUL(o, pattern);
2154 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
2155 return o_save_ptr_helper(o, n);
2156 }
2157 if (gr == GLOB_NOSPACE)
2158 bb_error_msg_and_die(bb_msg_memory_exhausted);
2159 /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
2160 * but we didn't specify it. Paranoia again. */
2161 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
2162 }
2163 if (globdata.gl_pathv && globdata.gl_pathv[0]) {
2164 char **argv = globdata.gl_pathv;
2165 while (1) {
2166 o_addstr_with_NUL(o, *argv);
2167 n = o_save_ptr_helper(o, n);
2168 argv++;
2169 if (!*argv)
2170 break;
2171 }
2172 }
2173 globfree(&globdata);
2174 }
2175 return n;
2176 }
2177 /* Performs globbing on last list[],
2178 * saving each result as a new list[].
2179 */
2180 static int o_glob(o_string *o, int n)
2181 {
2182 char *pattern, *copy;
2183
2184 debug_printf_glob("start o_glob: n:%d o->data:%p\n", n, o->data);
2185 if (!o->data)
2186 return o_save_ptr_helper(o, n);
2187 pattern = o->data + o_get_last_ptr(o, n);
2188 debug_printf_glob("glob pattern '%s'\n", pattern);
2189 if (!glob_needed(pattern)) {
2190 /* unbackslash last string in o in place, fix length */
2191 o->length = unbackslash(pattern) - o->data;
2192 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
2193 return o_save_ptr_helper(o, n);
2194 }
2195
2196 copy = xstrdup(pattern);
2197 /* "forget" pattern in o */
2198 o->length = pattern - o->data;
2199 n = glob_brace(copy, o, n);
2200 free(copy);
2201 if (DEBUG_GLOB)
2202 debug_print_list("o_glob returning", o, n);
2203 return n;
2204 }
2205
2206 #else
2207
2208 /* Helper */
2209 static int glob_needed(const char *s)
2210 {
2211 while (*s) {
2212 if (*s == '\\') {
2213 if (!s[1])
2214 return 0;
2215 s += 2;
2216 continue;
2217 }
2218 if (*s == '*' || *s == '[' || *s == '?')
2219 return 1;
2220 s++;
2221 }
2222 return 0;
2223 }
2224 /* Performs globbing on last list[],
2225 * saving each result as a new list[].
2226 */
2227 static int o_glob(o_string *o, int n)
2228 {
2229 glob_t globdata;
2230 int gr;
2231 char *pattern;
2232
2233 debug_printf_glob("start o_glob: n:%d o->data:%p\n", n, o->data);
2234 if (!o->data)
2235 return o_save_ptr_helper(o, n);
2236 pattern = o->data + o_get_last_ptr(o, n);
2237 debug_printf_glob("glob pattern '%s'\n", pattern);
2238 if (!glob_needed(pattern)) {
2239 literal:
2240 /* unbackslash last string in o in place, fix length */
2241 o->length = unbackslash(pattern) - o->data;
2242 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
2243 return o_save_ptr_helper(o, n);
2244 }
2245
2246 memset(&globdata, 0, sizeof(globdata));
2247 /* Can't use GLOB_NOCHECK: it does not unescape the string.
2248 * If we glob "*.\*" and don't find anything, we need
2249 * to fall back to using literal "*.*", but GLOB_NOCHECK
2250 * will return "*.\*"!
2251 */
2252 gr = glob(pattern, 0, NULL, &globdata);
2253 debug_printf_glob("glob('%s'):%d\n", pattern, gr);
2254 if (gr != 0) {
2255 if (gr == GLOB_NOMATCH) {
2256 globfree(&globdata);
2257 goto literal;
2258 }
2259 if (gr == GLOB_NOSPACE)
2260 bb_error_msg_and_die(bb_msg_memory_exhausted);
2261 /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
2262 * but we didn't specify it. Paranoia again. */
2263 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
2264 }
2265 if (globdata.gl_pathv && globdata.gl_pathv[0]) {
2266 char **argv = globdata.gl_pathv;
2267 /* "forget" pattern in o */
2268 o->length = pattern - o->data;
2269 while (1) {
2270 o_addstr_with_NUL(o, *argv);
2271 n = o_save_ptr_helper(o, n);
2272 argv++;
2273 if (!*argv)
2274 break;
2275 }
2276 }
2277 globfree(&globdata);
2278 if (DEBUG_GLOB)
2279 debug_print_list("o_glob returning", o, n);
2280 return n;
2281 }
2282
2283 #endif
2284
2285 /* If o->o_glob == 1, glob the string so far remembered.
2286 * Otherwise, just finish current list[] and start new */
2287 static int o_save_ptr(o_string *o, int n)
2288 {
2289 if (o->o_glob) { /* if globbing is requested */
2290 /* If o->has_empty_slot, list[n] was already globbed
2291 * (if it was requested back then when it was filled)
2292 * so don't do that again! */
2293 if (!o->has_empty_slot)
2294 return o_glob(o, n); /* o_save_ptr_helper is inside */
2295 }
2296 return o_save_ptr_helper(o, n);
2297 }
2298
2299 /* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
2300 static char **o_finalize_list(o_string *o, int n)
2301 {
2302 char **list;
2303 int string_start;
2304
2305 n = o_save_ptr(o, n); /* force growth for list[n] if necessary */
2306 if (DEBUG_EXPAND)
2307 debug_print_list("finalized", o, n);
2308 debug_printf_expand("finalized n:%d\n", n);
2309 list = (char**)o->data;
2310 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
2311 list[--n] = NULL;
2312 while (n) {
2313 n--;
2314 list[n] = o->data + (int)(ptrdiff_t)list[n] + string_start;
2315 }
2316 return list;
2317 }
2318
2319
2320 /* Expansion can recurse */
2321 #if ENABLE_HUSH_TICK
2322 static int process_command_subs(o_string *dest, const char *s);
2323 #endif
2324 static char *expand_string_to_string(const char *str);
2325 #if BB_MMU
2326 #define parse_stream_dquoted(as_string, dest, input, dquote_end) \
2327 parse_stream_dquoted(dest, input, dquote_end)
2328 #endif
2329 static int parse_stream_dquoted(o_string *as_string,
2330 o_string *dest,
2331 struct in_str *input,
2332 int dquote_end);
2333
2334 /* expand_strvec_to_strvec() takes a list of strings, expands
2335 * all variable references within and returns a pointer to
2336 * a list of expanded strings, possibly with larger number
2337 * of strings. (Think VAR="a b"; echo $VAR).
2338 * This new list is allocated as a single malloc block.
2339 * NULL-terminated list of char* pointers is at the beginning of it,
2340 * followed by strings themself.
2341 * Caller can deallocate entire list by single free(list). */
2342
2343 /* Store given string, finalizing the word and starting new one whenever
2344 * we encounter IFS char(s). This is used for expanding variable values.
2345 * End-of-string does NOT finalize word: think about 'echo -$VAR-' */
2346 static int expand_on_ifs(o_string *output, int n, const char *str)
2347 {
2348 while (1) {
2349 int word_len = strcspn(str, G.ifs);
2350 if (word_len) {
2351 if (output->o_escape || !output->o_glob)
2352 o_addQstr(output, str, word_len);
2353 else /* protect backslashes against globbing up :) */
2354 o_addblock_duplicate_backslash(output, str, word_len);
2355 str += word_len;
2356 }
2357 if (!*str) /* EOL - do not finalize word */
2358 break;
2359 o_addchr(output, '\0');
2360 debug_print_list("expand_on_ifs", output, n);
2361 n = o_save_ptr(output, n);
2362 str += strspn(str, G.ifs); /* skip ifs chars */
2363 }
2364 debug_print_list("expand_on_ifs[1]", output, n);
2365 return n;
2366 }
2367
2368 /* Helper to expand $((...)) and heredoc body. These act as if
2369 * they are in double quotes, with the exception that they are not :).
2370 * Just the rules are similar: "expand only $var and `cmd`"
2371 *
2372 * Returns malloced string.
2373 * As an optimization, we return NULL if expansion is not needed.
2374 */
2375 static char *expand_pseudo_dquoted(const char *str)
2376 {
2377 char *exp_str;
2378 struct in_str input;
2379 o_string dest = NULL_O_STRING;
2380
2381 if (strchr(str, '$') == NULL
2382 #if ENABLE_HUSH_TICK
2383 && strchr(str, '`') == NULL
2384 #endif
2385 ) {
2386 return NULL;
2387 }
2388
2389 /* We need to expand. Example:
2390 * echo $(($a + `echo 1`)) $((1 + $((2)) ))
2391 */
2392 setup_string_in_str(&input, str);
2393 parse_stream_dquoted(NULL, &dest, &input, EOF);
2394 //bb_error_msg("'%s' -> '%s'", str, dest.data);
2395 exp_str = expand_string_to_string(dest.data);
2396 //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
2397 o_free_unsafe(&dest);
2398 return exp_str;
2399 }
2400
2401 /* Expand all variable references in given string, adding words to list[]
2402 * at n, n+1,... positions. Return updated n (so that list[n] is next one
2403 * to be filled). This routine is extremely tricky: has to deal with
2404 * variables/parameters with whitespace, $* and $@, and constructs like
2405 * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
2406 static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2407 {
2408 /* or_mask is either 0 (normal case) or 0x80 -
2409 * expansion of right-hand side of assignment == 1-element expand.
2410 * It will also do no globbing, and thus we must not backslash-quote!
2411 */
2412 char ored_ch;
2413 char *p;
2414
2415 ored_ch = 0;
2416
2417 debug_printf_expand("expand_vars_to_list: arg:'%s' or_mask:%x\n", arg, or_mask);
2418 debug_print_list("expand_vars_to_list", output, n);
2419 n = o_save_ptr(output, n);
2420 debug_print_list("expand_vars_to_list[0]", output, n);
2421
2422 while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
2423 char first_ch;
2424 int i;
2425 char *dyn_val = NULL;
2426 const char *val = NULL;
2427 #if ENABLE_HUSH_TICK
2428 o_string subst_result = NULL_O_STRING;
2429 #endif
2430 #if ENABLE_SH_MATH_SUPPORT
2431 char arith_buf[sizeof(arith_t)*3 + 2];
2432 #endif
2433 o_addblock(output, arg, p - arg);
2434 debug_print_list("expand_vars_to_list[1]", output, n);
2435 arg = ++p;
2436 p = strchr(p, SPECIAL_VAR_SYMBOL);
2437
2438 first_ch = arg[0] | or_mask; /* forced to "quoted" if or_mask = 0x80 */
2439 /* "$@" is special. Even if quoted, it can still
2440 * expand to nothing (not even an empty string) */
2441 if ((first_ch & 0x7f) != '@')
2442 ored_ch |= first_ch;
2443
2444 switch (first_ch & 0x7f) {
2445 /* Highest bit in first_ch indicates that var is double-quoted */
2446 case '$': /* pid */
2447 val = utoa(G.root_pid);
2448 break;
2449 case '!': /* bg pid */
2450 val = G.last_bg_pid ? utoa(G.last_bg_pid) : (char*)"";
2451 break;
2452 case '?': /* exitcode */
2453 val = utoa(G.last_exitcode);
2454 break;
2455 case '#': /* argc */
2456 if (arg[1] != SPECIAL_VAR_SYMBOL)
2457 /* actually, it's a ${#var} */
2458 goto case_default;
2459 val = utoa(G.global_argc ? G.global_argc-1 : 0);
2460 break;
2461 case '*':
2462 case '@':
2463 i = 1;
2464 if (!G.global_argv[i])
2465 break;
2466 ored_ch |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
2467 if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
2468 smallint sv = output->o_escape;
2469 /* unquoted var's contents should be globbed, so don't escape */
2470 output->o_escape = 0;
2471 while (G.global_argv[i]) {
2472 n = expand_on_ifs(output, n, G.global_argv[i]);
2473 debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
2474 if (G.global_argv[i++][0] && G.global_argv[i]) {
2475 /* this argv[] is not empty and not last:
2476 * put terminating NUL, start new word */
2477 o_addchr(output, '\0');
2478 debug_print_list("expand_vars_to_list[2]", output, n);
2479 n = o_save_ptr(output, n);
2480 debug_print_list("expand_vars_to_list[3]", output, n);
2481 }
2482 }
2483 output->o_escape = sv;
2484 } else
2485 /* If or_mask is nonzero, we handle assignment 'a=....$@.....'
2486 * and in this case should treat it like '$*' - see 'else...' below */
2487 if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
2488 while (1) {
2489 o_addQstr(output, G.global_argv[i], strlen(G.global_argv[i]));
2490 if (++i >= G.global_argc)
2491 break;
2492 o_addchr(output, '\0');
2493 debug_print_list("expand_vars_to_list[4]", output, n);
2494 n = o_save_ptr(output, n);
2495 }
2496 } else { /* quoted $*: add as one word */
2497 while (1) {
2498 o_addQstr(output, G.global_argv[i], strlen(G.global_argv[i]));
2499 if (!G.global_argv[++i])
2500 break;
2501 if (G.ifs[0])
2502 o_addchr(output, G.ifs[0]);
2503 }
2504 }
2505 break;
2506 case SPECIAL_VAR_SYMBOL: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
2507 /* "Empty variable", used to make "" etc to not disappear */
2508 arg++;
2509 ored_ch = 0x80;
2510 break;
2511 #if ENABLE_HUSH_TICK
2512 case '`': /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
2513 *p = '\0';
2514 arg++;
2515 /* Can't just stuff it into output o_string,
2516 * expanded result may need to be globbed
2517 * and $IFS-splitted */
2518 debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
2519 G.last_exitcode = process_command_subs(&subst_result, arg);
2520 debug_printf_subst("SUBST RES '%s'\n", subst_result.data);
2521 val = subst_result.data;
2522 goto store_val;
2523 #endif
2524 #if ENABLE_SH_MATH_SUPPORT
2525 case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */
2526 arith_eval_hooks_t hooks;
2527 arith_t res;
2528 int errcode;
2529 char *exp_str;
2530
2531 arg++; /* skip '+' */
2532 *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
2533 debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
2534
2535 exp_str = expand_pseudo_dquoted(arg);
2536 hooks.lookupvar = get_local_var_value;
2537 hooks.setvar = set_local_var_from_halves;
2538 hooks.endofname = endofname;
2539 res = arith(exp_str ? exp_str : arg, &errcode, &hooks);
2540 free(exp_str);
2541
2542 if (errcode < 0) {
2543 const char *msg = "error in arithmetic";
2544 switch (errcode) {
2545 case -3:
2546 msg = "exponent less than 0";
2547 break;
2548 case -2:
2549 msg = "divide by 0";
2550 break;
2551 case -5:
2552 msg = "expression recursion loop detected";
2553 break;
2554 }
2555 die_if_script(msg);
2556 }
2557 debug_printf_subst("ARITH RES '"arith_t_fmt"'\n", res);
2558 sprintf(arith_buf, arith_t_fmt, res);
2559 val = arith_buf;
2560 break;
2561 }
2562 #endif
2563 default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
2564 case_default: {
2565 bool exp_len = false;
2566 bool exp_null = false;
2567 char *var = arg;
2568 char exp_save = exp_save; /* for compiler */
2569 char exp_op = exp_op; /* for compiler */
2570 char *exp_word = exp_word; /* for compiler */
2571 size_t exp_off = 0;
2572
2573 *p = '\0';
2574 arg[0] = first_ch & 0x7f;
2575
2576 /* prepare for expansions */
2577 if (var[0] == '#') {
2578 /* handle length expansion ${#var} */
2579 exp_len = true;
2580 ++var;
2581 } else {
2582 /* maybe handle parameter expansion */
2583 exp_off = strcspn(var, ":-=+?%#");
2584 if (!var[exp_off])
2585 exp_off = 0;
2586 if (exp_off) {
2587 exp_save = var[exp_off];
2588 exp_null = exp_save == ':';
2589 exp_word = var + exp_off;
2590 if (exp_null)
2591 ++exp_word;
2592 exp_op = *exp_word++;
2593 var[exp_off] = '\0';
2594 }
2595 }
2596
2597 /* lookup the variable in question */
2598 if (isdigit(var[0])) {
2599 /* handle_dollar() should have vetted var for us */
2600 i = xatoi_u(var);
2601 if (i < G.global_argc)
2602 val = G.global_argv[i];
2603 /* else val remains NULL: $N with too big N */
2604 } else
2605 val = get_local_var_value(var);
2606
2607 /* handle any expansions */
2608 if (exp_len) {
2609 debug_printf_expand("expand: length of '%s' = ", val);
2610 val = utoa(val ? strlen(val) : 0);
2611 debug_printf_expand("%s\n", val);
2612 } else if (exp_off) {
2613 if (exp_op == '%' || exp_op == '#') {
2614 if (val) {
2615 /* we need to do a pattern match */
2616 bool match_at_left;
2617 char *loc;
2618 scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left);
2619 if (exp_op == *exp_word) /* ## or %% */
2620 ++exp_word;
2621 val = dyn_val = xstrdup(val);
2622 loc = scan(dyn_val, exp_word, match_at_left);
2623 if (match_at_left) /* # or ## */
2624 val = loc;
2625 else if (loc) /* % or %% and match was found */
2626 *loc = '\0';
2627 }
2628 } else {
2629 /* we need to do an expansion */
2630 int exp_test = (!val || (exp_null && !val[0]));
2631 if (exp_op == '+')
2632 exp_test = !exp_test;
2633 debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
2634 exp_null ? "true" : "false", exp_test);
2635 if (exp_test) {
2636 if (exp_op == '?') {
2637 //TODO: how interactive bash aborts expansion mid-command?
2638 /* ${var?[error_msg_if_unset]} */
2639 /* ${var:?[error_msg_if_unset_or_null]} */
2640 /* mimic bash message */
2641 die_if_script("%s: %s",
2642 var,
2643 exp_word[0] ? exp_word : "parameter null or not set"
2644 );
2645 } else {
2646 val = exp_word;
2647 }
2648
2649 if (exp_op == '=') {
2650 /* ${var=[word]} or ${var:=[word]} */
2651 if (isdigit(var[0]) || var[0] == '#') {
2652 /* mimic bash message */
2653 die_if_script("$%s: cannot assign in this way", var);
2654 val = NULL;
2655 } else {
2656 char *new_var = xasprintf("%s=%s", var, val);
2657 set_local_var(new_var, /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0);
2658 }
2659 }
2660 }
2661 }
2662
2663 var[exp_off] = exp_save;
2664 }
2665
2666 arg[0] = first_ch;
2667 #if ENABLE_HUSH_TICK
2668 store_val:
2669 #endif
2670 if (!(first_ch & 0x80)) { /* unquoted $VAR */
2671 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, output->o_escape);
2672 if (val) {
2673 /* unquoted var's contents should be globbed, so don't escape */
2674 smallint sv = output->o_escape;
2675 output->o_escape = 0;
2676 n = expand_on_ifs(output, n, val);
2677 val = NULL;
2678 output->o_escape = sv;
2679 }
2680 } else { /* quoted $VAR, val will be appended below */
2681 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, output->o_escape);
2682 }
2683 } /* default: */
2684 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
2685
2686 if (val) {
2687 o_addQstr(output, val, strlen(val));
2688 }
2689 free(dyn_val);
2690 /* Do the check to avoid writing to a const string */
2691 if (*p != SPECIAL_VAR_SYMBOL)
2692 *p = SPECIAL_VAR_SYMBOL;
2693
2694 #if ENABLE_HUSH_TICK
2695 o_free(&subst_result);
2696 #endif
2697 arg = ++p;
2698 } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
2699
2700 if (arg[0]) {
2701 debug_print_list("expand_vars_to_list[a]", output, n);
2702 /* this part is literal, and it was already pre-quoted
2703 * if needed (much earlier), do not use o_addQstr here! */
2704 o_addstr_with_NUL(output, arg);
2705 debug_print_list("expand_vars_to_list[b]", output, n);
2706 } else if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
2707 && !(ored_ch & 0x80) /* and all vars were not quoted. */
2708 ) {
2709 n--;
2710 /* allow to reuse list[n] later without re-growth */
2711 output->has_empty_slot = 1;
2712 } else {
2713 o_addchr(output, '\0');
2714 }
2715 return n;
2716 }
2717
2718 static char **expand_variables(char **argv, int or_mask)
2719 {
2720 int n;
2721 char **list;
2722 char **v;
2723 o_string output = NULL_O_STRING;
2724
2725 if (or_mask & 0x100) {
2726 output.o_escape = 1; /* protect against globbing for "$var" */
2727 /* (unquoted $var will temporarily switch it off) */
2728 output.o_glob = 1;
2729 }
2730
2731 n = 0;
2732 v = argv;
2733 while (*v) {
2734 n = expand_vars_to_list(&output, n, *v, (unsigned char)or_mask);
2735 v++;
2736 }
2737 debug_print_list("expand_variables", &output, n);
2738
2739 /* output.data (malloced in one block) gets returned in "list" */
2740 list = o_finalize_list(&output, n);
2741 debug_print_strings("expand_variables[1]", list);
2742 return list;
2743 }
2744
2745 static char **expand_strvec_to_strvec(char **argv)
2746 {
2747 return expand_variables(argv, 0x100);
2748 }
2749
2750 #if ENABLE_HUSH_BASH_COMPAT
2751 static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
2752 {
2753 return expand_variables(argv, 0x80);
2754 }
2755 #endif
2756
2757 #ifdef CMD_SINGLEWORD_NOGLOB_COND
2758 static char **expand_strvec_to_strvec_singleword_noglob_cond(char **argv)
2759 {
2760 int n;
2761 char **list;
2762 char **v;
2763 o_string output = NULL_O_STRING;
2764
2765 n = 0;
2766 v = argv;
2767 while (*v) {
2768 int is_var = is_well_formed_var_name(*v, '=');
2769 /* is_var * 0x80: singleword expansion for vars */
2770 n = expand_vars_to_list(&output, n, *v, is_var * 0x80);
2771
2772 /* Subtle! expand_vars_to_list did not glob last word yet.
2773 * It does this only when fed with further data.
2774 * Therefore we set globbing flags AFTER it, not before:
2775 */
2776
2777 /* if it is not recognizably abc=...; then: */
2778 output.o_escape = !is_var; /* protect against globbing for "$var" */
2779 /* (unquoted $var will temporarily switch it off) */
2780 output.o_glob = !is_var; /* and indeed do globbing */
2781 v++;
2782 }
2783 debug_print_list("expand_cond", &output, n);
2784
2785 /* output.data (malloced in one block) gets returned in "list" */
2786 list = o_finalize_list(&output, n);
2787 debug_print_strings("expand_cond[1]", list);
2788 return list;
2789 }
2790 #endif
2791
2792 /* Used for expansion of right hand of assignments */
2793 /* NB: should NOT do globbing! "export v=/bin/c*; env | grep ^v=" outputs
2794 * "v=/bin/c*" */
2795 static char *expand_string_to_string(const char *str)
2796 {
2797 char *argv[2], **list;
2798
2799 argv[0] = (char*)str;
2800 argv[1] = NULL;
2801 list = expand_variables(argv, 0x80); /* 0x80: singleword expansion */
2802 if (HUSH_DEBUG)
2803 if (!list[0] || list[1])
2804 bb_error_msg_and_die("BUG in varexp2");
2805 /* actually, just move string 2*sizeof(char*) bytes back */
2806 overlapping_strcpy((char*)list, list[0]);
2807 unbackslash((char*)list);
2808 debug_printf_expand("string_to_string='%s'\n", (char*)list);
2809 return (char*)list;
2810 }
2811
2812 /* Used for "eval" builtin */
2813 static char* expand_strvec_to_string(char **argv)
2814 {
2815 char **list;
2816
2817 list = expand_variables(argv, 0x80);
2818 /* Convert all NULs to spaces */
2819 if (list[0]) {
2820 int n = 1;
2821 while (list[n]) {
2822 if (HUSH_DEBUG)
2823 if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
2824 bb_error_msg_and_die("BUG in varexp3");
2825 /* bash uses ' ' regardless of $IFS contents */
2826 list[n][-1] = ' ';
2827 n++;
2828 }
2829 }
2830 overlapping_strcpy((char*)list, list[0]);
2831 debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
2832 return (char*)list;
2833 }
2834
2835 static char **expand_assignments(char **argv, int count)
2836 {
2837 int i;
2838 char **p = NULL;
2839 /* Expand assignments into one string each */
2840 for (i = 0; i < count; i++) {
2841 p = add_string_to_strings(p, expand_string_to_string(argv[i]));
2842 }
2843 return p;
2844 }
2845
2846
2847 #if BB_MMU
2848 /* never called */
2849 void re_execute_shell(char ***to_free, const char *s,
2850 char *g_argv0, char **g_argv,
2851 char **builtin_argv) NORETURN;
2852
2853 static void reset_traps_to_defaults(void)
2854 {
2855 /* This function is always called in a child shell
2856 * after fork (not vfork, NOMMU doesn't use this function).
2857 */
2858 unsigned sig;
2859 unsigned mask;
2860
2861 /* Child shells are not interactive.
2862 * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
2863 * Testcase: (while :; do :; done) + ^Z should background.
2864 * Same goes for SIGTERM, SIGHUP, SIGINT.
2865 */
2866 if (!G.traps && !(G.non_DFL_mask & SPECIAL_INTERACTIVE_SIGS))
2867 return; /* already no traps and no SPECIAL_INTERACTIVE_SIGS */
2868
2869 /* Switching off SPECIAL_INTERACTIVE_SIGS.
2870 * Stupid. It can be done with *single* &= op, but we can't use
2871 * the fact that G.blocked_set is implemented as a bitmask
2872 * in libc... */
2873 mask = (SPECIAL_INTERACTIVE_SIGS >> 1);
2874 sig = 1;
2875 while (1) {
2876 if (mask & 1) {
2877 /* Careful. Only if no trap or trap is not "" */
2878 if (!G.traps || !G.traps[sig] || G.traps[sig][0])
2879 sigdelset(&G.blocked_set, sig);
2880 }
2881 mask >>= 1;
2882 if (!mask)
2883 break;
2884 sig++;
2885 }
2886 /* Our homegrown sig mask is saner to work with :) */
2887 G.non_DFL_mask &= ~SPECIAL_INTERACTIVE_SIGS;
2888
2889 /* Resetting all traps to default except empty ones */
2890 mask = G.non_DFL_mask;
2891 if (G.traps) for (sig = 0; sig < NSIG; sig++, mask >>= 1) {
2892 if (!G.traps[sig] || !G.traps[sig][0])
2893 continue;
2894 free(G.traps[sig]);
2895 G.traps[sig] = NULL;
2896 /* There is no signal for 0 (EXIT) */
2897 if (sig == 0)
2898 continue;
2899 /* There was a trap handler, we just removed it.
2900 * But if sig still has non-DFL handling,
2901 * we should not unblock the sig. */
2902 if (mask & 1)
2903 continue;
2904 sigdelset(&G.blocked_set, sig);
2905 }
2906 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
2907 }
2908
2909 #else /* !BB_MMU */
2910
2911 static void re_execute_shell(char ***to_free, const char *s,
2912 char *g_argv0, char **g_argv,
2913 char **builtin_argv) NORETURN;
2914 static void re_execute_shell(char ***to_free, const char *s,
2915 char *g_argv0, char **g_argv,
2916 char **builtin_argv)
2917 {
2918 #define NOMMU_HACK_FMT ("-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x"))
2919 /* delims + 2 * (number of bytes in printed hex numbers) */
2920 char param_buf[sizeof(NOMMU_HACK_FMT) + 2 * (sizeof(int)*6 + sizeof(long long)*1)];
2921 char *heredoc_argv[4];
2922 struct variable *cur;
2923 # if ENABLE_HUSH_FUNCTIONS
2924 struct function *funcp;
2925 # endif
2926 char **argv, **pp;
2927 unsigned cnt;
2928 unsigned long long empty_trap_mask;
2929
2930 if (!g_argv0) { /* heredoc */
2931 argv = heredoc_argv;
2932 argv[0] = (char *) G.argv0_for_re_execing;
2933 argv[1] = (char *) "-<";
2934 argv[2] = (char *) s;
2935 argv[3] = NULL;
2936 pp = &argv[3]; /* used as pointer to empty environment */
2937 goto do_exec;
2938 }
2939
2940 cnt = 0;
2941 pp = builtin_argv;
2942 if (pp) while (*pp++)
2943 cnt++;
2944
2945 empty_trap_mask = 0;
2946 if (G.traps) {
2947 int sig;
2948 for (sig = 1; sig < NSIG; sig++) {
2949 if (G.traps[sig] && !G.traps[sig][0])
2950 empty_trap_mask |= 1LL << sig;
2951 }
2952 }
2953
2954 sprintf(param_buf, NOMMU_HACK_FMT
2955 , (unsigned) G.root_pid
2956 , (unsigned) G.root_ppid
2957 , (unsigned) G.last_bg_pid
2958 , (unsigned) G.last_exitcode
2959 , cnt
2960 , empty_trap_mask
2961 IF_HUSH_LOOPS(, G.depth_of_loop)
2962 );
2963 #undef NOMMU_HACK_FMT
2964 /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<etc...> <vars...> <funcs...>
2965 * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL
2966 */
2967 cnt += 6;
2968 for (cur = G.top_var; cur; cur = cur->next) {
2969 if (!cur->flg_export || cur->flg_read_only)
2970 cnt += 2;
2971 }
2972 # if ENABLE_HUSH_FUNCTIONS
2973 for (funcp = G.top_func; funcp; funcp = funcp->next)
2974 cnt += 3;
2975 # endif
2976 pp = g_argv;
2977 while (*pp++)
2978 cnt++;
2979 *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
2980 *pp++ = (char *) G.argv0_for_re_execing;
2981 *pp++ = param_buf;
2982 for (cur = G.top_var; cur; cur = cur->next) {
2983 if (cur->varstr == hush_version_str)
2984 continue;
2985 if (cur->flg_read_only) {
2986 *pp++ = (char *) "-R";
2987 *pp++ = cur->varstr;
2988 } else if (!cur->flg_export) {
2989 *pp++ = (char *) "-V";
2990 *pp++ = cur->varstr;
2991 }
2992 }
2993 # if ENABLE_HUSH_FUNCTIONS
2994 for (funcp = G.top_func; funcp; funcp = funcp->next) {
2995 *pp++ = (char *) "-F";
2996 *pp++ = funcp->name;
2997 *pp++ = funcp->body_as_string;
2998 }
2999 # endif
3000 /* We can pass activated traps here. Say, -Tnn:trap_string
3001 *
3002 * However, POSIX says that subshells reset signals with traps
3003 * to SIG_DFL.
3004 * I tested bash-3.2 and it not only does that with true subshells
3005 * of the form ( list ), but with any forked children shells.
3006 * I set trap "echo W" WINCH; and then tried:
3007 *
3008 * { echo 1; sleep 20; echo 2; } &
3009 * while true; do echo 1; sleep 20; echo 2; break; done &
3010 * true | { echo 1; sleep 20; echo 2; } | cat
3011 *
3012 * In all these cases sending SIGWINCH to the child shell
3013 * did not run the trap. If I add trap "echo V" WINCH;
3014 * _inside_ group (just before echo 1), it works.
3015 *
3016 * I conclude it means we don't need to pass active traps here.
3017 * Even if we would use signal handlers instead of signal masking
3018 * in order to implement trap handling,
3019 * exec syscall below resets signals to SIG_DFL for us.
3020 */
3021 *pp++ = (char *) "-c";
3022 *pp++ = (char *) s;
3023 if (builtin_argv) {
3024 while (*++builtin_argv)
3025 *pp++ = *builtin_argv;
3026 *pp++ = (char *) "";
3027 }
3028 *pp++ = g_argv0;
3029 while (*g_argv)
3030 *pp++ = *g_argv++;
3031 /* *pp = NULL; - is already there */
3032 pp = environ;
3033
3034 do_exec:
3035 debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
3036 sigprocmask(SIG_SETMASK, &G.inherited_set, NULL);
3037 execve(bb_busybox_exec_path, argv, pp);
3038 /* Fallback. Useful for init=/bin/hush usage etc */
3039 if (argv[0][0] == '/')
3040 execve(argv[0], argv, pp);
3041 xfunc_error_retval = 127;
3042 bb_error_msg_and_die("can't re-execute the shell");
3043 }
3044 #endif /* !BB_MMU */
3045
3046
3047 static void setup_heredoc(struct redir_struct *redir)
3048 {
3049 struct fd_pair pair;
3050 pid_t pid;
3051 int len, written;
3052 /* the _body_ of heredoc (misleading field name) */
3053 const char *heredoc = redir->rd_filename;
3054 char *expanded;
3055 #if !BB_MMU
3056 char **to_free;
3057 #endif
3058
3059 expanded = NULL;
3060 if (!(redir->rd_dup & HEREDOC_QUOTED)) {
3061 expanded = expand_pseudo_dquoted(heredoc);
3062 if (expanded)
3063 heredoc = expanded;
3064 }
3065 len = strlen(heredoc);
3066
3067 close(redir->rd_fd); /* often saves dup2+close in xmove_fd */
3068 xpiped_pair(pair);
3069 xmove_fd(pair.rd, redir->rd_fd);
3070
3071 /* Try writing without forking. Newer kernels have
3072 * dynamically growing pipes. Must use non-blocking write! */
3073 ndelay_on(pair.wr);
3074 while (1) {
3075 written = write(pair.wr, heredoc, len);
3076 if (written <= 0)
3077 break;
3078 len -= written;
3079 if (len == 0) {
3080 close(pair.wr);
3081 free(expanded);
3082 return;
3083 }
3084 heredoc += written;
3085 }
3086 ndelay_off(pair.wr);
3087
3088 /* Okay, pipe buffer was not big enough */
3089 /* Note: we must not create a stray child (bastard? :)
3090 * for the unsuspecting parent process. Child creates a grandchild
3091 * and exits before parent execs the process which consumes heredoc
3092 * (that exec happens after we return from this function) */
3093 #if !BB_MMU
3094 to_free = NULL;
3095 #endif
3096 pid = vfork();
3097 if (pid < 0)
3098 bb_perror_msg_and_die("vfork");
3099 if (pid == 0) {
3100 /* child */
3101 disable_restore_tty_pgrp_on_exit();
3102 pid = BB_MMU ? fork() : vfork();
3103 if (pid < 0)
3104 bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork");
3105 if (pid != 0)
3106 _exit(0);
3107 /* grandchild */
3108 close(redir->rd_fd); /* read side of the pipe */
3109 #if BB_MMU
3110 full_write(pair.wr, heredoc, len); /* may loop or block */
3111 _exit(0);
3112 #else
3113 /* Delegate blocking writes to another process */
3114 xmove_fd(pair.wr, STDOUT_FILENO);
3115 re_execute_shell(&to_free, heredoc, NULL, NULL, NULL);
3116 #endif
3117 }
3118 /* parent */
3119 #if ENABLE_HUSH_FAST
3120 G.count_SIGCHLD++;
3121 //bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
3122 #endif
3123 enable_restore_tty_pgrp_on_exit();
3124 #if !BB_MMU
3125 free(to_free);
3126 #endif
3127 close(pair.wr);
3128 free(expanded);
3129 wait(NULL); /* wait till child has died */
3130 }
3131
3132 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
3133 * and stderr if they are redirected. */
3134 static int setup_redirects(struct command *prog, int squirrel[])
3135 {
3136 int openfd, mode;
3137 struct redir_struct *redir;
3138
3139 for (redir = prog->redirects; redir; redir = redir->next) {
3140 if (redir->rd_type == REDIRECT_HEREDOC2) {
3141 /* rd_fd<<HERE case */
3142 if (squirrel && redir->rd_fd < 3
3143 && squirrel[redir->rd_fd] < 0
3144 ) {
3145 squirrel[redir->rd_fd] = dup(redir->rd_fd);
3146 }
3147 /* for REDIRECT_HEREDOC2, rd_filename holds _contents_
3148 * of the heredoc */
3149 debug_printf_parse("set heredoc '%s'\n",
3150 redir->rd_filename);
3151 setup_heredoc(redir);
3152 continue;
3153 }
3154
3155 if (redir->rd_dup == REDIRFD_TO_FILE) {
3156 /* rd_fd<*>file case (<*> is <,>,>>,<>) */
3157 char *p;
3158 if (redir->rd_filename == NULL) {
3159 /* Something went wrong in the parse.
3160 * Pretend it didn't happen */
3161 bb_error_msg("bug in redirect parse");
3162 continue;
3163 }
3164 mode = redir_table[redir->rd_type].mode;
3165 p = expand_string_to_string(redir->rd_filename);
3166 openfd = open_or_warn(p, mode);
3167 free(p);
3168 if (openfd < 0) {
3169 /* this could get lost if stderr has been redirected, but
3170 * bash and ash both lose it as well (though zsh doesn't!) */
3171 //what the above comment tries to say?
3172 return 1;
3173 }
3174 } else {
3175 /* rd_fd<*>rd_dup or rd_fd<*>- cases */
3176 openfd = redir->rd_dup;
3177 }
3178
3179 if (openfd != redir->rd_fd) {
3180 if (squirrel && redir->rd_fd < 3
3181 && squirrel[redir->rd_fd] < 0
3182 ) {
3183 squirrel[redir->rd_fd] = dup(redir->rd_fd);
3184 }
3185 if (openfd == REDIRFD_CLOSE) {
3186 /* "n>-" means "close me" */
3187 close(redir->rd_fd);
3188 } else {
3189 xdup2(openfd, redir->rd_fd);
3190 if (redir->rd_dup == REDIRFD_TO_FILE)
3191 close(openfd);
3192 }
3193 }
3194 }
3195 return 0;
3196 }
3197
3198 static void restore_redirects(int squirrel[])
3199 {
3200 int i, fd;
3201 for (i = 0; i < 3; i++) {
3202 fd = squirrel[i];
3203 if (fd != -1) {
3204 /* We simply die on error */
3205 xmove_fd(fd, i);
3206 }
3207 }
3208 }
3209
3210
3211 static void free_pipe_list(struct pipe *head);
3212
3213 /* Return code is the exit status of the pipe */
3214 static void free_pipe(struct pipe *pi)
3215 {
3216 char **p;
3217 struct command *command;
3218 struct redir_struct *r, *rnext;
3219 int a, i;
3220
3221 if (pi->stopped_cmds > 0) /* why? */
3222 return;
3223 debug_printf_clean("run pipe: (pid %d)\n", getpid());
3224 for (i = 0; i < pi->num_cmds; i++) {
3225 command = &pi->cmds[i];
3226 debug_printf_clean(" command %d:\n", i);
3227 if (command->argv) {
3228 for (a = 0, p = command->argv; *p; a++, p++) {
3229 debug_printf_clean(" argv[%d] = %s\n", a, *p);
3230 }
3231 free_strings(command->argv);
3232 command->argv = NULL;
3233 }
3234 /* not "else if": on syntax error, we may have both! */
3235 if (command->group) {
3236 debug_printf_clean(" begin group (cmd_type:%d)\n",
3237 command->cmd_type);
3238 free_pipe_list(command->group);
3239 debug_printf_clean(" end group\n");
3240 command->group = NULL;
3241 }
3242 /* else is crucial here.
3243 * If group != NULL, child_func is meaningless */
3244 #if ENABLE_HUSH_FUNCTIONS
3245 else if (command->child_func) {
3246 debug_printf_exec("cmd %p releases child func at %p\n", command, command->child_func);
3247 command->child_func->parent_cmd = NULL;
3248 }
3249 #endif
3250 #if !BB_MMU
3251 free(command->group_as_string);
3252 command->group_as_string = NULL;
3253 #endif
3254 for (r = command->redirects; r; r = rnext) {
3255 debug_printf_clean(" redirect %d%s",
3256 r->rd_fd, redir_table[r->rd_type].descrip);
3257 /* guard against the case >$FOO, where foo is unset or blank */
3258 if (r->rd_filename) {
3259 debug_printf_clean(" fname:'%s'\n", r->rd_filename);
3260 free(r->rd_filename);
3261 r->rd_filename = NULL;
3262 }
3263 debug_printf_clean(" rd_dup:%d\n", r->rd_dup);
3264 rnext = r->next;
3265 free(r);
3266 }
3267 command->redirects = NULL;
3268 }
3269 free(pi->cmds); /* children are an array, they get freed all at once */
3270 pi->cmds = NULL;
3271 #if ENABLE_HUSH_JOB
3272 free(pi->cmdtext);
3273 pi->cmdtext = NULL;
3274 #endif
3275 }
3276
3277 static void free_pipe_list(struct pipe *head)
3278 {
3279 struct pipe *pi, *next;
3280
3281 for (pi = head; pi; pi = next) {
3282 #if HAS_KEYWORDS
3283 debug_printf_clean(" pipe reserved word %d\n", pi->res_word);
3284 #endif
3285 free_pipe(pi);
3286 debug_printf_clean("pipe followup code %d\n", pi->followup);
3287 next = pi->next;
3288 /*pi->next = NULL;*/
3289 free(pi);
3290 }
3291 }
3292
3293
3294 static int run_list(struct pipe *pi);
3295 #if BB_MMU
3296 #define parse_stream(pstring, input, end_trigger) \
3297 parse_stream(input, end_trigger)
3298 #endif
3299 static struct pipe *parse_stream(char **pstring,
3300 struct in_str *input,
3301 int end_trigger);
3302 static void parse_and_run_string(const char *s);
3303
3304
3305 static char *find_in_path(const char *arg)
3306 {
3307 char *ret = NULL;
3308 const char *PATH = get_local_var_value("PATH");
3309
3310 if (!PATH)
3311 return NULL;
3312
3313 while (1) {
3314 const char *end = strchrnul(PATH, ':');
3315 int sz = end - PATH; /* must be int! */
3316
3317 free(ret);
3318 if (sz != 0) {
3319 ret = xasprintf("%.*s/%s", sz, PATH, arg);
3320 } else {
3321 /* We have xxx::yyyy in $PATH,
3322 * it means "use current dir" */
3323 ret = xstrdup(arg);
3324 }
3325 if (access(ret, F_OK) == 0)
3326 break;
3327
3328 if (*end == '\0') {
3329 free(ret);
3330 return NULL;
3331 }
3332 PATH = end + 1;
3333 }
3334
3335 return ret;
3336 }
3337
3338 static const struct built_in_command* find_builtin_helper(const char *name,
3339 const struct built_in_command *x,
3340 const struct built_in_command *end)
3341 {
3342 while (x != end) {
3343 if (strcmp(name, x->cmd) != 0) {
3344 x++;
3345 continue;
3346 }
3347 debug_printf_exec("found builtin '%s'\n", name);
3348 return x;
3349 }
3350 return NULL;
3351 }
3352 static const struct built_in_command* find_builtin1(const char *name)
3353 {
3354 return find_builtin_helper(name, bltins1, &bltins1[ARRAY_SIZE(bltins1)]);
3355 }
3356 static const struct built_in_command* find_builtin(const char *name)
3357 {
3358 const struct built_in_command *x = find_builtin1(name);
3359 if (x)
3360 return x;
3361 return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
3362 }
3363
3364 #if ENABLE_HUSH_FUNCTIONS
3365 static struct function **find_function_slot(const char *name)
3366 {
3367 struct function **funcpp = &G.top_func;
3368 while (*funcpp) {
3369 if (strcmp(name, (*funcpp)->name) == 0) {
3370 break;
3371 }
3372 funcpp = &(*funcpp)->next;
3373 }
3374 return funcpp;
3375 }
3376
3377 static const struct function *find_function(const char *name)
3378 {
3379 const struct function *funcp = *find_function_slot(name);
3380 if (funcp)
3381 debug_printf_exec("found function '%s'\n", name);
3382 return funcp;
3383 }
3384
3385 /* Note: takes ownership on name ptr */
3386 static struct function *new_function(char *name)
3387 {
3388 struct function **funcpp = find_function_slot(name);
3389 struct function *funcp = *funcpp;
3390
3391 if (funcp != NULL) {
3392 struct command *cmd = funcp->parent_cmd;
3393 debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd);
3394 if (!cmd) {
3395 debug_printf_exec("freeing & replacing function '%s'\n", funcp->name);
3396 free(funcp->name);
3397 /* Note: if !funcp->body, do not free body_as_string!
3398 * This is a special case of "-F name body" function:
3399 * body_as_string was not malloced! */
3400 if (funcp->body) {
3401 free_pipe_list(funcp->body);
3402 # if !BB_MMU
3403 free(funcp->body_as_string);
3404 # endif
3405 }
3406 } else {
3407 debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp->name);
3408 cmd->argv[0] = funcp->name;
3409 cmd->group = funcp->body;
3410 # if !BB_MMU
3411 cmd->group_as_string = funcp->body_as_string;
3412 # endif
3413 }
3414 } else {
3415 debug_printf_exec("remembering new function '%s'\n", name);
3416 funcp = *funcpp = xzalloc(sizeof(*funcp));
3417 /*funcp->next = NULL;*/
3418 }
3419
3420 funcp->name = name;
3421 return funcp;
3422 }
3423
3424 static void unset_func(const char *name)
3425 {
3426 struct function **funcpp = find_function_slot(name);
3427 struct function *funcp = *funcpp;
3428
3429 if (funcp != NULL) {
3430 debug_printf_exec("freeing function '%s'\n", funcp->name);
3431 *funcpp = funcp->next;
3432 /* funcp is unlinked now, deleting it.
3433 * Note: if !funcp->body, the function was created by
3434 * "-F name body", do not free ->body_as_string
3435 * and ->name as they were not malloced. */
3436 if (funcp->body) {
3437 free_pipe_list(funcp->body);
3438 free(funcp->name);
3439 # if !BB_MMU
3440 free(funcp->body_as_string);
3441 # endif
3442 }
3443 free(funcp);
3444 }
3445 }
3446
3447 # if BB_MMU
3448 #define exec_function(to_free, funcp, argv) \
3449 exec_function(funcp, argv)
3450 # endif
3451 static void exec_function(char ***to_free,
3452 const struct function *funcp,
3453 char **argv) NORETURN;
3454 static void exec_function(char ***to_free,
3455 const struct function *funcp,
3456 char **argv)
3457 {
3458 # if BB_MMU
3459 int n = 1;
3460
3461 argv[0] = G.global_argv[0];
3462 G.global_argv = argv;
3463 while (*++argv)
3464 n++;
3465 G.global_argc = n;
3466 /* On MMU, funcp->body is always non-NULL */
3467 n = run_list(funcp->body);
3468 fflush_all();
3469 _exit(n);
3470 # else
3471 re_execute_shell(to_free,
3472 funcp->body_as_string,
3473 G.global_argv[0],
3474 argv + 1,
3475 NULL);
3476 # endif
3477 }
3478
3479 static int run_function(const struct function *funcp, char **argv)
3480 {
3481 int rc;
3482 save_arg_t sv;
3483 smallint sv_flg;
3484
3485 save_and_replace_G_args(&sv, argv);
3486
3487 /* "we are in function, ok to use return" */
3488 sv_flg = G.flag_return_in_progress;
3489 G.flag_return_in_progress = -1;
3490 # if ENABLE_HUSH_LOCAL
3491 G.func_nest_level++;
3492 # endif
3493
3494 /* On MMU, funcp->body is always non-NULL */
3495 # if !BB_MMU
3496 if (!funcp->body) {
3497 /* Function defined by -F */
3498 parse_and_run_string(funcp->body_as_string);
3499 rc = G.last_exitcode;
3500 } else
3501 # endif
3502 {
3503 rc = run_list(funcp->body);
3504 }
3505
3506 # if ENABLE_HUSH_LOCAL
3507 {
3508 struct variable *var;
3509 struct variable **var_pp;
3510
3511 var_pp = &G.top_var;
3512 while ((var = *var_pp) != NULL) {
3513 if (var->func_nest_level < G.func_nest_level) {
3514 var_pp = &var->next;
3515 continue;
3516 }
3517 /* Unexport */
3518 if (var->flg_export)
3519 bb_unsetenv(var->varstr);
3520 /* Remove from global list */
3521 *var_pp = var->next;
3522 /* Free */
3523 if (!var->max_len)
3524 free(var->varstr);
3525 free(var);
3526 }
3527 G.func_nest_level--;
3528 }
3529 # endif
3530 G.flag_return_in_progress = sv_flg;
3531
3532 restore_G_args(&sv, argv);
3533
3534 return rc;
3535 }
3536 #endif /* ENABLE_HUSH_FUNCTIONS */
3537
3538
3539 #if BB_MMU
3540 #define exec_builtin(to_free, x, argv) \
3541 exec_builtin(x, argv)
3542 #else
3543 #define exec_builtin(to_free, x, argv) \
3544 exec_builtin(to_free, argv)
3545 #endif
3546 static void exec_builtin(char ***to_free,
3547 const struct built_in_command *x,
3548 char **argv) NORETURN;
3549 static void exec_builtin(char ***to_free,
3550 const struct built_in_command *x,
3551 char **argv)
3552 {
3553 #if BB_MMU
3554 int rcode = x->function(argv);
3555 fflush_all();
3556 _exit(rcode);
3557 #else
3558 /* On NOMMU, we must never block!
3559 * Example: { sleep 99 | read line; } & echo Ok
3560 */
3561 re_execute_shell(to_free,
3562 argv[0],
3563 G.global_argv[0],
3564 G.global_argv + 1,
3565 argv);
3566 #endif
3567 }
3568
3569
3570 static void execvp_or_die(char **argv) NORETURN;
3571 static void execvp_or_die(char **argv)
3572 {
3573 debug_printf_exec("execing '%s'\n", argv[0]);
3574 sigprocmask(SIG_SETMASK, &G.inherited_set, NULL);
3575 /* if FEATURE_SH_STANDALONE, "exec <applet_name>" should work,
3576 * therefore we should use BB_EXECVP, not execvp */
3577 BB_EXECVP(argv[0], argv);
3578 bb_perror_msg("can't execute '%s'", argv[0]);
3579 _exit(127); /* bash compat */
3580 }
3581
3582 #if BB_MMU
3583 #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
3584 pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
3585 #define pseudo_exec(nommu_save, command, argv_expanded) \
3586 pseudo_exec(command, argv_expanded)
3587 #endif
3588
3589 /* Called after [v]fork() in run_pipe, or from builtin_exec.
3590 * Never returns.
3591 * Don't exit() here. If you don't exec, use _exit instead.
3592 * The at_exit handlers apparently confuse the calling process,
3593 * in particular stdin handling. Not sure why? -- because of vfork! (vda) */
3594 static void pseudo_exec_argv(nommu_save_t *nommu_save,
3595 char **argv, int assignment_cnt,
3596 char **argv_expanded) NORETURN;
3597 static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
3598 char **argv, int assignment_cnt,
3599 char **argv_expanded)
3600 {
3601 char **new_env;
3602
3603 /* Case when we are here: ... | var=val | ... */
3604 if (!argv[assignment_cnt])
3605 _exit(EXIT_SUCCESS);
3606
3607 new_env = expand_assignments(argv, assignment_cnt);
3608 #if BB_MMU
3609 set_vars_and_save_old(new_env);
3610 free(new_env); /* optional */
3611 /* we can also destroy set_vars_and_save_old's return value,
3612 * to save memory */
3613 #else
3614 nommu_save->new_env = new_env;
3615 nommu_save->old_vars = set_vars_and_save_old(new_env);
3616 #endif
3617 if (argv_expanded) {
3618 argv = argv_expanded;
3619 } else {
3620 argv = expand_strvec_to_strvec(argv + assignment_cnt);
3621 #if !BB_MMU
3622 nommu_save->argv = argv;
3623 #endif
3624 }
3625
3626 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
3627 if (strchr(argv[0], '/') != NULL)
3628 goto skip;
3629 #endif
3630
3631 /* Check if the command matches any of the builtins.
3632 * Depending on context, this might be redundant. But it's
3633 * easier to waste a few CPU cycles than it is to figure out
3634 * if this is one of those cases.
3635 */
3636 {
3637 /* On NOMMU, it is more expensive to re-execute shell
3638 * just in order to run echo or test builtin.
3639 * It's better to skip it here and run corresponding
3640 * non-builtin later. */
3641 const struct built_in_command *x;
3642 x = BB_MMU ? find_builtin(argv[0]) : find_builtin1(argv[0]);
3643 if (x) {
3644 exec_builtin(&nommu_save->argv_from_re_execing, x, argv);
3645 }
3646 }
3647 #if ENABLE_HUSH_FUNCTIONS
3648 /* Check if the command matches any functions */
3649 {
3650 const struct function *funcp = find_function(argv[0]);
3651 if (funcp) {
3652 exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
3653 }
3654 }
3655 #endif
3656
3657 #if ENABLE_FEATURE_SH_STANDALONE
3658 /* Check if the command matches any busybox applets */
3659 {
3660 int a = find_applet_by_name(argv[0]);
3661 if (a >= 0) {
3662 # if BB_MMU /* see above why on NOMMU it is not allowed */
3663 if (APPLET_IS_NOEXEC(a)) {
3664 debug_printf_exec("running applet '%s'\n", argv[0]);
3665 run_applet_no_and_exit(a, argv);
3666 }
3667 # endif
3668 /* Re-exec ourselves */
3669 debug_printf_exec("re-execing applet '%s'\n", argv[0]);
3670 sigprocmask(SIG_SETMASK, &G.inherited_set, NULL);
3671 execv(bb_busybox_exec_path, argv);
3672 /* If they called chroot or otherwise made the binary no longer
3673 * executable, fall through */
3674 }
3675 }
3676 #endif
3677
3678 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
3679 skip:
3680 #endif
3681 execvp_or_die(argv);
3682 }
3683
3684 /* Called after [v]fork() in run_pipe
3685 */
3686 static void pseudo_exec(nommu_save_t *nommu_save,
3687 struct command *command,
3688 char **argv_expanded) NORETURN;
3689 static void pseudo_exec(nommu_save_t *nommu_save,
3690 struct command *command,
3691 char **argv_expanded)
3692 {
3693 if (command->argv) {
3694 pseudo_exec_argv(nommu_save, command->argv,
3695 command->assignment_cnt, argv_expanded);
3696 }
3697
3698 if (command->group) {
3699 /* Cases when we are here:
3700 * ( list )
3701 * { list } &
3702 * ... | ( list ) | ...
3703 * ... | { list } | ...
3704 */
3705 #if BB_MMU
3706 int rcode;
3707 debug_printf_exec("pseudo_exec: run_list\n");
3708 reset_traps_to_defaults();
3709 rcode = run_list(command->group);
3710 /* OK to leak memory by not calling free_pipe_list,
3711 * since this process is about to exit */
3712 _exit(rcode);
3713 #else
3714 re_execute_shell(&nommu_save->argv_from_re_execing,
3715 command->group_as_string,
3716 G.global_argv[0],
3717 G.global_argv + 1,
3718 NULL);
3719 #endif
3720 }
3721
3722 /* Case when we are here: ... | >file */
3723 debug_printf_exec("pseudo_exec'ed null command\n");
3724 _exit(EXIT_SUCCESS);
3725 }
3726
3727 #if ENABLE_HUSH_JOB
3728 static const char *get_cmdtext(struct pipe *pi)
3729 {
3730 char **argv;
3731 char *p;
3732 int len;
3733
3734 /* This is subtle. ->cmdtext is created only on first backgrounding.
3735 * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
3736 * On subsequent bg argv is trashed, but we won't use it */
3737 if (pi->cmdtext)
3738 return pi->cmdtext;
3739 argv = pi->cmds[0].argv;
3740 if (!argv || !argv[0]) {
3741 pi->cmdtext = xzalloc(1);
3742 return pi->cmdtext;
3743 }
3744
3745 len = 0;
3746 do {
3747 len += strlen(*argv) + 1;
3748 } while (*++argv);
3749 p = xmalloc(len);
3750 pi->cmdtext = p;
3751 argv = pi->cmds[0].argv;
3752 do {
3753 len = strlen(*argv);
3754 memcpy(p, *argv, len);
3755 p += len;
3756 *p++ = ' ';
3757 } while (*++argv);
3758 p[-1] = '\0';
3759 return pi->cmdtext;
3760 }
3761
3762 static void insert_bg_job(struct pipe *pi)
3763 {
3764 struct pipe *job, **jobp;
3765 int i;
3766
3767 /* Linear search for the ID of the job to use */
3768 pi->jobid = 1;
3769 for (job = G.job_list; job; job = job->next)
3770 if (job->jobid >= pi->jobid)
3771 pi->jobid = job->jobid + 1;
3772
3773 /* Add job to the list of running jobs */
3774 jobp = &G.job_list;
3775 while ((job = *jobp) != NULL)
3776 jobp = &job->next;
3777 job = *jobp = xmalloc(sizeof(*job));
3778
3779 *job = *pi; /* physical copy */
3780 job->next = NULL;
3781 job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds);
3782 /* Cannot copy entire pi->cmds[] vector! This causes double frees */
3783 for (i = 0; i < pi->num_cmds; i++) {
3784 job->cmds[i].pid = pi->cmds[i].pid;
3785 /* all other fields are not used and stay zero */
3786 }
3787 job->cmdtext = xstrdup(get_cmdtext(pi));
3788
3789 if (G_interactive_fd)
3790 printf("[%d] %d %s\n", job->jobid, job->cmds[0].pid, job->cmdtext);
3791 /* Last command's pid goes to $! */
3792 G.last_bg_pid = job->cmds[job->num_cmds - 1].pid;
3793 G.last_jobid = job->jobid;
3794 }
3795
3796 static void remove_bg_job(struct pipe *pi)
3797 {
3798 struct pipe *prev_pipe;
3799
3800 if (pi == G.job_list) {
3801 G.job_list = pi->next;
3802 } else {
3803 prev_pipe = G.job_list;
3804 while (prev_pipe->next != pi)
3805 prev_pipe = prev_pipe->next;
3806 prev_pipe->next = pi->next;
3807 }
3808 if (G.job_list)
3809 G.last_jobid = G.job_list->jobid;
3810 else
3811 G.last_jobid = 0;
3812 }
3813
3814 /* Remove a backgrounded job */
3815 static void delete_finished_bg_job(struct pipe *pi)
3816 {
3817 remove_bg_job(pi);
3818 pi->stopped_cmds = 0;
3819 free_pipe(pi);
3820 free(pi);
3821 }
3822 #endif /* JOB */
3823
3824 /* Check to see if any processes have exited -- if they
3825 * have, figure out why and see if a job has completed */
3826 static int checkjobs(struct pipe* fg_pipe)
3827 {
3828 int attributes;
3829 int status;
3830 #if ENABLE_HUSH_JOB
3831 struct pipe *pi;
3832 #endif
3833 pid_t childpid;
3834 int rcode = 0;
3835
3836 debug_printf_jobs("checkjobs %p\n", fg_pipe);
3837
3838 attributes = WUNTRACED;
3839 if (fg_pipe == NULL)
3840 attributes |= WNOHANG;
3841
3842 errno = 0;
3843 #if ENABLE_HUSH_FAST
3844 if (G.handled_SIGCHLD == G.count_SIGCHLD) {
3845 //bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p",
3846 //getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe);
3847 /* There was neither fork nor SIGCHLD since last waitpid */
3848 /* Avoid doing waitpid syscall if possible */
3849 if (!G.we_have_children) {
3850 errno = ECHILD;
3851 return -1;
3852 }
3853 if (fg_pipe == NULL) { /* is WNOHANG set? */
3854 /* We have children, but they did not exit
3855 * or stop yet (we saw no SIGCHLD) */
3856 return 0;
3857 }
3858 /* else: !WNOHANG, waitpid will block, can't short-circuit */
3859 }
3860 #endif
3861
3862 /* Do we do this right?
3863 * bash-3.00# sleep 20 | false
3864 * <ctrl-Z pressed>
3865 * [3]+ Stopped sleep 20 | false
3866 * bash-3.00# echo $?
3867 * 1 <========== bg pipe is not fully done, but exitcode is already known!
3868 * [hush 1.14.0: yes we do it right]
3869 */
3870 wait_more:
3871 while (1) {
3872 int i;
3873 int dead;
3874
3875 #if ENABLE_HUSH_FAST
3876 i = G.count_SIGCHLD;
3877 #endif
3878 childpid = waitpid(-1, &status, attributes);
3879 if (childpid <= 0) {
3880 if (childpid && errno != ECHILD)
3881 bb_perror_msg("waitpid");
3882 #if ENABLE_HUSH_FAST
3883 else { /* Until next SIGCHLD, waitpid's are useless */
3884 G.we_have_children = (childpid == 0);
3885 G.handled_SIGCHLD = i;
3886 //bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
3887 }
3888 #endif
3889 break;
3890 }
3891 dead = WIFEXITED(status) || WIFSIGNALED(status);
3892
3893 #if DEBUG_JOBS
3894 if (WIFSTOPPED(status))
3895 debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
3896 childpid, WSTOPSIG(status), WEXITSTATUS(status));
3897 if (WIFSIGNALED(status))
3898 debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
3899 childpid, WTERMSIG(status), WEXITSTATUS(status));
3900 if (WIFEXITED(status))
3901 debug_printf_jobs("pid %d exited, exitcode %d\n",
3902 childpid, WEXITSTATUS(status));
3903 #endif
3904 /* Were we asked to wait for fg pipe? */
3905 if (fg_pipe) {
3906 for (i = 0; i < fg_pipe->num_cmds; i++) {
3907 debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
3908 if (fg_pipe->cmds[i].pid != childpid)
3909 continue;
3910 if (dead) {
3911 fg_pipe->cmds[i].pid = 0;
3912 fg_pipe->alive_cmds--;
3913 if (i == fg_pipe->num_cmds - 1) {
3914 /* last process gives overall exitstatus */
3915 rcode = WEXITSTATUS(status);
3916 /* bash prints killer signal's name for *last*
3917 * process in pipe (prints just newline for SIGINT).
3918 * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT)
3919 */
3920 if (WIFSIGNALED(status)) {
3921 int sig = WTERMSIG(status);
3922 printf("%s\n", sig == SIGINT ? "" : get_signame(sig));
3923 /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here?
3924 * Maybe we need to use sig | 128? */
3925 rcode = sig + 128;
3926 }
3927 IF_HAS_KEYWORDS(if (fg_pipe->pi_inverted) rcode = !rcode;)
3928 }
3929 } else {
3930 fg_pipe->cmds[i].is_stopped = 1;
3931 fg_pipe->stopped_cmds++;
3932 }
3933 debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
3934 fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
3935 if (fg_pipe->alive_cmds - fg_pipe->stopped_cmds <= 0) {
3936 /* All processes in fg pipe have exited or stopped */
3937 /* Note: *non-interactive* bash does not continue if all processes in fg pipe
3938 * are stopped. Testcase: "cat | cat" in a script (not on command line!)
3939 * and "killall -STOP cat" */
3940 if (G_interactive_fd) {
3941 #if ENABLE_HUSH_JOB
3942 if (fg_pipe->alive_cmds)
3943 insert_bg_job(fg_pipe);
3944 #endif
3945 return rcode;
3946 }
3947 if (!fg_pipe->alive_cmds)
3948 return rcode;
3949 }
3950 /* There are still running processes in the fg pipe */
3951 goto wait_more; /* do waitpid again */
3952 }
3953 /* it wasnt fg_pipe, look for process in bg pipes */
3954 }
3955
3956 #if ENABLE_HUSH_JOB
3957 /* We asked to wait for bg or orphaned children */
3958 /* No need to remember exitcode in this case */
3959 for (pi = G.job_list; pi; pi = pi->next) {
3960 for (i = 0; i < pi->num_cmds; i++) {
3961 if (pi->cmds[i].pid == childpid)
3962 goto found_pi_and_prognum;
3963 }
3964 }
3965 /* Happens when shell is used as init process (init=/bin/sh) */
3966 debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
3967 continue; /* do waitpid again */
3968
3969 found_pi_and_prognum:
3970 if (dead) {
3971 /* child exited */
3972 pi->cmds[i].pid = 0;
3973 pi->alive_cmds--;
3974 if (!pi->alive_cmds) {
3975 if (G_interactive_fd)
3976 printf(JOB_STATUS_FORMAT, pi->jobid,
3977 "Done", pi->cmdtext);
3978 delete_finished_bg_job(pi);
3979 }
3980 } else {
3981 /* child stopped */
3982 pi->cmds[i].is_stopped = 1;
3983 pi->stopped_cmds++;
3984 }
3985 #endif
3986 } /* while (waitpid succeeds)... */
3987
3988 return rcode;
3989 }
3990
3991 #if ENABLE_HUSH_JOB
3992 static int checkjobs_and_fg_shell(struct pipe* fg_pipe)
3993 {
3994 pid_t p;
3995 int rcode = checkjobs(fg_pipe);
3996 if (G_saved_tty_pgrp) {
3997 /* Job finished, move the shell to the foreground */
3998 p = getpgrp(); /* our process group id */
3999 debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p);
4000 tcsetpgrp(G_interactive_fd, p);
4001 }
4002 return rcode;
4003 }
4004 #endif
4005
4006 /* Start all the jobs, but don't wait for anything to finish.
4007 * See checkjobs().
4008 *
4009 * Return code is normally -1, when the caller has to wait for children
4010 * to finish to determine the exit status of the pipe. If the pipe
4011 * is a simple builtin command, however, the action is done by the
4012 * time run_pipe returns, and the exit code is provided as the
4013 * return value.
4014 *
4015 * Returns -1 only if started some children. IOW: we have to
4016 * mask out retvals of builtins etc with 0xff!
4017 *
4018 * The only case when we do not need to [v]fork is when the pipe
4019 * is single, non-backgrounded, non-subshell command. Examples:
4020 * cmd ; ... { list } ; ...
4021 * cmd && ... { list } && ...
4022 * cmd || ... { list } || ...
4023 * If it is, then we can run cmd as a builtin, NOFORK [do we do this?],
4024 * or (if SH_STANDALONE) an applet, and we can run the { list }
4025 * with run_list. If it isn't one of these, we fork and exec cmd.
4026 *
4027 * Cases when we must fork:
4028 * non-single: cmd | cmd
4029 * backgrounded: cmd & { list } &
4030 * subshell: ( list ) [&]
4031 */
4032 static NOINLINE int run_pipe(struct pipe *pi)
4033 {
4034 static const char *const null_ptr = NULL;
4035 int i;
4036 int nextin;
4037 struct command *command;
4038 char **argv_expanded;
4039 char **argv;
4040 char *p;
4041 /* it is not always needed, but we aim to smaller code */
4042 int squirrel[] = { -1, -1, -1 };
4043 int rcode;
4044
4045 debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds);
4046 debug_enter();
4047
4048 IF_HUSH_JOB(pi->pgrp = -1;)
4049 pi->stopped_cmds = 0;
4050 command = &(pi->cmds[0]);
4051 argv_expanded = NULL;
4052
4053 if (pi->num_cmds != 1
4054 || pi->followup == PIPE_BG
4055 || command->cmd_type == CMD_SUBSHELL
4056 ) {
4057 goto must_fork;
4058 }
4059
4060 pi->alive_cmds = 1;
4061
4062 debug_printf_exec(": group:%p argv:'%s'\n",
4063 command->group, command->argv ? command->argv[0] : "NONE");
4064
4065 if (command->group) {
4066 #if ENABLE_HUSH_FUNCTIONS
4067 if (command->cmd_type == CMD_FUNCDEF) {
4068 /* "executing" func () { list } */
4069 struct function *funcp;
4070
4071 funcp = new_function(command->argv[0]);
4072 /* funcp->name is already set to argv[0] */
4073 funcp->body = command->group;
4074 # if !BB_MMU
4075 funcp->body_as_string = command->group_as_string;
4076 command->group_as_string = NULL;
4077 # endif
4078 command->group = NULL;
4079 command->argv[0] = NULL;
4080 debug_printf_exec("cmd %p has child func at %p\n", command, funcp);
4081 funcp->parent_cmd = command;
4082 command->child_func = funcp;
4083
4084 debug_printf_exec("run_pipe: return EXIT_SUCCESS\n");
4085 debug_leave();
4086 return EXIT_SUCCESS;
4087 }
4088 #endif
4089 /* { list } */
4090 debug_printf("non-subshell group\n");
4091 rcode = 1; /* exitcode if redir failed */
4092 if (setup_redirects(command, squirrel) == 0) {
4093 debug_printf_exec(": run_list\n");
4094 rcode = run_list(command->group) & 0xff;
4095 }
4096 restore_redirects(squirrel);
4097 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
4098 debug_leave();
4099 debug_printf_exec("run_pipe: return %d\n", rcode);
4100 return rcode;
4101 }
4102
4103 argv = command->argv ? command->argv : (char **) &null_ptr;
4104 {
4105 const struct built_in_command *x;
4106 #if ENABLE_HUSH_FUNCTIONS
4107 const struct function *funcp;
4108 #else
4109 enum { funcp = 0 };
4110 #endif
4111 char **new_env = NULL;
4112 struct variable *old_vars = NULL;
4113
4114 if (argv[command->assignment_cnt] == NULL) {
4115 /* Assignments, but no command */
4116 /* Ensure redirects take effect. Try "a=t >file" */
4117 rcode = setup_redirects(command, squirrel);
4118 restore_redirects(squirrel);
4119 /* Set shell variables */
4120 while (*argv) {
4121 p = expand_string_to_string(*argv);
4122 debug_printf_exec("set shell var:'%s'->'%s'\n",
4123 *argv, p);
4124 set_local_var(p, /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0);
4125 argv++;
4126 }
4127 /* Do we need to flag set_local_var() errors?
4128 * "assignment to readonly var" and "putenv error"
4129 */
4130 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
4131 debug_leave();
4132 debug_printf_exec("run_pipe: return %d\n", rcode);
4133 return rcode;
4134 }
4135
4136 /* Expand the rest into (possibly) many strings each */
4137 if (0) {}
4138 #if ENABLE_HUSH_BASH_COMPAT
4139 else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
4140 argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
4141 }
4142 #endif
4143 #ifdef CMD_SINGLEWORD_NOGLOB_COND
4144 else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB_COND) {
4145 argv_expanded = expand_strvec_to_strvec_singleword_noglob_cond(argv + command->assignment_cnt);
4146
4147 }
4148 #endif
4149 else {
4150 argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
4151 }
4152
4153 /* if someone gives us an empty string: `cmd with empty output` */
4154 if (!argv_expanded[0]) {
4155 free(argv_expanded);
4156 debug_leave();
4157 return G.last_exitcode;
4158 }
4159
4160 x = find_builtin(argv_expanded[0]);
4161 #if ENABLE_HUSH_FUNCTIONS
4162 funcp = NULL;
4163 if (!x)
4164 funcp = find_function(argv_expanded[0]);
4165 #endif
4166 if (x || funcp) {
4167 if (!funcp) {
4168 if (x->function == builtin_exec && argv_expanded[1] == NULL) {
4169 debug_printf("exec with redirects only\n");
4170 rcode = setup_redirects(command, NULL);
4171 goto clean_up_and_ret1;
4172 }
4173 }
4174 /* setup_redirects acts on file descriptors, not FILEs.
4175 * This is perfect for work that comes after exec().
4176 * Is it really safe for inline use? Experimentally,
4177 * things seem to work. */
4178 rcode = setup_redirects(command, squirrel);
4179 if (rcode == 0) {
4180 new_env = expand_assignments(argv, command->assignment_cnt);
4181 old_vars = set_vars_and_save_old(new_env);
4182 if (!funcp) {
4183 debug_printf_exec(": builtin '%s' '%s'...\n",
4184 x->cmd, argv_expanded[1]);
4185 rcode = x->function(argv_expanded) & 0xff;
4186 fflush_all();
4187 }
4188 #if ENABLE_HUSH_FUNCTIONS
4189 else {
4190 # if ENABLE_HUSH_LOCAL
4191 struct variable **sv;
4192 sv = G.shadowed_vars_pp;
4193 G.shadowed_vars_pp = &old_vars;
4194 # endif
4195 debug_printf_exec(": function '%s' '%s'...\n",
4196 funcp->name, argv_expanded[1]);
4197 rcode = run_function(funcp, argv_expanded) & 0xff;
4198 # if ENABLE_HUSH_LOCAL
4199 G.shadowed_vars_pp = sv;
4200 # endif
4201 }
4202 #endif
4203 }
4204 #if ENABLE_FEATURE_SH_STANDALONE
4205 clean_up_and_ret:
4206 #endif
4207 restore_redirects(squirrel);
4208 unset_vars(new_env);
4209 add_vars(old_vars);
4210 clean_up_and_ret1:
4211 free(argv_expanded);
4212 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
4213 debug_leave();
4214 debug_printf_exec("run_pipe return %d\n", rcode);
4215 return rcode;
4216 }
4217
4218 #if ENABLE_FEATURE_SH_STANDALONE
4219 i = find_applet_by_name(argv_expanded[0]);
4220 if (i >= 0 && APPLET_IS_NOFORK(i)) {
4221 rcode = setup_redirects(command, squirrel);
4222 if (rcode == 0) {
4223 new_env = expand_assignments(argv, command->assignment_cnt);
4224 old_vars = set_vars_and_save_old(new_env);
4225 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
4226 argv_expanded[0], argv_expanded[1]);
4227 rcode = run_nofork_applet(i, argv_expanded);
4228 }
4229 goto clean_up_and_ret;
4230 }
4231 #endif
4232 /* It is neither builtin nor applet. We must fork. */
4233 }
4234
4235 must_fork:
4236 /* NB: argv_expanded may already be created, and that
4237 * might include `cmd` runs! Do not rerun it! We *must*
4238 * use argv_expanded if it's non-NULL */
4239
4240 /* Going to fork a child per each pipe member */
4241 pi->alive_cmds = 0;
4242 nextin = 0;
4243
4244 for (i = 0; i < pi->num_cmds; i++) {
4245 struct fd_pair pipefds;
4246 #if !BB_MMU
4247 volatile nommu_save_t nommu_save;
4248 nommu_save.new_env = NULL;
4249 nommu_save.old_vars = NULL;
4250 nommu_save.argv = NULL;
4251 nommu_save.argv_from_re_execing = NULL;
4252 #endif
4253 command = &(pi->cmds[i]);
4254 if (command->argv) {
4255 debug_printf_exec(": pipe member '%s' '%s'...\n",
4256 command->argv[0], command->argv[1]);
4257 } else {
4258 debug_printf_exec(": pipe member with no argv\n");
4259 }
4260
4261 /* pipes are inserted between pairs of commands */
4262 pipefds.rd = 0;
4263 pipefds.wr = 1;
4264 if ((i + 1) < pi->num_cmds)
4265 xpiped_pair(pipefds);
4266
4267 command->pid = BB_MMU ? fork() : vfork();
4268 if (!command->pid) { /* child */
4269 #if ENABLE_HUSH_JOB
4270 disable_restore_tty_pgrp_on_exit();
4271 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
4272
4273 /* Every child adds itself to new process group
4274 * with pgid == pid_of_first_child_in_pipe */
4275 if (G.run_list_level == 1 && G_interactive_fd) {
4276 pid_t pgrp;
4277 pgrp = pi->pgrp;
4278 if (pgrp < 0) /* true for 1st process only */
4279 pgrp = getpid();
4280 if (setpgid(0, pgrp) == 0
4281 && pi->followup != PIPE_BG
4282 && G_saved_tty_pgrp /* we have ctty */
4283 ) {
4284 /* We do it in *every* child, not just first,
4285 * to avoid races */
4286 tcsetpgrp(G_interactive_fd, pgrp);
4287 }
4288 }
4289 #endif
4290 if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) {
4291 /* 1st cmd in backgrounded pipe
4292 * should have its stdin /dev/null'ed */
4293 close(0);
4294 if (open(bb_dev_null, O_RDONLY))
4295 xopen("/", O_RDONLY);
4296 } else {
4297 xmove_fd(nextin, 0);
4298 }
4299 xmove_fd(pipefds.wr, 1);
4300 if (pipefds.rd > 1)
4301 close(pipefds.rd);
4302 /* Like bash, explicit redirects override pipes,
4303 * and the pipe fd is available for dup'ing. */
4304 if (setup_redirects(command, NULL))
4305 _exit(1);
4306
4307 /* Restore default handlers just prior to exec */
4308 /*signal(SIGCHLD, SIG_DFL); - so far we don't have any handlers */
4309
4310 /* Stores to nommu_save list of env vars putenv'ed
4311 * (NOMMU, on MMU we don't need that) */
4312 /* cast away volatility... */
4313 pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded);
4314 /* pseudo_exec() does not return */
4315 }
4316
4317 /* parent or error */
4318 #if ENABLE_HUSH_FAST
4319 G.count_SIGCHLD++;
4320 //bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
4321 #endif
4322 enable_restore_tty_pgrp_on_exit();
4323 #if !BB_MMU
4324 /* Clean up after vforked child */
4325 free(nommu_save.argv);
4326 free(nommu_save.argv_from_re_execing);
4327 unset_vars(nommu_save.new_env);
4328 add_vars(nommu_save.old_vars);
4329 #endif
4330 free(argv_expanded);
4331 argv_expanded = NULL;
4332 if (command->pid < 0) { /* [v]fork failed */
4333 /* Clearly indicate, was it fork or vfork */
4334 bb_perror_msg(BB_MMU ? "fork" : "vfork");
4335 } else {
4336 pi->alive_cmds++;
4337 #if ENABLE_HUSH_JOB
4338 /* Second and next children need to know pid of first one */
4339 if (pi->pgrp < 0)
4340 pi->pgrp = command->pid;
4341 #endif
4342 }
4343
4344 if (i)
4345 close(nextin);
4346 if ((i + 1) < pi->num_cmds)
4347 close(pipefds.wr);
4348 /* Pass read (output) pipe end to next iteration */
4349 nextin = pipefds.rd;
4350 }
4351
4352 if (!pi->alive_cmds) {
4353 debug_leave();
4354 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
4355 return 1;
4356 }
4357
4358 debug_leave();
4359 debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds);
4360 return -1;
4361 }
4362
4363 #ifndef debug_print_tree
4364 static void debug_print_tree(struct pipe *pi, int lvl)
4365 {
4366 static const char *const PIPE[] = {
4367 [PIPE_SEQ] = "SEQ",
4368 [PIPE_AND] = "AND",
4369 [PIPE_OR ] = "OR" ,
4370 [PIPE_BG ] = "BG" ,
4371 };
4372 static const char *RES[] = {
4373 [RES_NONE ] = "NONE" ,
4374 # if ENABLE_HUSH_IF
4375 [RES_IF ] = "IF" ,
4376 [RES_THEN ] = "THEN" ,
4377 [RES_ELIF ] = "ELIF" ,
4378 [RES_ELSE ] = "ELSE" ,
4379 [RES_FI ] = "FI" ,
4380 # endif
4381 # if ENABLE_HUSH_LOOPS
4382 [RES_FOR ] = "FOR" ,
4383 [RES_WHILE] = "WHILE",
4384 [RES_UNTIL] = "UNTIL",
4385 [RES_DO ] = "DO" ,
4386 [RES_DONE ] = "DONE" ,
4387 # endif
4388 # if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
4389 [RES_IN ] = "IN" ,
4390 # endif
4391 # if ENABLE_HUSH_CASE
4392 [RES_CASE ] = "CASE" ,
4393 [RES_CASE_IN ] = "CASE_IN" ,
4394 [RES_MATCH] = "MATCH",
4395 [RES_CASE_BODY] = "CASE_BODY",
4396 [RES_ESAC ] = "ESAC" ,
4397 # endif
4398 [RES_XXXX ] = "XXXX" ,
4399 [RES_SNTX ] = "SNTX" ,
4400 };
4401 static const char *const CMDTYPE[] = {
4402 "{}",
4403 "()",
4404 "[noglob]",
4405 # if ENABLE_HUSH_FUNCTIONS
4406 "func()",
4407 # endif
4408 };
4409
4410 int pin, prn;
4411
4412 pin = 0;
4413 while (pi) {
4414 fprintf(stderr, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "",
4415 pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]);
4416 prn = 0;
4417 while (prn < pi->num_cmds) {
4418 struct command *command = &pi->cmds[prn];
4419 char **argv = command->argv;
4420
4421 fprintf(stderr, "%*s cmd %d assignment_cnt:%d",
4422 lvl*2, "", prn,
4423 command->assignment_cnt);
4424 if (command->group) {
4425 fprintf(stderr, " group %s: (argv=%p)%s%s\n",
4426 CMDTYPE[command->cmd_type],
4427 argv
4428 #if !BB_MMU
4429 , " group_as_string:", command->group_as_string
4430 #else
4431 , "", ""
4432 #endif
4433 );
4434 debug_print_tree(command->group, lvl+1);
4435 prn++;
4436 continue;
4437 }
4438 if (argv) while (*argv) {
4439 fprintf(stderr, " '%s'", *argv);
4440 argv++;
4441 }
4442 fprintf(stderr, "\n");
4443 prn++;
4444 }
4445 pi = pi->next;
4446 pin++;
4447 }
4448 }
4449 #endif /* debug_print_tree */
4450
4451 /* NB: called by pseudo_exec, and therefore must not modify any
4452 * global data until exec/_exit (we can be a child after vfork!) */
4453 static int run_list(struct pipe *pi)
4454 {
4455 #if ENABLE_HUSH_CASE
4456 char *case_word = NULL;
4457 #endif
4458 #if ENABLE_HUSH_LOOPS
4459 struct pipe *loop_top = NULL;
4460 char **for_lcur = NULL;
4461 char **for_list = NULL;
4462 #endif
4463 smallint last_followup;
4464 smalluint rcode;
4465 #if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
4466 smalluint cond_code = 0;
4467 #else
4468 enum { cond_code = 0 };
4469 #endif
4470 #if HAS_KEYWORDS
4471 smallint rword; /* enum reserved_style */
4472 smallint last_rword; /* ditto */
4473 #endif
4474
4475 debug_printf_exec("run_list start lvl %d\n", G.run_list_level);
4476 debug_enter();
4477
4478 #if ENABLE_HUSH_LOOPS
4479 /* Check syntax for "for" */
4480 for (struct pipe *cpipe = pi; cpipe; cpipe = cpipe->next) {
4481 if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN)
4482 continue;
4483 /* current word is FOR or IN (BOLD in comments below) */
4484 if (cpipe->next == NULL) {
4485 syntax_error("malformed for");
4486 debug_leave();
4487 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
4488 return 1;
4489 }
4490 /* "FOR v; do ..." and "for v IN a b; do..." are ok */
4491 if (cpipe->next->res_word == RES_DO)
4492 continue;
4493 /* next word is not "do". It must be "in" then ("FOR v in ...") */
4494 if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */
4495 || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */
4496 ) {
4497 syntax_error("malformed for");
4498 debug_leave();
4499 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
4500 return 1;
4501 }
4502 }
4503 #endif
4504
4505 /* Past this point, all code paths should jump to ret: label
4506 * in order to return, no direct "return" statements please.
4507 * This helps to ensure that no memory is leaked. */
4508
4509 #if ENABLE_HUSH_JOB
4510 G.run_list_level++;
4511 #endif
4512
4513 #if HAS_KEYWORDS
4514 rword = RES_NONE;
4515 last_rword = RES_XXXX;
4516 #endif
4517 last_followup = PIPE_SEQ;
4518 rcode = G.last_exitcode;
4519
4520 /* Go through list of pipes, (maybe) executing them. */
4521 for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) {
4522 if (G.flag_SIGINT)
4523 break;
4524
4525 IF_HAS_KEYWORDS(rword = pi->res_word;)
4526 debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n",
4527 rword, cond_code, last_rword);
4528 #if ENABLE_HUSH_LOOPS
4529 if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR)
4530 && loop_top == NULL /* avoid bumping G.depth_of_loop twice */
4531 ) {
4532 /* start of a loop: remember where loop starts */
4533 loop_top = pi;
4534 G.depth_of_loop++;
4535 }
4536 #endif
4537 /* Still in the same "if...", "then..." or "do..." branch? */
4538 if (IF_HAS_KEYWORDS(rword == last_rword &&) 1) {
4539 if ((rcode == 0 && last_followup == PIPE_OR)
4540 || (rcode != 0 && last_followup == PIPE_AND)
4541 ) {
4542 /* It is "<true> || CMD" or "<false> && CMD"
4543 * and we should not execute CMD */
4544 debug_printf_exec("skipped cmd because of || or &&\n");
4545 last_followup = pi->followup;
4546 continue;
4547 }
4548 }
4549 last_followup = pi->followup;
4550 IF_HAS_KEYWORDS(last_rword = rword;)
4551 #if ENABLE_HUSH_IF
4552 if (cond_code) {
4553 if (rword == RES_THEN) {
4554 /* if false; then ... fi has exitcode 0! */
4555 G.last_exitcode = rcode = EXIT_SUCCESS;
4556 /* "if <false> THEN cmd": skip cmd */
4557 continue;
4558 }
4559 } else {
4560 if (rword == RES_ELSE || rword == RES_ELIF) {
4561 /* "if <true> then ... ELSE/ELIF cmd":
4562 * skip cmd and all following ones */
4563 break;
4564 }
4565 }
4566 #endif
4567 #if ENABLE_HUSH_LOOPS
4568 if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */
4569 if (!for_lcur) {
4570 /* first loop through for */
4571
4572 static const char encoded_dollar_at[] ALIGN1 = {
4573 SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
4574 }; /* encoded representation of "$@" */
4575 static const char *const encoded_dollar_at_argv[] = {
4576 encoded_dollar_at, NULL
4577 }; /* argv list with one element: "$@" */
4578 char **vals;
4579
4580 vals = (char**)encoded_dollar_at_argv;
4581 if (pi->next->res_word == RES_IN) {
4582 /* if no variable values after "in" we skip "for" */
4583 if (!pi->next->cmds[0].argv) {
4584 G.last_exitcode = rcode = EXIT_SUCCESS;
4585 debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n");
4586 break;
4587 }
4588 vals = pi->next->cmds[0].argv;
4589 } /* else: "for var; do..." -> assume "$@" list */
4590 /* create list of variable values */
4591 debug_print_strings("for_list made from", vals);
4592 for_list = expand_strvec_to_strvec(vals);
4593 for_lcur = for_list;
4594 debug_print_strings("for_list", for_list);
4595 }
4596 if (!*for_lcur) {
4597 /* "for" loop is over, clean up */
4598 free(for_list);
4599 for_list = NULL;
4600 for_lcur = NULL;
4601 break;
4602 }
4603 /* Insert next value from for_lcur */
4604 /* note: *for_lcur already has quotes removed, $var expanded, etc */
4605 set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0);
4606 continue;
4607 }
4608 if (rword == RES_IN) {
4609 continue; /* "for v IN list;..." - "in" has no cmds anyway */
4610 }
4611 if (rword == RES_DONE) {
4612 continue; /* "done" has no cmds too */
4613 }
4614 #endif
4615 #if ENABLE_HUSH_CASE
4616 if (rword == RES_CASE) {
4617 case_word = expand_strvec_to_string(pi->cmds->argv);
4618 continue;
4619 }
4620 if (rword == RES_MATCH) {
4621 char **argv;
4622
4623 if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
4624 break;
4625 /* all prev words didn't match, does this one match? */
4626 argv = pi->cmds->argv;
4627 while (*argv) {
4628 char *pattern = expand_string_to_string(*argv);
4629 /* TODO: which FNM_xxx flags to use? */
4630 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
4631 free(pattern);
4632 if (cond_code == 0) { /* match! we will execute this branch */
4633 free(case_word); /* make future "word)" stop */
4634 case_word = NULL;
4635 break;
4636 }
4637 argv++;
4638 }
4639 continue;
4640 }
4641 if (rword == RES_CASE_BODY) { /* inside of a case branch */
4642 if (cond_code != 0)
4643 continue; /* not matched yet, skip this pipe */
4644 }
4645 #endif
4646 /* Just pressing <enter> in shell should check for jobs.
4647 * OTOH, in non-interactive shell this is useless
4648 * and only leads to extra job checks */
4649 if (pi->num_cmds == 0) {
4650 if (G_interactive_fd)
4651 goto check_jobs_and_continue;
4652 continue;
4653 }
4654
4655 /* After analyzing all keywords and conditions, we decided
4656 * to execute this pipe. NB: have to do checkjobs(NULL)
4657 * after run_pipe to collect any background children,
4658 * even if list execution is to be stopped. */
4659 debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds);
4660 {
4661 int r;
4662 #if ENABLE_HUSH_LOOPS
4663 G.flag_break_continue = 0;
4664 #endif
4665 rcode = r = run_pipe(pi); /* NB: rcode is a smallint */
4666 if (r != -1) {
4667 /* We ran a builtin, function, or group.
4668 * rcode is already known
4669 * and we don't need to wait for anything. */
4670 G.last_exitcode = rcode;
4671 debug_printf_exec(": builtin/func exitcode %d\n", rcode);
4672 check_and_run_traps(0);
4673 #if ENABLE_HUSH_LOOPS
4674 /* Was it "break" or "continue"? */
4675 if (G.flag_break_continue) {
4676 smallint fbc = G.flag_break_continue;
4677 /* We might fall into outer *loop*,
4678 * don't want to break it too */
4679 if (loop_top) {
4680 G.depth_break_continue--;
4681 if (G.depth_break_continue == 0)
4682 G.flag_break_continue = 0;
4683 /* else: e.g. "continue 2" should *break* once, *then* continue */
4684 } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
4685 if (G.depth_break_continue != 0 || fbc == BC_BREAK)
4686 goto check_jobs_and_break;
4687 /* "continue": simulate end of loop */
4688 rword = RES_DONE;
4689 continue;
4690 }
4691 #endif
4692 #if ENABLE_HUSH_FUNCTIONS
4693 if (G.flag_return_in_progress == 1) {
4694 /* same as "goto check_jobs_and_break" */
4695 checkjobs(NULL);
4696 break;
4697 }
4698 #endif
4699 } else if (pi->followup == PIPE_BG) {
4700 /* What does bash do with attempts to background builtins? */
4701 /* even bash 3.2 doesn't do that well with nested bg:
4702 * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
4703 * I'm NOT treating inner &'s as jobs */
4704 check_and_run_traps(0);
4705 #if ENABLE_HUSH_JOB
4706 if (G.run_list_level == 1)
4707 insert_bg_job(pi);
4708 #endif
4709 G.last_exitcode = rcode = EXIT_SUCCESS;
4710 debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
4711 } else {
4712 #if ENABLE_HUSH_JOB
4713 if (G.run_list_level == 1 && G_interactive_fd) {
4714 /* Waits for completion, then fg's main shell */
4715 rcode = checkjobs_and_fg_shell(pi);
4716 debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode);
4717 check_and_run_traps(0);
4718 } else
4719 #endif
4720 { /* This one just waits for completion */
4721 rcode = checkjobs(pi);
4722 debug_printf_exec(": checkjobs exitcode %d\n", rcode);
4723 check_and_run_traps(0);
4724 }
4725 G.last_exitcode = rcode;
4726 }
4727 }
4728
4729 /* Analyze how result affects subsequent commands */
4730 #if ENABLE_HUSH_IF
4731 if (rword == RES_IF || rword == RES_ELIF)
4732 cond_code = rcode;
4733 #endif
4734 #if ENABLE_HUSH_LOOPS
4735 /* Beware of "while false; true; do ..."! */
4736 if (pi->next && pi->next->res_word == RES_DO) {
4737 if (rword == RES_WHILE) {
4738 if (rcode) {
4739 /* "while false; do...done" - exitcode 0 */
4740 G.last_exitcode = rcode = EXIT_SUCCESS;
4741 debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
4742 goto check_jobs_and_break;
4743 }
4744 }
4745 if (rword == RES_UNTIL) {
4746 if (!rcode) {
4747 debug_printf_exec(": until expr is true: breaking\n");
4748 check_jobs_and_break:
4749 checkjobs(NULL);
4750 break;
4751 }
4752 }
4753 }
4754 #endif
4755
4756 check_jobs_and_continue:
4757 checkjobs(NULL);
4758 } /* for (pi) */
4759
4760 #if ENABLE_HUSH_JOB
4761 G.run_list_level--;
4762 #endif
4763 #if ENABLE_HUSH_LOOPS
4764 if (loop_top)
4765 G.depth_of_loop--;
4766 free(for_list);
4767 #endif
4768 #if ENABLE_HUSH_CASE
4769 free(case_word);
4770 #endif
4771 debug_leave();
4772 debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode);
4773 return rcode;
4774 }
4775
4776 /* Select which version we will use */
4777 static int run_and_free_list(struct pipe *pi)
4778 {
4779 int rcode = 0;
4780 debug_printf_exec("run_and_free_list entered\n");
4781 if (!G.fake_mode) {
4782 debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds);
4783 rcode = run_list(pi);
4784 }
4785 /* free_pipe_list has the side effect of clearing memory.
4786 * In the long run that function can be merged with run_list,
4787 * but doing that now would hobble the debugging effort. */
4788 free_pipe_list(pi);
4789 debug_printf_exec("run_and_free_list return %d\n", rcode);
4790 return rcode;
4791 }
4792
4793
4794 static struct pipe *new_pipe(void)
4795 {
4796 struct pipe *pi;
4797 pi = xzalloc(sizeof(struct pipe));
4798 /*pi->followup = 0; - deliberately invalid value */
4799 /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
4800 return pi;
4801 }
4802
4803 /* Command (member of a pipe) is complete, or we start a new pipe
4804 * if ctx->command is NULL.
4805 * No errors possible here.
4806 */
4807 static int done_command(struct parse_context *ctx)
4808 {
4809 /* The command is really already in the pipe structure, so
4810 * advance the pipe counter and make a new, null command. */
4811 struct pipe *pi = ctx->pipe;
4812 struct command *command = ctx->command;
4813
4814 if (command) {
4815 if (IS_NULL_CMD(command)) {
4816 debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
4817 goto clear_and_ret;
4818 }
4819 pi->num_cmds++;
4820 debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
4821 //debug_print_tree(ctx->list_head, 20);
4822 } else {
4823 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
4824 }
4825
4826 /* Only real trickiness here is that the uncommitted
4827 * command structure is not counted in pi->num_cmds. */
4828 pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1));
4829 ctx->command = command = &pi->cmds[pi->num_cmds];
4830 clear_and_ret:
4831 memset(command, 0, sizeof(*command));
4832 return pi->num_cmds; /* used only for 0/nonzero check */
4833 }
4834
4835 static void done_pipe(struct parse_context *ctx, pipe_style type)
4836 {
4837 int not_null;
4838
4839 debug_printf_parse("done_pipe entered, followup %d\n", type);
4840 /* Close previous command */
4841 not_null = done_command(ctx);
4842 ctx->pipe->followup = type;
4843 #if HAS_KEYWORDS
4844 ctx->pipe->pi_inverted = ctx->ctx_inverted;
4845 ctx->ctx_inverted = 0;
4846 ctx->pipe->res_word = ctx->ctx_res_w;
4847 #endif
4848
4849 /* Without this check, even just <enter> on command line generates
4850 * tree of three NOPs (!). Which is harmless but annoying.
4851 * IOW: it is safe to do it unconditionally. */
4852 if (not_null
4853 #if ENABLE_HUSH_IF
4854 || ctx->ctx_res_w == RES_FI
4855 #endif
4856 #if ENABLE_HUSH_LOOPS
4857 || ctx->ctx_res_w == RES_DONE
4858 || ctx->ctx_res_w == RES_FOR
4859 || ctx->ctx_res_w == RES_IN
4860 #endif
4861 #if ENABLE_HUSH_CASE
4862 || ctx->ctx_res_w == RES_ESAC
4863 #endif
4864 ) {
4865 struct pipe *new_p;
4866 debug_printf_parse("done_pipe: adding new pipe: "
4867 "not_null:%d ctx->ctx_res_w:%d\n",
4868 not_null, ctx->ctx_res_w);
4869 new_p = new_pipe();
4870 ctx->pipe->next = new_p;
4871 ctx->pipe = new_p;
4872 /* RES_THEN, RES_DO etc are "sticky" -
4873 * they remain set for pipes inside if/while.
4874 * This is used to control execution.
4875 * RES_FOR and RES_IN are NOT sticky (needed to support
4876 * cases where variable or value happens to match a keyword):
4877 */
4878 #if ENABLE_HUSH_LOOPS
4879 if (ctx->ctx_res_w == RES_FOR
4880 || ctx->ctx_res_w == RES_IN)
4881 ctx->ctx_res_w = RES_NONE;
4882 #endif
4883 #if ENABLE_HUSH_CASE
4884 if (ctx->ctx_res_w == RES_MATCH)
4885 ctx->ctx_res_w = RES_CASE_BODY;
4886 if (ctx->ctx_res_w == RES_CASE)
4887 ctx->ctx_res_w = RES_CASE_IN;
4888 #endif
4889 ctx->command = NULL; /* trick done_command below */
4890 /* Create the memory for command, roughly:
4891 * ctx->pipe->cmds = new struct command;
4892 * ctx->command = &ctx->pipe->cmds[0];
4893 */
4894 done_command(ctx);
4895 //debug_print_tree(ctx->list_head, 10);
4896 }
4897 debug_printf_parse("done_pipe return\n");
4898 }
4899
4900 static void initialize_context(struct parse_context *ctx)
4901 {
4902 memset(ctx, 0, sizeof(*ctx));
4903 ctx->pipe = ctx->list_head = new_pipe();
4904 /* Create the memory for command, roughly:
4905 * ctx->pipe->cmds = new struct command;
4906 * ctx->command = &ctx->pipe->cmds[0];
4907 */
4908 done_command(ctx);
4909 }
4910
4911 /* If a reserved word is found and processed, parse context is modified
4912 * and 1 is returned.
4913 */
4914 #if HAS_KEYWORDS
4915 struct reserved_combo {
4916 char literal[6];
4917 unsigned char res;
4918 unsigned char assignment_flag;
4919 int flag;
4920 };
4921 enum {
4922 FLAG_END = (1 << RES_NONE ),
4923 # if ENABLE_HUSH_IF
4924 FLAG_IF = (1 << RES_IF ),
4925 FLAG_THEN = (1 << RES_THEN ),
4926 FLAG_ELIF = (1 << RES_ELIF ),
4927 FLAG_ELSE = (1 << RES_ELSE ),
4928 FLAG_FI = (1 << RES_FI ),
4929 # endif
4930 # if ENABLE_HUSH_LOOPS
4931 FLAG_FOR = (1 << RES_FOR ),
4932 FLAG_WHILE = (1 << RES_WHILE),
4933 FLAG_UNTIL = (1 << RES_UNTIL),
4934 FLAG_DO = (1 << RES_DO ),
4935 FLAG_DONE = (1 << RES_DONE ),
4936 FLAG_IN = (1 << RES_IN ),
4937 # endif
4938 # if ENABLE_HUSH_CASE
4939 FLAG_MATCH = (1 << RES_MATCH),
4940 FLAG_ESAC = (1 << RES_ESAC ),
4941 # endif
4942 FLAG_START = (1 << RES_XXXX ),
4943 };
4944
4945 static const struct reserved_combo* match_reserved_word(o_string *word)
4946 {
4947 /* Mostly a list of accepted follow-up reserved words.
4948 * FLAG_END means we are done with the sequence, and are ready
4949 * to turn the compound list into a command.
4950 * FLAG_START means the word must start a new compound list.
4951 */
4952 static const struct reserved_combo reserved_list[] = {
4953 # if ENABLE_HUSH_IF
4954 { "!", RES_NONE, NOT_ASSIGNMENT , 0 },
4955 { "if", RES_IF, WORD_IS_KEYWORD, FLAG_THEN | FLAG_START },
4956 { "then", RES_THEN, WORD_IS_KEYWORD, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
4957 { "elif", RES_ELIF, WORD_IS_KEYWORD, FLAG_THEN },
4958 { "else", RES_ELSE, WORD_IS_KEYWORD, FLAG_FI },
4959 { "fi", RES_FI, NOT_ASSIGNMENT , FLAG_END },
4960 # endif
4961 # if ENABLE_HUSH_LOOPS
4962 { "for", RES_FOR, NOT_ASSIGNMENT , FLAG_IN | FLAG_DO | FLAG_START },
4963 { "while", RES_WHILE, WORD_IS_KEYWORD, FLAG_DO | FLAG_START },
4964 { "until", RES_UNTIL, WORD_IS_KEYWORD, FLAG_DO | FLAG_START },
4965 { "in", RES_IN, NOT_ASSIGNMENT , FLAG_DO },
4966 { "do", RES_DO, WORD_IS_KEYWORD, FLAG_DONE },
4967 { "done", RES_DONE, NOT_ASSIGNMENT , FLAG_END },
4968 # endif
4969 # if ENABLE_HUSH_CASE
4970 { "case", RES_CASE, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_START },
4971 { "esac", RES_ESAC, NOT_ASSIGNMENT , FLAG_END },
4972 # endif
4973 };
4974 const struct reserved_combo *r;
4975
4976 for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
4977 if (strcmp(word->data, r->literal) == 0)
4978 return r;
4979 }
4980 return NULL;
4981 }
4982 /* Return 0: not a keyword, 1: keyword
4983 */
4984 static int reserved_word(o_string *word, struct parse_context *ctx)
4985 {
4986 # if ENABLE_HUSH_CASE
4987 static const struct reserved_combo reserved_match = {
4988 "", RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC
4989 };
4990 # endif
4991 const struct reserved_combo *r;
4992
4993 if (word->o_quoted)
4994 return 0;
4995 r = match_reserved_word(word);
4996 if (!r)
4997 return 0;
4998
4999 debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
5000 # if ENABLE_HUSH_CASE
5001 if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE_IN) {
5002 /* "case word IN ..." - IN part starts first MATCH part */
5003 r = &reserved_match;
5004 } else
5005 # endif
5006 if (r->flag == 0) { /* '!' */
5007 if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */
5008 syntax_error("! ! command");
5009 ctx->ctx_res_w = RES_SNTX;
5010 }
5011 ctx->ctx_inverted = 1;
5012 return 1;
5013 }
5014 if (r->flag & FLAG_START) {
5015 struct parse_context *old;
5016
5017 old = xmalloc(sizeof(*old));
5018 debug_printf_parse("push stack %p\n", old);
5019 *old = *ctx; /* physical copy */
5020 initialize_context(ctx);
5021 ctx->stack = old;
5022 } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
5023 syntax_error_at(word->data);
5024 ctx->ctx_res_w = RES_SNTX;
5025 return 1;
5026 } else {
5027 /* "{...} fi" is ok. "{...} if" is not
5028 * Example:
5029 * if { echo foo; } then { echo bar; } fi */
5030 if (ctx->command->group)
5031 done_pipe(ctx, PIPE_SEQ);
5032 }
5033
5034 ctx->ctx_res_w = r->res;
5035 ctx->old_flag = r->flag;
5036 word->o_assignment = r->assignment_flag;
5037
5038 if (ctx->old_flag & FLAG_END) {
5039 struct parse_context *old;
5040
5041 done_pipe(ctx, PIPE_SEQ);
5042 debug_printf_parse("pop stack %p\n", ctx->stack);
5043 old = ctx->stack;
5044 old->command->group = ctx->list_head;
5045 old->command->cmd_type = CMD_NORMAL;
5046 # if !BB_MMU
5047 o_addstr(&old->as_string, ctx->as_string.data);
5048 o_free_unsafe(&ctx->as_string);
5049 old->command->group_as_string = xstrdup(old->as_string.data);
5050 debug_printf_parse("pop, remembering as:'%s'\n",
5051 old->command->group_as_string);
5052 # endif
5053 *ctx = *old; /* physical copy */
5054 free(old);
5055 }
5056 return 1;
5057 }
5058 #endif /* HAS_KEYWORDS */
5059
5060 /* Word is complete, look at it and update parsing context.
5061 * Normal return is 0. Syntax errors return 1.
5062 * Note: on return, word is reset, but not o_free'd!
5063 */
5064 static int done_word(o_string *word, struct parse_context *ctx)
5065 {
5066 struct command *command = ctx->command;
5067
5068 debug_printf_parse("done_word entered: '%s' %p\n", word->data, command);
5069 if (word->length == 0 && word->o_quoted == 0) {
5070 debug_printf_parse("done_word return 0: true null, ignored\n");
5071 return 0;
5072 }
5073
5074 if (ctx->pending_redirect) {
5075 /* We do not glob in e.g. >*.tmp case. bash seems to glob here
5076 * only if run as "bash", not "sh" */
5077 /* http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
5078 * "2.7 Redirection
5079 * ...the word that follows the redirection operator
5080 * shall be subjected to tilde expansion, parameter expansion,
5081 * command substitution, arithmetic expansion, and quote
5082 * removal. Pathname expansion shall not be performed
5083 * on the word by a non-interactive shell; an interactive
5084 * shell may perform it, but shall do so only when
5085 * the expansion would result in one word."
5086 */
5087 ctx->pending_redirect->rd_filename = xstrdup(word->data);
5088 /* Cater for >\file case:
5089 * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
5090 * Same with heredocs:
5091 * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
5092 */
5093 if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
5094 unbackslash(ctx->pending_redirect->rd_filename);
5095 /* Is it <<"HEREDOC"? */
5096 if (word->o_quoted) {
5097 ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
5098 }
5099 }
5100 debug_printf_parse("word stored in rd_filename: '%s'\n", word->data);
5101 ctx->pending_redirect = NULL;
5102 } else {
5103 /* If this word wasn't an assignment, next ones definitely
5104 * can't be assignments. Even if they look like ones. */
5105 if (word->o_assignment != DEFINITELY_ASSIGNMENT
5106 && word->o_assignment != WORD_IS_KEYWORD
5107 ) {
5108 word->o_assignment = NOT_ASSIGNMENT;
5109 } else {
5110 if (word->o_assignment == DEFINITELY_ASSIGNMENT)
5111 command->assignment_cnt++;
5112 word->o_assignment = MAYBE_ASSIGNMENT;
5113 }
5114
5115 #if HAS_KEYWORDS
5116 # if ENABLE_HUSH_CASE
5117 if (ctx->ctx_dsemicolon
5118 && strcmp(word->data, "esac") != 0 /* not "... pattern) cmd;; esac" */
5119 ) {
5120 /* already done when ctx_dsemicolon was set to 1: */
5121 /* ctx->ctx_res_w = RES_MATCH; */
5122 ctx->ctx_dsemicolon = 0;
5123 } else
5124 # endif
5125 if (!command->argv /* if it's the first word... */
5126 # if ENABLE_HUSH_LOOPS
5127 && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */
5128 && ctx->ctx_res_w != RES_IN
5129 # endif
5130 # if ENABLE_HUSH_CASE
5131 && ctx->ctx_res_w != RES_CASE
5132 # endif
5133 ) {
5134 debug_printf_parse("checking '%s' for reserved-ness\n", word->data);
5135 if (reserved_word(word, ctx)) {
5136 o_reset_to_empty_unquoted(word);
5137 debug_printf_parse("done_word return %d\n",
5138 (ctx->ctx_res_w == RES_SNTX));
5139 return (ctx->ctx_res_w == RES_SNTX);
5140 }
5141 # ifdef CMD_SINGLEWORD_NOGLOB_COND
5142 if (strcmp(word->data, "export") == 0
5143 # if ENABLE_HUSH_LOCAL
5144 || strcmp(word->data, "local") == 0
5145 # endif
5146 ) {
5147 command->cmd_type = CMD_SINGLEWORD_NOGLOB_COND;
5148 } else
5149 # endif
5150 # if ENABLE_HUSH_BASH_COMPAT
5151 if (strcmp(word->data, "[[") == 0) {
5152 command->cmd_type = CMD_SINGLEWORD_NOGLOB;
5153 }
5154 /* fall through */
5155 # endif
5156 }
5157 #endif
5158 if (command->group) {
5159 /* "{ echo foo; } echo bar" - bad */
5160 syntax_error_at(word->data);
5161 debug_printf_parse("done_word return 1: syntax error, "
5162 "groups and arglists don't mix\n");
5163 return 1;
5164 }
5165 if (word->o_quoted /* word had "xx" or 'xx' at least as part of it. */
5166 /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */
5167 && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL)
5168 /* (otherwise it's known to be not empty and is already safe) */
5169 ) {
5170 /* exclude "$@" - it can expand to no word despite "" */
5171 char *p = word->data;
5172 while (p[0] == SPECIAL_VAR_SYMBOL
5173 && (p[1] & 0x7f) == '@'
5174 && p[2] == SPECIAL_VAR_SYMBOL
5175 ) {
5176 p += 3;
5177 }
5178 if (p == word->data || p[0] != '\0') {
5179 /* saw no "$@", or not only "$@" but some
5180 * real text is there too */
5181 /* insert "empty variable" reference, this makes
5182 * e.g. "", $empty"" etc to not disappear */
5183 o_addchr(word, SPECIAL_VAR_SYMBOL);
5184 o_addchr(word, SPECIAL_VAR_SYMBOL);
5185 }
5186 }
5187 command->argv = add_string_to_strings(command->argv, xstrdup(word->data));
5188 debug_print_strings("word appended to argv", command->argv);
5189 }
5190
5191 #if ENABLE_HUSH_LOOPS
5192 if (ctx->ctx_res_w == RES_FOR) {
5193 if (word->o_quoted
5194 || !is_well_formed_var_name(command->argv[0], '\0')
5195 ) {
5196 /* bash says just "not a valid identifier" */
5197 syntax_error("not a valid identifier in for");
5198 return 1;
5199 }
5200 /* Force FOR to have just one word (variable name) */
5201 /* NB: basically, this makes hush see "for v in ..."
5202 * syntax as if it is "for v; in ...". FOR and IN become
5203 * two pipe structs in parse tree. */
5204 done_pipe(ctx, PIPE_SEQ);
5205 }
5206 #endif
5207 #if ENABLE_HUSH_CASE
5208 /* Force CASE to have just one word */
5209 if (ctx->ctx_res_w == RES_CASE) {
5210 done_pipe(ctx, PIPE_SEQ);
5211 }
5212 #endif
5213
5214 o_reset_to_empty_unquoted(word);
5215
5216 debug_printf_parse("done_word return 0\n");
5217 return 0;
5218 }
5219
5220
5221 /* Peek ahead in the input to find out if we have a "&n" construct,
5222 * as in "2>&1", that represents duplicating a file descriptor.
5223 * Return:
5224 * REDIRFD_CLOSE if >&- "close fd" construct is seen,
5225 * REDIRFD_SYNTAX_ERR if syntax error,
5226 * REDIRFD_TO_FILE if no & was seen,
5227 * or the number found.
5228 */
5229 #if BB_MMU
5230 #define parse_redir_right_fd(as_string, input) \
5231 parse_redir_right_fd(input)
5232 #endif
5233 static int parse_redir_right_fd(o_string *as_string, struct in_str *input)
5234 {
5235 int ch, d, ok;
5236
5237 ch = i_peek(input);
5238 if (ch != '&')
5239 return REDIRFD_TO_FILE;
5240
5241 ch = i_getch(input); /* get the & */
5242 nommu_addchr(as_string, ch);
5243 ch = i_peek(input);
5244 if (ch == '-') {
5245 ch = i_getch(input);
5246 nommu_addchr(as_string, ch);
5247 return REDIRFD_CLOSE;
5248 }
5249 d = 0;
5250 ok = 0;
5251 while (ch != EOF && isdigit(ch)) {
5252 d = d*10 + (ch-'0');
5253 ok = 1;
5254 ch = i_getch(input);
5255 nommu_addchr(as_string, ch);
5256 ch = i_peek(input);
5257 }
5258 if (ok) return d;
5259
5260 //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
5261
5262 bb_error_msg("ambiguous redirect");
5263 return REDIRFD_SYNTAX_ERR;
5264 }
5265
5266 /* Return code is 0 normal, 1 if a syntax error is detected
5267 */
5268 static int parse_redirect(struct parse_context *ctx,
5269 int fd,
5270 redir_type style,
5271 struct in_str *input)
5272 {
5273 struct command *command = ctx->command;
5274 struct redir_struct *redir;
5275 struct redir_struct **redirp;
5276 int dup_num;
5277
5278 dup_num = REDIRFD_TO_FILE;
5279 if (style != REDIRECT_HEREDOC) {
5280 /* Check for a '>&1' type redirect */
5281 dup_num = parse_redir_right_fd(&ctx->as_string, input);
5282 if (dup_num == REDIRFD_SYNTAX_ERR)
5283 return 1;
5284 } else {
5285 int ch = i_peek(input);
5286 dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */
5287 if (dup_num) { /* <<-... */
5288 ch = i_getch(input);
5289 nommu_addchr(&ctx->as_string, ch);
5290 ch = i_peek(input);
5291 }
5292 }
5293
5294 if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) {
5295 int ch = i_peek(input);
5296 if (ch == '|') {
5297 /* >|FILE redirect ("clobbering" >).
5298 * Since we do not support "set -o noclobber" yet,
5299 * >| and > are the same for now. Just eat |.
5300 */
5301 ch = i_getch(input);
5302 nommu_addchr(&ctx->as_string, ch);
5303 }
5304 }
5305
5306 /* Create a new redir_struct and append it to the linked list */
5307 redirp = &command->redirects;
5308 while ((redir = *redirp) != NULL) {
5309 redirp = &(redir->next);
5310 }
5311 *redirp = redir = xzalloc(sizeof(*redir));
5312 /* redir->next = NULL; */
5313 /* redir->rd_filename = NULL; */
5314 redir->rd_type = style;
5315 redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd;
5316
5317 debug_printf_parse("redirect type %d %s\n", redir->rd_fd,
5318 redir_table[style].descrip);
5319
5320 redir->rd_dup = dup_num;
5321 if (style != REDIRECT_HEREDOC && dup_num != REDIRFD_TO_FILE) {
5322 /* Erik had a check here that the file descriptor in question
5323 * is legit; I postpone that to "run time"
5324 * A "-" representation of "close me" shows up as a -3 here */
5325 debug_printf_parse("duplicating redirect '%d>&%d'\n",
5326 redir->rd_fd, redir->rd_dup);
5327 } else {
5328 /* Set ctx->pending_redirect, so we know what to do at the
5329 * end of the next parsed word. */
5330 ctx->pending_redirect = redir;
5331 }
5332 return 0;
5333 }
5334
5335 /* If a redirect is immediately preceded by a number, that number is
5336 * supposed to tell which file descriptor to redirect. This routine
5337 * looks for such preceding numbers. In an ideal world this routine
5338 * needs to handle all the following classes of redirects...
5339 * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo
5340 * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo
5341 * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo
5342 * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo
5343 *
5344 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
5345 * "2.7 Redirection
5346 * ... If n is quoted, the number shall not be recognized as part of
5347 * the redirection expression. For example:
5348 * echo \2>a
5349 * writes the character 2 into file a"
5350 * We are getting it right by setting ->o_quoted on any \<char>
5351 *
5352 * A -1 return means no valid number was found,
5353 * the caller should use the appropriate default for this redirection.
5354 */
5355 static int redirect_opt_num(o_string *o)
5356 {
5357 int num;
5358
5359 if (o->data == NULL)
5360 return -1;
5361 num = bb_strtou(o->data, NULL, 10);
5362 if (errno || num < 0)
5363 return -1;
5364 o_reset_to_empty_unquoted(o);
5365 return num;
5366 }
5367
5368 #if BB_MMU
5369 #define fetch_till_str(as_string, input, word, skip_tabs) \
5370 fetch_till_str(input, word, skip_tabs)
5371 #endif
5372 static char *fetch_till_str(o_string *as_string,
5373 struct in_str *input,
5374 const char *word,
5375 int skip_tabs)
5376 {
5377 o_string heredoc = NULL_O_STRING;
5378 int past_EOL = 0;
5379 int ch;
5380
5381 goto jump_in;
5382 while (1) {
5383 ch = i_getch(input);
5384 nommu_addchr(as_string, ch);
5385 if (ch == '\n') {
5386 if (strcmp(heredoc.data + past_EOL, word) == 0) {
5387 heredoc.data[past_EOL] = '\0';
5388 debug_printf_parse("parsed heredoc '%s'\n", heredoc.data);
5389 return heredoc.data;
5390 }
5391 do {
5392 o_addchr(&heredoc, ch);
5393 past_EOL = heredoc.length;
5394 jump_in:
5395 do {
5396 ch = i_getch(input);
5397 nommu_addchr(as_string, ch);
5398 } while (skip_tabs && ch == '\t');
5399 } while (ch == '\n');
5400 }
5401 if (ch == EOF) {
5402 o_free_unsafe(&heredoc);
5403 return NULL;
5404 }
5405 o_addchr(&heredoc, ch);
5406 nommu_addchr(as_string, ch);
5407 }
5408 }
5409
5410 /* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
5411 * and load them all. There should be exactly heredoc_cnt of them.
5412 */
5413 static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_str *input)
5414 {
5415 struct pipe *pi = ctx->list_head;
5416
5417 while (pi && heredoc_cnt) {
5418 int i;
5419 struct command *cmd = pi->cmds;
5420
5421 debug_printf_parse("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n",
5422 pi->num_cmds,
5423 cmd->argv ? cmd->argv[0] : "NONE");
5424 for (i = 0; i < pi->num_cmds; i++) {
5425 struct redir_struct *redir = cmd->redirects;
5426
5427 debug_printf_parse("fetch_heredocs: %d cmd argv0:'%s'\n",
5428 i, cmd->argv ? cmd->argv[0] : "NONE");
5429 while (redir) {
5430 if (redir->rd_type == REDIRECT_HEREDOC) {
5431 char *p;
5432
5433 redir->rd_type = REDIRECT_HEREDOC2;
5434 /* redir->rd_dup is (ab)used to indicate <<- */
5435 p = fetch_till_str(&ctx->as_string, input,
5436 redir->rd_filename, redir->rd_dup & HEREDOC_SKIPTABS);
5437 if (!p) {
5438 syntax_error("unexpected EOF in here document");
5439 return 1;
5440 }
5441 free(redir->rd_filename);
5442 redir->rd_filename = p;
5443 heredoc_cnt--;
5444 }
5445 redir = redir->next;
5446 }
5447 cmd++;
5448 }
5449 pi = pi->next;
5450 }
5451 #if 0
5452 /* Should be 0. If it isn't, it's a parse error */
5453 if (heredoc_cnt)
5454 bb_error_msg_and_die("heredoc BUG 2");
5455 #endif
5456 return 0;
5457 }
5458
5459
5460 #if ENABLE_HUSH_TICK
5461 static FILE *generate_stream_from_string(const char *s, pid_t *pid_p)
5462 {
5463 pid_t pid;
5464 int channel[2];
5465 # if !BB_MMU
5466 char **to_free = NULL;
5467 # endif
5468
5469 xpipe(channel);
5470 pid = BB_MMU ? fork() : vfork();
5471 if (pid < 0)
5472 bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork");
5473
5474 if (pid == 0) { /* child */
5475 disable_restore_tty_pgrp_on_exit();
5476 /* Process substitution is not considered to be usual
5477 * 'command execution'.
5478 * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
5479 */
5480 bb_signals(0
5481 + (1 << SIGTSTP)
5482 + (1 << SIGTTIN)
5483 + (1 << SIGTTOU)
5484 , SIG_IGN);
5485 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
5486 close(channel[0]); /* NB: close _first_, then move fd! */
5487 xmove_fd(channel[1], 1);
5488 /* Prevent it from trying to handle ctrl-z etc */
5489 IF_HUSH_JOB(G.run_list_level = 1;)
5490 /* Awful hack for `trap` or $(trap).
5491 *
5492 * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
5493 * contains an example where "trap" is executed in a subshell:
5494 *
5495 * save_traps=$(trap)
5496 * ...
5497 * eval "$save_traps"
5498 *
5499 * Standard does not say that "trap" in subshell shall print
5500 * parent shell's traps. It only says that its output
5501 * must have suitable form, but then, in the above example
5502 * (which is not supposed to be normative), it implies that.
5503 *
5504 * bash (and probably other shell) does implement it
5505 * (traps are reset to defaults, but "trap" still shows them),
5506 * but as a result, "trap" logic is hopelessly messed up:
5507 *
5508 * # trap
5509 * trap -- 'echo Ho' SIGWINCH <--- we have a handler
5510 * # (trap) <--- trap is in subshell - no output (correct, traps are reset)
5511 * # true | trap <--- trap is in subshell - no output (ditto)
5512 * # echo `true | trap` <--- in subshell - output (but traps are reset!)
5513 * trap -- 'echo Ho' SIGWINCH
5514 * # echo `(trap)` <--- in subshell in subshell - output
5515 * trap -- 'echo Ho' SIGWINCH
5516 * # echo `true | (trap)` <--- in subshell in subshell in subshell - output!
5517 * trap -- 'echo Ho' SIGWINCH
5518 *
5519 * The rules when to forget and when to not forget traps
5520 * get really complex and nonsensical.
5521 *
5522 * Our solution: ONLY bare $(trap) or `trap` is special.
5523 */
5524 s = skip_whitespace(s);
5525 if (strncmp(s, "trap", 4) == 0 && (*skip_whitespace(s + 4) == '\0'))
5526 {
5527 static const char *const argv[] = { NULL, NULL };
5528 builtin_trap((char**)argv);
5529 exit(0); /* not _exit() - we need to fflush */
5530 }
5531 # if BB_MMU
5532 reset_traps_to_defaults();
5533 parse_and_run_string(s);
5534 _exit(G.last_exitcode);
5535 # else
5536 /* We re-execute after vfork on NOMMU. This makes this script safe:
5537 * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG
5538 * huge=`cat BIG` # was blocking here forever
5539 * echo OK
5540 */
5541 re_execute_shell(&to_free,
5542 s,
5543 G.global_argv[0],
5544 G.global_argv + 1,
5545 NULL);
5546 # endif
5547 }
5548
5549 /* parent */
5550 *pid_p = pid;
5551 # if ENABLE_HUSH_FAST
5552 G.count_SIGCHLD++;
5553 //bb_error_msg("[%d] fork in generate_stream_from_string: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
5554 # endif
5555 enable_restore_tty_pgrp_on_exit();
5556 # if !BB_MMU
5557 free(to_free);
5558 # endif
5559 close(channel[1]);
5560 close_on_exec_on(channel[0]);
5561 return xfdopen_for_read(channel[0]);
5562 }
5563
5564 /* Return code is exit status of the process that is run. */
5565 static int process_command_subs(o_string *dest, const char *s)
5566 {
5567 FILE *fp;
5568 struct in_str pipe_str;
5569 pid_t pid;
5570 int status, ch, eol_cnt;
5571
5572 fp = generate_stream_from_string(s, &pid);
5573
5574 /* Now send results of command back into original context */
5575 setup_file_in_str(&pipe_str, fp);
5576 eol_cnt = 0;
5577 while ((ch = i_getch(&pipe_str)) != EOF) {
5578 if (ch == '\n') {
5579 eol_cnt++;
5580 continue;
5581 }
5582 while (eol_cnt) {
5583 o_addchr(dest, '\n');
5584 eol_cnt--;
5585 }
5586 o_addQchr(dest, ch);
5587 }
5588
5589 debug_printf("done reading from `cmd` pipe, closing it\n");
5590 fclose(fp);
5591 /* We need to extract exitcode. Test case
5592 * "true; echo `sleep 1; false` $?"
5593 * should print 1 */
5594 safe_waitpid(pid, &status, 0);
5595 debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status));
5596 return WEXITSTATUS(status);
5597 }
5598 #endif /* ENABLE_HUSH_TICK */
5599
5600 #if !ENABLE_HUSH_FUNCTIONS
5601 #define parse_group(dest, ctx, input, ch) \
5602 parse_group(ctx, input, ch)
5603 #endif
5604 static int parse_group(o_string *dest, struct parse_context *ctx,
5605 struct in_str *input, int ch)
5606 {
5607 /* dest contains characters seen prior to ( or {.
5608 * Typically it's empty, but for function defs,
5609 * it contains function name (without '()'). */
5610 struct pipe *pipe_list;
5611 int endch;
5612 struct command *command = ctx->command;
5613
5614 debug_printf_parse("parse_group entered\n");
5615 #if ENABLE_HUSH_FUNCTIONS
5616 if (ch == '(' && !dest->o_quoted) {
5617 if (dest->length)
5618 if (done_word(dest, ctx))
5619 return 1;
5620 if (!command->argv)
5621 goto skip; /* (... */
5622 if (command->argv[1]) { /* word word ... (... */
5623 syntax_error_unexpected_ch('(');
5624 return 1;
5625 }
5626 /* it is "word(..." or "word (..." */
5627 do
5628 ch = i_getch(input);
5629 while (ch == ' ' || ch == '\t');
5630 if (ch != ')') {
5631 syntax_error_unexpected_ch(ch);
5632 return 1;
5633 }
5634 nommu_addchr(&ctx->as_string, ch);
5635 do
5636 ch = i_getch(input);
5637 while (ch == ' ' || ch == '\t' || ch == '\n');
5638 if (ch != '{') {
5639 syntax_error_unexpected_ch(ch);
5640 return 1;
5641 }
5642 nommu_addchr(&ctx->as_string, ch);
5643 command->cmd_type = CMD_FUNCDEF;
5644 goto skip;
5645 }
5646 #endif
5647
5648 #if 0 /* Prevented by caller */
5649 if (command->argv /* word [word]{... */
5650 || dest->length /* word{... */
5651 || dest->o_quoted /* ""{... */
5652 ) {
5653 syntax_error(NULL);
5654 debug_printf_parse("parse_group return 1: "
5655 "syntax error, groups and arglists don't mix\n");
5656 return 1;
5657 }
5658 #endif
5659
5660 #if ENABLE_HUSH_FUNCTIONS
5661 skip:
5662 #endif
5663 endch = '}';
5664 if (ch == '(') {
5665 endch = ')';
5666 command->cmd_type = CMD_SUBSHELL;
5667 } else {
5668 /* bash does not allow "{echo...", requires whitespace */
5669 ch = i_getch(input);
5670 if (ch != ' ' && ch != '\t' && ch != '\n') {
5671 syntax_error_unexpected_ch(ch);
5672 return 1;
5673 }
5674 nommu_addchr(&ctx->as_string, ch);
5675 }
5676
5677 {
5678 #if !BB_MMU
5679 char *as_string = NULL;
5680 #endif
5681 pipe_list = parse_stream(&as_string, input, endch);
5682 #if !BB_MMU
5683 if (as_string)
5684 o_addstr(&ctx->as_string, as_string);
5685 #endif
5686 /* empty ()/{} or parse error? */
5687 if (!pipe_list || pipe_list == ERR_PTR) {
5688 /* parse_stream already emitted error msg */
5689 #if !BB_MMU
5690 free(as_string);
5691 #endif
5692 debug_printf_parse("parse_group return 1: "
5693 "parse_stream returned %p\n", pipe_list);
5694 return 1;
5695 }
5696 command->group = pipe_list;
5697 #if !BB_MMU
5698 as_string[strlen(as_string) - 1] = '\0'; /* plink ')' or '}' */
5699 command->group_as_string = as_string;
5700 debug_printf_parse("end of group, remembering as:'%s'\n",
5701 command->group_as_string);
5702 #endif
5703 }
5704 debug_printf_parse("parse_group return 0\n");
5705 return 0;
5706 /* command remains "open", available for possible redirects */
5707 }
5708
5709 #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT
5710 /* Subroutines for copying $(...) and `...` things */
5711 static void add_till_backquote(o_string *dest, struct in_str *input);
5712 /* '...' */
5713 static void add_till_single_quote(o_string *dest, struct in_str *input)
5714 {
5715 while (1) {
5716 int ch = i_getch(input);
5717 if (ch == EOF) {
5718 syntax_error_unterm_ch('\'');
5719 /*xfunc_die(); - redundant */
5720 }
5721 if (ch == '\'')
5722 return;
5723 o_addchr(dest, ch);
5724 }
5725 }
5726 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
5727 static void add_till_double_quote(o_string *dest, struct in_str *input)
5728 {
5729 while (1) {
5730 int ch = i_getch(input);
5731 if (ch == EOF) {
5732 syntax_error_unterm_ch('"');
5733 /*xfunc_die(); - redundant */
5734 }
5735 if (ch == '"')
5736 return;
5737 if (ch == '\\') { /* \x. Copy both chars. */
5738 o_addchr(dest, ch);
5739 ch = i_getch(input);
5740 }
5741 o_addchr(dest, ch);
5742 if (ch == '`') {
5743 add_till_backquote(dest, input);
5744 o_addchr(dest, ch);
5745 continue;
5746 }
5747 //if (ch == '$') ...
5748 }
5749 }
5750 /* Process `cmd` - copy contents until "`" is seen. Complicated by
5751 * \` quoting.
5752 * "Within the backquoted style of command substitution, backslash
5753 * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
5754 * The search for the matching backquote shall be satisfied by the first
5755 * backquote found without a preceding backslash; during this search,
5756 * if a non-escaped backquote is encountered within a shell comment,
5757 * a here-document, an embedded command substitution of the $(command)
5758 * form, or a quoted string, undefined results occur. A single-quoted
5759 * or double-quoted string that begins, but does not end, within the
5760 * "`...`" sequence produces undefined results."
5761 * Example Output
5762 * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST
5763 */
5764 static void add_till_backquote(o_string *dest, struct in_str *input)
5765 {
5766 while (1) {
5767 int ch = i_getch(input);
5768 if (ch == EOF) {
5769 syntax_error_unterm_ch('`');
5770 /*xfunc_die(); - redundant */
5771 }
5772 if (ch == '`')
5773 return;
5774 if (ch == '\\') {
5775 /* \x. Copy both chars unless it is \` */
5776 int ch2 = i_getch(input);
5777 if (ch2 == EOF) {
5778 syntax_error_unterm_ch('`');
5779 /*xfunc_die(); - redundant */
5780 }
5781 if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
5782 o_addchr(dest, ch);
5783 ch = ch2;
5784 }
5785 o_addchr(dest, ch);
5786 }
5787 }
5788 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
5789 * quoting and nested ()s.
5790 * "With the $(command) style of command substitution, all characters
5791 * following the open parenthesis to the matching closing parenthesis
5792 * constitute the command. Any valid shell script can be used for command,
5793 * except a script consisting solely of redirections which produces
5794 * unspecified results."
5795 * Example Output
5796 * echo $(echo '(TEST)' BEST) (TEST) BEST
5797 * echo $(echo 'TEST)' BEST) TEST) BEST
5798 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST
5799 */
5800 static void add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl)
5801 {
5802 int count = 0;
5803 while (1) {
5804 int ch = i_getch(input);
5805 if (ch == EOF) {
5806 syntax_error_unterm_ch(')');
5807 /*xfunc_die(); - redundant */
5808 }
5809 if (ch == '(')
5810 count++;
5811 if (ch == ')') {
5812 if (--count < 0) {
5813 if (!dbl)
5814 break;
5815 if (i_peek(input) == ')') {
5816 i_getch(input);
5817 break;
5818 }
5819 }
5820 }
5821 o_addchr(dest, ch);
5822 if (ch == '\'') {
5823 add_till_single_quote(dest, input);
5824 o_addchr(dest, ch);
5825 continue;
5826 }
5827 if (ch == '"') {
5828 add_till_double_quote(dest, input);
5829 o_addchr(dest, ch);
5830 continue;
5831 }
5832 if (ch == '\\') {
5833 /* \x. Copy verbatim. Important for \(, \) */
5834 ch = i_getch(input);
5835 if (ch == EOF) {
5836 syntax_error_unterm_ch(')');
5837 /*xfunc_die(); - redundant */
5838 }
5839 o_addchr(dest, ch);
5840 continue;
5841 }
5842 }
5843 }
5844 #endif /* ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT */
5845
5846 /* Return code: 0 for OK, 1 for syntax error */
5847 #if BB_MMU
5848 #define handle_dollar(as_string, dest, input) \
5849 handle_dollar(dest, input)
5850 #endif
5851 static int handle_dollar(o_string *as_string,
5852 o_string *dest,
5853 struct in_str *input)
5854 {
5855 int ch = i_peek(input); /* first character after the $ */
5856 unsigned char quote_mask = dest->o_escape ? 0x80 : 0;
5857
5858 debug_printf_parse("handle_dollar entered: ch='%c'\n", ch);
5859 if (isalpha(ch)) {
5860 ch = i_getch(input);
5861 nommu_addchr(as_string, ch);
5862 make_var:
5863 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5864 while (1) {
5865 debug_printf_parse(": '%c'\n", ch);
5866 o_addchr(dest, ch | quote_mask);
5867 quote_mask = 0;
5868 ch = i_peek(input);
5869 if (!isalnum(ch) && ch != '_')
5870 break;
5871 ch = i_getch(input);
5872 nommu_addchr(as_string, ch);
5873 }
5874 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5875 } else if (isdigit(ch)) {
5876 make_one_char_var:
5877 ch = i_getch(input);
5878 nommu_addchr(as_string, ch);
5879 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5880 debug_printf_parse(": '%c'\n", ch);
5881 o_addchr(dest, ch | quote_mask);
5882 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5883 } else switch (ch) {
5884 case '$': /* pid */
5885 case '!': /* last bg pid */
5886 case '?': /* last exit code */
5887 case '#': /* number of args */
5888 case '*': /* args */
5889 case '@': /* args */
5890 goto make_one_char_var;
5891 case '{': {
5892 bool first_char, all_digits;
5893 int expansion;
5894
5895 ch = i_getch(input);
5896 nommu_addchr(as_string, ch);
5897 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5898
5899 /* TODO: maybe someone will try to escape the '}' */
5900 expansion = 0;
5901 first_char = true;
5902 all_digits = false;
5903 while (1) {
5904 ch = i_getch(input);
5905 nommu_addchr(as_string, ch);
5906 if (ch == '}') {
5907 break;
5908 }
5909
5910 if (first_char) {
5911 if (ch == '#') {
5912 /* ${#var}: length of var contents */
5913 goto char_ok;
5914 }
5915 if (isdigit(ch)) {
5916 all_digits = true;
5917 goto char_ok;
5918 }
5919 /* They're being verbose and doing ${?} */
5920 if (i_peek(input) == '}' && strchr("$!?#*@_", ch))
5921 goto char_ok;
5922 }
5923
5924 if (expansion < 2
5925 && ( (all_digits && !isdigit(ch))
5926 || (!all_digits && !isalnum(ch) && ch != '_')
5927 )
5928 ) {
5929 /* handle parameter expansions
5930 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
5931 */
5932 if (first_char)
5933 goto case_default;
5934 switch (ch) {
5935 case ':': /* null modifier */
5936 if (expansion == 0) {
5937 debug_printf_parse(": null modifier\n");
5938 ++expansion;
5939 break;
5940 }
5941 goto case_default;
5942 case '#': /* remove prefix */
5943 case '%': /* remove suffix */
5944 if (expansion == 0) {
5945 debug_printf_parse(": remove suffix/prefix\n");
5946 expansion = 2;
5947 break;
5948 }
5949 goto case_default;
5950 case '-': /* default value */
5951 case '=': /* assign default */
5952 case '+': /* alternative */
5953 case '?': /* error indicate */
5954 debug_printf_parse(": parameter expansion\n");
5955 expansion = 2;
5956 break;
5957 default:
5958 case_default:
5959 syntax_error_unterm_str("${name}");
5960 debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");
5961 return 1;
5962 }
5963 }
5964 char_ok:
5965 debug_printf_parse(": '%c'\n", ch);
5966 o_addchr(dest, ch | quote_mask);
5967 quote_mask = 0;
5968 first_char = false;
5969 } /* while (1) */
5970 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5971 break;
5972 }
5973 #if ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_TICK
5974 case '(': {
5975 # if !BB_MMU
5976 int pos;
5977 # endif
5978 ch = i_getch(input);
5979 nommu_addchr(as_string, ch);
5980 # if ENABLE_SH_MATH_SUPPORT
5981 if (i_peek(input) == '(') {
5982 ch = i_getch(input);
5983 nommu_addchr(as_string, ch);
5984 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5985 o_addchr(dest, /*quote_mask |*/ '+');
5986 # if !BB_MMU
5987 pos = dest->length;
5988 # endif
5989 add_till_closing_paren(dest, input, true);
5990 # if !BB_MMU
5991 if (as_string) {
5992 o_addstr(as_string, dest->data + pos);
5993 o_addchr(as_string, ')');
5994 o_addchr(as_string, ')');
5995 }
5996 # endif
5997 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5998 break;
5999 }
6000 # endif
6001 # if ENABLE_HUSH_TICK
6002 o_addchr(dest, SPECIAL_VAR_SYMBOL);
6003 o_addchr(dest, quote_mask | '`');
6004 # if !BB_MMU
6005 pos = dest->length;
6006 # endif
6007 add_till_closing_paren(dest, input, false);
6008 # if !BB_MMU
6009 if (as_string) {
6010 o_addstr(as_string, dest->data + pos);
6011 o_addchr(as_string, ')');
6012 }
6013 # endif
6014 o_addchr(dest, SPECIAL_VAR_SYMBOL);
6015 # endif
6016 break;
6017 }
6018 #endif
6019 case '_':
6020 ch = i_getch(input);
6021 nommu_addchr(as_string, ch);
6022 ch = i_peek(input);
6023 if (isalnum(ch)) { /* it's $_name or $_123 */
6024 ch = '_';
6025 goto make_var;
6026 }
6027 /* else: it's $_ */
6028 /* TODO: $_ and $-: */
6029 /* $_ Shell or shell script name; or last argument of last command
6030 * (if last command wasn't a pipe; if it was, bash sets $_ to "");
6031 * but in command's env, set to full pathname used to invoke it */
6032 /* $- Option flags set by set builtin or shell options (-i etc) */
6033 default:
6034 o_addQchr(dest, '$');
6035 }
6036 debug_printf_parse("handle_dollar return 0\n");
6037 return 0;
6038 }
6039
6040 #if BB_MMU
6041 #define parse_stream_dquoted(as_string, dest, input, dquote_end) \
6042 parse_stream_dquoted(dest, input, dquote_end)
6043 #endif
6044 static int parse_stream_dquoted(o_string *as_string,
6045 o_string *dest,
6046 struct in_str *input,
6047 int dquote_end)
6048 {
6049 int ch;
6050 int next;
6051
6052 again:
6053 ch = i_getch(input);
6054 if (ch != EOF)
6055 nommu_addchr(as_string, ch);
6056 if (ch == dquote_end) { /* may be only '"' or EOF */
6057 if (dest->o_assignment == NOT_ASSIGNMENT)
6058 dest->o_escape ^= 1;
6059 debug_printf_parse("parse_stream_dquoted return 0\n");
6060 return 0;
6061 }
6062 /* note: can't move it above ch == dquote_end check! */
6063 if (ch == EOF) {
6064 syntax_error_unterm_ch('"');
6065 /*xfunc_die(); - redundant */
6066 }
6067 next = '\0';
6068 if (ch != '\n') {
6069 next = i_peek(input);
6070 }
6071 debug_printf_parse("\" ch=%c (%d) escape=%d\n",
6072 ch, ch, dest->o_escape);
6073 if (ch == '\\') {
6074 if (next == EOF) {
6075 syntax_error("\\<eof>");
6076 xfunc_die();
6077 }
6078 /* bash:
6079 * "The backslash retains its special meaning [in "..."]
6080 * only when followed by one of the following characters:
6081 * $, `, ", \, or <newline>. A double quote may be quoted
6082 * within double quotes by preceding it with a backslash."
6083 */
6084 if (strchr("$`\"\\\n", next) != NULL) {
6085 ch = i_getch(input);
6086 if (ch != '\n') {
6087 o_addqchr(dest, ch);
6088 nommu_addchr(as_string, ch);
6089 }
6090 } else {
6091 o_addqchr(dest, '\\');
6092 nommu_addchr(as_string, '\\');
6093 }
6094 goto again;
6095 }
6096 if (ch == '$') {
6097 if (handle_dollar(as_string, dest, input) != 0) {
6098 debug_printf_parse("parse_stream_dquoted return 1: "
6099 "handle_dollar returned non-0\n");
6100 return 1;
6101 }
6102 goto again;
6103 }
6104 #if ENABLE_HUSH_TICK
6105 if (ch == '`') {
6106 //int pos = dest->length;
6107 o_addchr(dest, SPECIAL_VAR_SYMBOL);
6108 o_addchr(dest, 0x80 | '`');
6109 add_till_backquote(dest, input);
6110 o_addchr(dest, SPECIAL_VAR_SYMBOL);
6111 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6112 goto again;
6113 }
6114 #endif
6115 o_addQchr(dest, ch);
6116 if (ch == '='
6117 && (dest->o_assignment == MAYBE_ASSIGNMENT
6118 || dest->o_assignment == WORD_IS_KEYWORD)
6119 && is_well_formed_var_name(dest->data, '=')
6120 ) {
6121 dest->o_assignment = DEFINITELY_ASSIGNMENT;
6122 }
6123 goto again;
6124 }
6125
6126 /*
6127 * Scan input until EOF or end_trigger char.
6128 * Return a list of pipes to execute, or NULL on EOF
6129 * or if end_trigger character is met.
6130 * On syntax error, exit is shell is not interactive,
6131 * reset parsing machinery and start parsing anew,
6132 * or return ERR_PTR.
6133 */
6134 static struct pipe *parse_stream(char **pstring,
6135 struct in_str *input,
6136 int end_trigger)
6137 {
6138 struct parse_context ctx;
6139 o_string dest = NULL_O_STRING;
6140 int is_in_dquote;
6141 int heredoc_cnt;
6142
6143 /* Double-quote state is handled in the state variable is_in_dquote.
6144 * A single-quote triggers a bypass of the main loop until its mate is
6145 * found. When recursing, quote state is passed in via dest->o_escape.
6146 */
6147 debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
6148 end_trigger ? end_trigger : 'X');
6149 debug_enter();
6150
6151 /* If very first arg is "" or '', dest.data may end up NULL.
6152 * Preventing this: */
6153 o_addchr(&dest, '\0');
6154 dest.length = 0;
6155
6156 G.ifs = get_local_var_value("IFS");
6157 if (G.ifs == NULL)
6158 G.ifs = defifs;
6159
6160 reset:
6161 #if ENABLE_HUSH_INTERACTIVE
6162 input->promptmode = 0; /* PS1 */
6163 #endif
6164 /* dest.o_assignment = MAYBE_ASSIGNMENT; - already is */
6165 initialize_context(&ctx);
6166 is_in_dquote = 0;
6167 heredoc_cnt = 0;
6168 while (1) {
6169 const char *is_ifs;
6170 const char *is_special;
6171 int ch;
6172 int next;
6173 int redir_fd;
6174 redir_type redir_style;
6175
6176 if (is_in_dquote) {
6177 /* dest.o_quoted = 1; - already is (see below) */
6178 if (parse_stream_dquoted(&ctx.as_string, &dest, input, '"')) {
6179 goto parse_error;
6180 }
6181 /* We reached closing '"' */
6182 is_in_dquote = 0;
6183 }
6184 ch = i_getch(input);
6185 debug_printf_parse(": ch=%c (%d) escape=%d\n",
6186 ch, ch, dest.o_escape);
6187 if (ch == EOF) {
6188 struct pipe *pi;
6189
6190 if (heredoc_cnt) {
6191 syntax_error_unterm_str("here document");
6192 goto parse_error;
6193 }
6194 /* end_trigger == '}' case errors out earlier,
6195 * checking only ')' */
6196 if (end_trigger == ')') {
6197 syntax_error_unterm_ch('('); /* exits */
6198 /* goto parse_error; */
6199 }
6200
6201 if (done_word(&dest, &ctx)) {
6202 goto parse_error;
6203 }
6204 o_free(&dest);
6205 done_pipe(&ctx, PIPE_SEQ);
6206 pi = ctx.list_head;
6207 /* If we got nothing... */
6208 /* (this makes bare "&" cmd a no-op.
6209 * bash says: "syntax error near unexpected token '&'") */
6210 if (pi->num_cmds == 0
6211 IF_HAS_KEYWORDS( && pi->res_word == RES_NONE)
6212 ) {
6213 free_pipe_list(pi);
6214 pi = NULL;
6215 }
6216 #if !BB_MMU
6217 debug_printf_parse("as_string '%s'\n", ctx.as_string.data);
6218 if (pstring)
6219 *pstring = ctx.as_string.data;
6220 else
6221 o_free_unsafe(&ctx.as_string);
6222 #endif
6223 debug_leave();
6224 debug_printf_parse("parse_stream return %p\n", pi);
6225 return pi;
6226 }
6227 nommu_addchr(&ctx.as_string, ch);
6228
6229 next = '\0';
6230 if (ch != '\n')
6231 next = i_peek(input);
6232
6233 is_special = "{}<>;&|()#'" /* special outside of "str" */
6234 "\\$\"" IF_HUSH_TICK("`"); /* always special */
6235 /* Are { and } special here? */
6236 if (ctx.command->argv /* word [word]{... */
6237 || dest.length /* word{... */
6238 || dest.o_quoted /* ""{... */
6239 || (next != ';' && next != ')' && !strchr(G.ifs, next)) /* {word */
6240 ) {
6241 /* They are not special, skip "{}" */
6242 is_special += 2;
6243 }
6244 is_special = strchr(is_special, ch);
6245 is_ifs = strchr(G.ifs, ch);
6246
6247 if (!is_special && !is_ifs) { /* ordinary char */
6248 ordinary_char:
6249 o_addQchr(&dest, ch);
6250 if ((dest.o_assignment == MAYBE_ASSIGNMENT
6251 || dest.o_assignment == WORD_IS_KEYWORD)
6252 && ch == '='
6253 && is_well_formed_var_name(dest.data, '=')
6254 ) {
6255 dest.o_assignment = DEFINITELY_ASSIGNMENT;
6256 }
6257 continue;
6258 }
6259
6260 if (is_ifs) {
6261 if (done_word(&dest, &ctx)) {
6262 goto parse_error;
6263 }
6264 if (ch == '\n') {
6265 #if ENABLE_HUSH_CASE
6266 /* "case ... in <newline> word) ..." -
6267 * newlines are ignored (but ';' wouldn't be) */
6268 if (ctx.command->argv == NULL
6269 && ctx.ctx_res_w == RES_MATCH
6270 ) {
6271 continue;
6272 }
6273 #endif
6274 /* Treat newline as a command separator. */
6275 done_pipe(&ctx, PIPE_SEQ);
6276 debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt);
6277 if (heredoc_cnt) {
6278 if (fetch_heredocs(heredoc_cnt, &ctx, input)) {
6279 goto parse_error;
6280 }
6281 heredoc_cnt = 0;
6282 }
6283 dest.o_assignment = MAYBE_ASSIGNMENT;
6284 ch = ';';
6285 /* note: if (is_ifs) continue;
6286 * will still trigger for us */
6287 }
6288 }
6289
6290 /* "cmd}" or "cmd }..." without semicolon or &:
6291 * } is an ordinary char in this case, even inside { cmd; }
6292 * Pathological example: { ""}; } should exec "}" cmd
6293 */
6294 if (ch == '}') {
6295 if (!IS_NULL_CMD(ctx.command) /* cmd } */
6296 || dest.length != 0 /* word} */
6297 || dest.o_quoted /* ""} */
6298 ) {
6299 goto ordinary_char;
6300 }
6301 if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */
6302 goto skip_end_trigger;
6303 /* else: } does terminate a group */
6304 }
6305
6306 if (end_trigger && end_trigger == ch
6307 && (ch != ';' || heredoc_cnt == 0)
6308 #if ENABLE_HUSH_CASE
6309 && (ch != ')'
6310 || ctx.ctx_res_w != RES_MATCH
6311 || (!dest.o_quoted && strcmp(dest.data, "esac") == 0)
6312 )
6313 #endif
6314 ) {
6315 if (heredoc_cnt) {
6316 /* This is technically valid:
6317 * { cat <<HERE; }; echo Ok
6318 * heredoc
6319 * heredoc
6320 * HERE
6321 * but we don't support this.
6322 * We require heredoc to be in enclosing {}/(),
6323 * if any.
6324 */
6325 syntax_error_unterm_str("here document");
6326 goto parse_error;
6327 }
6328 if (done_word(&dest, &ctx)) {
6329 goto parse_error;
6330 }
6331 done_pipe(&ctx, PIPE_SEQ);
6332 dest.o_assignment = MAYBE_ASSIGNMENT;
6333 /* Do we sit outside of any if's, loops or case's? */
6334 if (!HAS_KEYWORDS
6335 IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
6336 ) {
6337 o_free(&dest);
6338 #if !BB_MMU
6339 debug_printf_parse("as_string '%s'\n", ctx.as_string.data);
6340 if (pstring)
6341 *pstring = ctx.as_string.data;
6342 else
6343 o_free_unsafe(&ctx.as_string);
6344 #endif
6345 debug_leave();
6346 debug_printf_parse("parse_stream return %p: "
6347 "end_trigger char found\n",
6348 ctx.list_head);
6349 return ctx.list_head;
6350 }
6351 }
6352 skip_end_trigger:
6353 if (is_ifs)
6354 continue;
6355
6356 /* Catch <, > before deciding whether this word is
6357 * an assignment. a=1 2>z b=2: b=2 is still assignment */
6358 switch (ch) {
6359 case '>':
6360 redir_fd = redirect_opt_num(&dest);
6361 if (done_word(&dest, &ctx)) {
6362 goto parse_error;
6363 }
6364 redir_style = REDIRECT_OVERWRITE;
6365 if (next == '>') {
6366 redir_style = REDIRECT_APPEND;
6367 ch = i_getch(input);
6368 nommu_addchr(&ctx.as_string, ch);
6369 }
6370 #if 0
6371 else if (next == '(') {
6372 syntax_error(">(process) not supported");
6373 goto parse_error;
6374 }
6375 #endif
6376 if (parse_redirect(&ctx, redir_fd, redir_style, input))
6377 goto parse_error;
6378 continue; /* back to top of while (1) */
6379 case '<':
6380 redir_fd = redirect_opt_num(&dest);
6381 if (done_word(&dest, &ctx)) {
6382 goto parse_error;
6383 }
6384 redir_style = REDIRECT_INPUT;
6385 if (next == '<') {
6386 redir_style = REDIRECT_HEREDOC;
6387 heredoc_cnt++;
6388 debug_printf_parse("++heredoc_cnt=%d\n", heredoc_cnt);
6389 ch = i_getch(input);
6390 nommu_addchr(&ctx.as_string, ch);
6391 } else if (next == '>') {
6392 redir_style = REDIRECT_IO;
6393 ch = i_getch(input);
6394 nommu_addchr(&ctx.as_string, ch);
6395 }
6396 #if 0
6397 else if (next == '(') {
6398 syntax_error("<(process) not supported");
6399 goto parse_error;
6400 }
6401 #endif
6402 if (parse_redirect(&ctx, redir_fd, redir_style, input))
6403 goto parse_error;
6404 continue; /* back to top of while (1) */
6405 }
6406
6407 if (dest.o_assignment == MAYBE_ASSIGNMENT
6408 /* check that we are not in word in "a=1 2>word b=1": */
6409 && !ctx.pending_redirect
6410 ) {
6411 /* ch is a special char and thus this word
6412 * cannot be an assignment */
6413 dest.o_assignment = NOT_ASSIGNMENT;
6414 }
6415
6416 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */
6417
6418 switch (ch) {
6419 case '#':
6420 if (dest.length == 0) {
6421 while (1) {
6422 ch = i_peek(input);
6423 if (ch == EOF || ch == '\n')
6424 break;
6425 i_getch(input);
6426 /* note: we do not add it to &ctx.as_string */
6427 }
6428 nommu_addchr(&ctx.as_string, '\n');
6429 } else {
6430 o_addQchr(&dest, ch);
6431 }
6432 break;
6433 case '\\':
6434 if (next == EOF) {
6435 syntax_error("\\<eof>");
6436 xfunc_die();
6437 }
6438 ch = i_getch(input);
6439 if (ch != '\n') {
6440 o_addchr(&dest, '\\');
6441 /*nommu_addchr(&ctx.as_string, '\\'); - already done */
6442 o_addchr(&dest, ch);
6443 nommu_addchr(&ctx.as_string, ch);
6444 /* Example: echo Hello \2>file
6445 * we need to know that word 2 is quoted */
6446 dest.o_quoted = 1;
6447 }
6448 #if !BB_MMU
6449 else {
6450 /* It's "\<newline>". Remove trailing '\' from ctx.as_string */
6451 ctx.as_string.data[--ctx.as_string.length] = '\0';
6452 }
6453 #endif
6454 break;
6455 case '$':
6456 if (handle_dollar(&ctx.as_string, &dest, input) != 0) {
6457 debug_printf_parse("parse_stream parse error: "
6458 "handle_dollar returned non-0\n");
6459 goto parse_error;
6460 }
6461 break;
6462 case '\'':
6463 dest.o_quoted = 1;
6464 while (1) {
6465 ch = i_getch(input);
6466 if (ch == EOF) {
6467 syntax_error_unterm_ch('\'');
6468 /*xfunc_die(); - redundant */
6469 }
6470 nommu_addchr(&ctx.as_string, ch);
6471 if (ch == '\'')
6472 break;
6473 o_addqchr(&dest, ch);
6474 }
6475 break;
6476 case '"':
6477 dest.o_quoted = 1;
6478 is_in_dquote ^= 1; /* invert */
6479 if (dest.o_assignment == NOT_ASSIGNMENT)
6480 dest.o_escape ^= 1;
6481 break;
6482 #if ENABLE_HUSH_TICK
6483 case '`': {
6484 #if !BB_MMU
6485 int pos;
6486 #endif
6487 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6488 o_addchr(&dest, '`');
6489 #if !BB_MMU
6490 pos = dest.length;
6491 #endif
6492 add_till_backquote(&dest, input);
6493 #if !BB_MMU
6494 o_addstr(&ctx.as_string, dest.data + pos);
6495 o_addchr(&ctx.as_string, '`');
6496 #endif
6497 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6498 //debug_printf_subst("SUBST RES3 '%s'\n", dest.data + pos);
6499 break;
6500 }
6501 #endif
6502 case ';':
6503 #if ENABLE_HUSH_CASE
6504 case_semi:
6505 #endif
6506 if (done_word(&dest, &ctx)) {
6507 goto parse_error;
6508 }
6509 done_pipe(&ctx, PIPE_SEQ);
6510 #if ENABLE_HUSH_CASE
6511 /* Eat multiple semicolons, detect
6512 * whether it means something special */
6513 while (1) {
6514 ch = i_peek(input);
6515 if (ch != ';')
6516 break;
6517 ch = i_getch(input);
6518 nommu_addchr(&ctx.as_string, ch);
6519 if (ctx.ctx_res_w == RES_CASE_BODY) {
6520 ctx.ctx_dsemicolon = 1;
6521 ctx.ctx_res_w = RES_MATCH;
6522 break;
6523 }
6524 }
6525 #endif
6526 new_cmd:
6527 /* We just finished a cmd. New one may start
6528 * with an assignment */
6529 dest.o_assignment = MAYBE_ASSIGNMENT;
6530 break;
6531 case '&':
6532 if (done_word(&dest, &ctx)) {
6533 goto parse_error;
6534 }
6535 if (next == '&') {
6536 ch = i_getch(input);
6537 nommu_addchr(&ctx.as_string, ch);
6538 done_pipe(&ctx, PIPE_AND);
6539 } else {
6540 done_pipe(&ctx, PIPE_BG);
6541 }
6542 goto new_cmd;
6543 case '|':
6544 if (done_word(&dest, &ctx)) {
6545 goto parse_error;
6546 }
6547 #if ENABLE_HUSH_CASE
6548 if (ctx.ctx_res_w == RES_MATCH)
6549 break; /* we are in case's "word | word)" */
6550 #endif
6551 if (next == '|') { /* || */
6552 ch = i_getch(input);
6553 nommu_addchr(&ctx.as_string, ch);
6554 done_pipe(&ctx, PIPE_OR);
6555 } else {
6556 /* we could pick up a file descriptor choice here
6557 * with redirect_opt_num(), but bash doesn't do it.
6558 * "echo foo 2| cat" yields "foo 2". */
6559 done_command(&ctx);
6560 #if !BB_MMU
6561 o_reset_to_empty_unquoted(&ctx.as_string);
6562 #endif
6563 }
6564 goto new_cmd;
6565 case '(':
6566 #if ENABLE_HUSH_CASE
6567 /* "case... in [(]word)..." - skip '(' */
6568 if (ctx.ctx_res_w == RES_MATCH
6569 && ctx.command->argv == NULL /* not (word|(... */
6570 && dest.length == 0 /* not word(... */
6571 && dest.o_quoted == 0 /* not ""(... */
6572 ) {
6573 continue;
6574 }
6575 #endif
6576 case '{':
6577 if (parse_group(&dest, &ctx, input, ch) != 0) {
6578 goto parse_error;
6579 }
6580 goto new_cmd;
6581 case ')':
6582 #if ENABLE_HUSH_CASE
6583 if (ctx.ctx_res_w == RES_MATCH)
6584 goto case_semi;
6585 #endif
6586 case '}':
6587 /* proper use of this character is caught by end_trigger:
6588 * if we see {, we call parse_group(..., end_trigger='}')
6589 * and it will match } earlier (not here). */
6590 syntax_error_unexpected_ch(ch);
6591 goto parse_error;
6592 default:
6593 if (HUSH_DEBUG)
6594 bb_error_msg_and_die("BUG: unexpected %c\n", ch);
6595 }
6596 } /* while (1) */
6597
6598 parse_error:
6599 {
6600 struct parse_context *pctx;
6601 IF_HAS_KEYWORDS(struct parse_context *p2;)
6602
6603 /* Clean up allocated tree.
6604 * Sample for finding leaks on syntax error recovery path.
6605 * Run it from interactive shell, watch pmap `pidof hush`.
6606 * while if false; then false; fi; do break; fi
6607 * Samples to catch leaks at execution:
6608 * while if (true | {true;}); then echo ok; fi; do break; done
6609 * while if (true | {true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done
6610 */
6611 pctx = &ctx;
6612 do {
6613 /* Update pipe/command counts,
6614 * otherwise freeing may miss some */
6615 done_pipe(pctx, PIPE_SEQ);
6616 debug_printf_clean("freeing list %p from ctx %p\n",
6617 pctx->list_head, pctx);
6618 debug_print_tree(pctx->list_head, 0);
6619 free_pipe_list(pctx->list_head);
6620 debug_printf_clean("freed list %p\n", pctx->list_head);
6621 #if !BB_MMU
6622 o_free_unsafe(&pctx->as_string);
6623 #endif
6624 IF_HAS_KEYWORDS(p2 = pctx->stack;)
6625 if (pctx != &ctx) {
6626 free(pctx);
6627 }
6628 IF_HAS_KEYWORDS(pctx = p2;)
6629 } while (HAS_KEYWORDS && pctx);
6630 /* Free text, clear all dest fields */
6631 o_free(&dest);
6632 /* If we are not in top-level parse, we return,
6633 * our caller will propagate error.
6634 */
6635 if (end_trigger != ';') {
6636 #if !BB_MMU
6637 if (pstring)
6638 *pstring = NULL;
6639 #endif
6640 debug_leave();
6641 return ERR_PTR;
6642 }
6643 /* Discard cached input, force prompt */
6644 input->p = NULL;
6645 IF_HUSH_INTERACTIVE(input->promptme = 1;)
6646 goto reset;
6647 }
6648 }
6649
6650 /* Executing from string: eval, sh -c '...'
6651 * or from file: /etc/profile, . file, sh <script>, sh (intereactive)
6652 * end_trigger controls how often we stop parsing
6653 * NUL: parse all, execute, return
6654 * ';': parse till ';' or newline, execute, repeat till EOF
6655 */
6656 static void parse_and_run_stream(struct in_str *inp, int end_trigger)
6657 {
6658 /* Why we need empty flag?
6659 * An obscure corner case "false; ``; echo $?":
6660 * empty command in `` should still set $? to 0.
6661 * But we can't just set $? to 0 at the start,
6662 * this breaks "false; echo `echo $?`" case.
6663 */
6664 bool empty = 1;
6665 while (1) {
6666 struct pipe *pipe_list;
6667
6668 pipe_list = parse_stream(NULL, inp, end_trigger);
6669 if (!pipe_list) { /* EOF */
6670 if (empty)
6671 G.last_exitcode = 0;
6672 break;
6673 }
6674 debug_print_tree(pipe_list, 0);
6675 debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
6676 run_and_free_list(pipe_list);
6677 empty = 0;
6678 }
6679 }
6680
6681 static void parse_and_run_string(const char *s)
6682 {
6683 struct in_str input;
6684 setup_string_in_str(&input, s);
6685 parse_and_run_stream(&input, '\0');
6686 }
6687
6688 static void parse_and_run_file(FILE *f)
6689 {
6690 struct in_str input;
6691 setup_file_in_str(&input, f);
6692 parse_and_run_stream(&input, ';');
6693 }
6694
6695 /* Called a few times only (or even once if "sh -c") */
6696 static void init_sigmasks(void)
6697 {
6698 unsigned sig;
6699 unsigned mask;
6700 sigset_t old_blocked_set;
6701
6702 if (!G.inherited_set_is_saved) {
6703 sigprocmask(SIG_SETMASK, NULL, &G.blocked_set);
6704 G.inherited_set = G.blocked_set;
6705 }
6706 old_blocked_set = G.blocked_set;
6707
6708 mask = (1 << SIGQUIT);
6709 if (G_interactive_fd) {
6710 mask = (1 << SIGQUIT) | SPECIAL_INTERACTIVE_SIGS;
6711 if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */
6712 mask |= SPECIAL_JOB_SIGS;
6713 }
6714 G.non_DFL_mask = mask;
6715
6716 sig = 0;
6717 while (mask) {
6718 if (mask & 1)
6719 sigaddset(&G.blocked_set, sig);
6720 mask >>= 1;
6721 sig++;
6722 }
6723 sigdelset(&G.blocked_set, SIGCHLD);
6724
6725 if (memcmp(&old_blocked_set, &G.blocked_set, sizeof(old_blocked_set)) != 0)
6726 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
6727
6728 /* POSIX allows shell to re-enable SIGCHLD
6729 * even if it was SIG_IGN on entry */
6730 #if ENABLE_HUSH_FAST
6731 G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */
6732 if (!G.inherited_set_is_saved)
6733 signal(SIGCHLD, SIGCHLD_handler);
6734 #else
6735 if (!G.inherited_set_is_saved)
6736 signal(SIGCHLD, SIG_DFL);
6737 #endif
6738
6739 G.inherited_set_is_saved = 1;
6740 }
6741
6742 #if ENABLE_HUSH_JOB
6743 /* helper */
6744 static void maybe_set_to_sigexit(int sig)
6745 {
6746 void (*handler)(int);
6747 /* non_DFL_mask'ed signals are, well, masked,
6748 * no need to set handler for them.
6749 */
6750 if (!((G.non_DFL_mask >> sig) & 1)) {
6751 handler = signal(sig, sigexit);
6752 if (handler == SIG_IGN) /* oops... restore back to IGN! */
6753 signal(sig, handler);
6754 }
6755 }
6756 /* Set handlers to restore tty pgrp and exit */
6757 static void set_fatal_handlers(void)
6758 {
6759 /* We _must_ restore tty pgrp on fatal signals */
6760 if (HUSH_DEBUG) {
6761 maybe_set_to_sigexit(SIGILL );
6762 maybe_set_to_sigexit(SIGFPE );
6763 maybe_set_to_sigexit(SIGBUS );
6764 maybe_set_to_sigexit(SIGSEGV);
6765 maybe_set_to_sigexit(SIGTRAP);
6766 } /* else: hush is perfect. what SEGV? */
6767 maybe_set_to_sigexit(SIGABRT);
6768 /* bash 3.2 seems to handle these just like 'fatal' ones */
6769 maybe_set_to_sigexit(SIGPIPE);
6770 maybe_set_to_sigexit(SIGALRM);
6771 /* if we are interactive, SIGHUP, SIGTERM and SIGINT are masked.
6772 * if we aren't interactive... but in this case
6773 * we never want to restore pgrp on exit, and this fn is not called */
6774 /*maybe_set_to_sigexit(SIGHUP );*/
6775 /*maybe_set_to_sigexit(SIGTERM);*/
6776 /*maybe_set_to_sigexit(SIGINT );*/
6777 }
6778 #endif
6779
6780 static int set_mode(const char cstate, const char mode)
6781 {
6782 int state = (cstate == '-' ? 1 : 0);
6783 switch (mode) {
6784 case 'n': G.fake_mode = state; break;
6785 case 'x': /*G.debug_mode = state;*/ break;
6786 default: return EXIT_FAILURE;
6787 }
6788 return EXIT_SUCCESS;
6789 }
6790
6791 int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
6792 int hush_main(int argc, char **argv)
6793 {
6794 static const struct variable const_shell_ver = {
6795 .next = NULL,
6796 .varstr = (char*)hush_version_str,
6797 .max_len = 1, /* 0 can provoke free(name) */
6798 .flg_export = 1,
6799 .flg_read_only = 1,
6800 };
6801 int opt;
6802 unsigned builtin_argc;
6803 char **e;
6804 struct variable *cur_var;
6805
6806 INIT_G();
6807 if (EXIT_SUCCESS) /* if EXIT_SUCCESS == 0, is already done */
6808 G.last_exitcode = EXIT_SUCCESS;
6809 #if !BB_MMU
6810 G.argv0_for_re_execing = argv[0];
6811 #endif
6812 /* Deal with HUSH_VERSION */
6813 G.shell_ver = const_shell_ver; /* copying struct here */
6814 G.top_var = &G.shell_ver;
6815 debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
6816 unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
6817 /* Initialize our shell local variables with the values
6818 * currently living in the environment */
6819 cur_var = G.top_var;
6820 e = environ;
6821 if (e) while (*e) {
6822 char *value = strchr(*e, '=');
6823 if (value) { /* paranoia */
6824 cur_var->next = xzalloc(sizeof(*cur_var));
6825 cur_var = cur_var->next;
6826 cur_var->varstr = *e;
6827 cur_var->max_len = strlen(*e);
6828 cur_var->flg_export = 1;
6829 }
6830 e++;
6831 }
6832 /* reinstate HUSH_VERSION */
6833 debug_printf_env("putenv '%s'\n", hush_version_str);
6834 putenv((char *)hush_version_str);
6835
6836 /* Export PWD */
6837 set_pwd_var(/*exp:*/ 1);
6838 /* bash also exports SHLVL and _,
6839 * and sets (but doesn't export) the following variables:
6840 * BASH=/bin/bash
6841 * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu")
6842 * BASH_VERSION='3.2.0(1)-release'
6843 * HOSTTYPE=i386
6844 * MACHTYPE=i386-pc-linux-gnu
6845 * OSTYPE=linux-gnu
6846 * HOSTNAME=<xxxxxxxxxx>
6847 * PPID=<NNNNN> - we also do it elsewhere
6848 * EUID=<NNNNN>
6849 * UID=<NNNNN>
6850 * GROUPS=()
6851 * LINES=<NNN>
6852 * COLUMNS=<NNN>
6853 * BASH_ARGC=()
6854 * BASH_ARGV=()
6855 * BASH_LINENO=()
6856 * BASH_SOURCE=()
6857 * DIRSTACK=()
6858 * PIPESTATUS=([0]="0")
6859 * HISTFILE=/<xxx>/.bash_history
6860 * HISTFILESIZE=500
6861 * HISTSIZE=500
6862 * MAILCHECK=60
6863 * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
6864 * SHELL=/bin/bash
6865 * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
6866 * TERM=dumb
6867 * OPTERR=1
6868 * OPTIND=1
6869 * IFS=$' \t\n'
6870 * PS1='\s-\v\$ '
6871 * PS2='> '
6872 * PS4='+ '
6873 */
6874
6875 #if ENABLE_FEATURE_EDITING
6876 G.line_input_state = new_line_input_t(FOR_SHELL);
6877 #endif
6878 G.global_argc = argc;
6879 G.global_argv = argv;
6880 /* Initialize some more globals to non-zero values */
6881 cmdedit_update_prompt();
6882
6883 if (setjmp(die_jmp)) {
6884 /* xfunc has failed! die die die */
6885 /* no EXIT traps, this is an escape hatch! */
6886 G.exiting = 1;
6887 hush_exit(xfunc_error_retval);
6888 }
6889
6890 /* Shell is non-interactive at first. We need to call
6891 * init_sigmasks() if we are going to execute "sh <script>",
6892 * "sh -c <cmds>" or login shell's /etc/profile and friends.
6893 * If we later decide that we are interactive, we run init_sigmasks()
6894 * in order to intercept (more) signals.
6895 */
6896
6897 /* Parse options */
6898 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
6899 builtin_argc = 0;
6900 while (1) {
6901 opt = getopt(argc, argv, "+c:xins"
6902 #if !BB_MMU
6903 "<:$:R:V:"
6904 # if ENABLE_HUSH_FUNCTIONS
6905 "F:"
6906 # endif
6907 #endif
6908 );
6909 if (opt <= 0)
6910 break;
6911 switch (opt) {
6912 case 'c':
6913 /* Possibilities:
6914 * sh ... -c 'script'
6915 * sh ... -c 'script' ARG0 [ARG1...]
6916 * On NOMMU, if builtin_argc != 0,
6917 * sh ... -c 'builtin' [BARGV...] "" ARG0 [ARG1...]
6918 * "" needs to be replaced with NULL
6919 * and BARGV vector fed to builtin function.
6920 * Note: this form never happens:
6921 * sh ... -c 'builtin' [BARGV...] ""
6922 */
6923 if (!G.root_pid) {
6924 G.root_pid = getpid();
6925 G.root_ppid = getppid();
6926 }
6927 G.global_argv = argv + optind;
6928 G.global_argc = argc - optind;
6929 if (builtin_argc) {
6930 /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */
6931 const struct built_in_command *x;
6932
6933 init_sigmasks();
6934 x = find_builtin(optarg);
6935 if (x) { /* paranoia */
6936 G.global_argc -= builtin_argc; /* skip [BARGV...] "" */
6937 G.global_argv += builtin_argc;
6938 G.global_argv[-1] = NULL; /* replace "" */
6939 G.last_exitcode = x->function(argv + optind - 1);
6940 }
6941 goto final_return;
6942 }
6943 if (!G.global_argv[0]) {
6944 /* -c 'script' (no params): prevent empty $0 */
6945 G.global_argv--; /* points to argv[i] of 'script' */
6946 G.global_argv[0] = argv[0];
6947 G.global_argc++;
6948 } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */
6949 init_sigmasks();
6950 parse_and_run_string(optarg);
6951 goto final_return;
6952 case 'i':
6953 /* Well, we cannot just declare interactiveness,
6954 * we have to have some stuff (ctty, etc) */
6955 /* G_interactive_fd++; */
6956 break;
6957 case 's':
6958 /* "-s" means "read from stdin", but this is how we always
6959 * operate, so simply do nothing here. */
6960 break;
6961 #if !BB_MMU
6962 case '<': /* "big heredoc" support */
6963 full_write(STDOUT_FILENO, optarg, strlen(optarg));
6964 _exit(0);
6965 case '$': {
6966 unsigned long long empty_trap_mask;
6967
6968 G.root_pid = bb_strtou(optarg, &optarg, 16);
6969 optarg++;
6970 G.root_ppid = bb_strtou(optarg, &optarg, 16);
6971 optarg++;
6972 G.last_bg_pid = bb_strtou(optarg, &optarg, 16);
6973 optarg++;
6974 G.last_exitcode = bb_strtou(optarg, &optarg, 16);
6975 optarg++;
6976 builtin_argc = bb_strtou(optarg, &optarg, 16);
6977 optarg++;
6978 empty_trap_mask = bb_strtoull(optarg, &optarg, 16);
6979 if (empty_trap_mask != 0) {
6980 int sig;
6981 init_sigmasks();
6982 G.traps = xzalloc(sizeof(G.traps[0]) * NSIG);
6983 for (sig = 1; sig < NSIG; sig++) {
6984 if (empty_trap_mask & (1LL << sig)) {
6985 G.traps[sig] = xzalloc(1); /* == xstrdup(""); */
6986 sigaddset(&G.blocked_set, sig);
6987 }
6988 }
6989 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
6990 }
6991 # if ENABLE_HUSH_LOOPS
6992 optarg++;
6993 G.depth_of_loop = bb_strtou(optarg, &optarg, 16);
6994 # endif
6995 break;
6996 }
6997 case 'R':
6998 case 'V':
6999 set_local_var(xstrdup(optarg), /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ opt == 'R');
7000 break;
7001 # if ENABLE_HUSH_FUNCTIONS
7002 case 'F': {
7003 struct function *funcp = new_function(optarg);
7004 /* funcp->name is already set to optarg */
7005 /* funcp->body is set to NULL. It's a special case. */
7006 funcp->body_as_string = argv[optind];
7007 optind++;
7008 break;
7009 }
7010 # endif
7011 #endif
7012 case 'n':
7013 case 'x':
7014 if (!set_mode('-', opt))
7015 break;
7016 default:
7017 #ifndef BB_VER
7018 fprintf(stderr, "Usage: sh [FILE]...\n"
7019 " or: sh -c command [args]...\n\n");
7020 exit(EXIT_FAILURE);
7021 #else
7022 bb_show_usage();
7023 #endif
7024 }
7025 } /* option parsing loop */
7026
7027 if (!G.root_pid) {
7028 G.root_pid = getpid();
7029 G.root_ppid = getppid();
7030 }
7031
7032 /* If we are login shell... */
7033 if (argv[0] && argv[0][0] == '-') {
7034 FILE *input;
7035 debug_printf("sourcing /etc/profile\n");
7036 input = fopen_for_read("/etc/profile");
7037 if (input != NULL) {
7038 close_on_exec_on(fileno(input));
7039 init_sigmasks();
7040 parse_and_run_file(input);
7041 fclose(input);
7042 }
7043 /* bash: after sourcing /etc/profile,
7044 * tries to source (in the given order):
7045 * ~/.bash_profile, ~/.bash_login, ~/.profile,
7046 * stopping on first found. --noprofile turns this off.
7047 * bash also sources ~/.bash_logout on exit.
7048 * If called as sh, skips .bash_XXX files.
7049 */
7050 }
7051
7052 if (argv[optind]) {
7053 FILE *input;
7054 /*
7055 * "bash <script>" (which is never interactive (unless -i?))
7056 * sources $BASH_ENV here (without scanning $PATH).
7057 * If called as sh, does the same but with $ENV.
7058 */
7059 debug_printf("running script '%s'\n", argv[optind]);
7060 G.global_argv = argv + optind;
7061 G.global_argc = argc - optind;
7062 input = xfopen_for_read(argv[optind]);
7063 close_on_exec_on(fileno(input));
7064 init_sigmasks();
7065 parse_and_run_file(input);
7066 #if ENABLE_FEATURE_CLEAN_UP
7067 fclose(input);
7068 #endif
7069 goto final_return;
7070 }
7071
7072 /* Up to here, shell was non-interactive. Now it may become one.
7073 * NB: don't forget to (re)run init_sigmasks() as needed.
7074 */
7075
7076 /* A shell is interactive if the '-i' flag was given,
7077 * or if all of the following conditions are met:
7078 * no -c command
7079 * no arguments remaining or the -s flag given
7080 * standard input is a terminal
7081 * standard output is a terminal
7082 * Refer to Posix.2, the description of the 'sh' utility.
7083 */
7084 #if ENABLE_HUSH_JOB
7085 if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
7086 G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
7087 debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp);
7088 if (G_saved_tty_pgrp < 0)
7089 G_saved_tty_pgrp = 0;
7090
7091 /* try to dup stdin to high fd#, >= 255 */
7092 G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255);
7093 if (G_interactive_fd < 0) {
7094 /* try to dup to any fd */
7095 G_interactive_fd = dup(STDIN_FILENO);
7096 if (G_interactive_fd < 0) {
7097 /* give up */
7098 G_interactive_fd = 0;
7099 G_saved_tty_pgrp = 0;
7100 }
7101 }
7102 // TODO: track & disallow any attempts of user
7103 // to (inadvertently) close/redirect G_interactive_fd
7104 }
7105 debug_printf("interactive_fd:%d\n", G_interactive_fd);
7106 if (G_interactive_fd) {
7107 close_on_exec_on(G_interactive_fd);
7108
7109 if (G_saved_tty_pgrp) {
7110 /* If we were run as 'hush &', sleep until we are
7111 * in the foreground (tty pgrp == our pgrp).
7112 * If we get started under a job aware app (like bash),
7113 * make sure we are now in charge so we don't fight over
7114 * who gets the foreground */
7115 while (1) {
7116 pid_t shell_pgrp = getpgrp();
7117 G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd);
7118 if (G_saved_tty_pgrp == shell_pgrp)
7119 break;
7120 /* send TTIN to ourself (should stop us) */
7121 kill(- shell_pgrp, SIGTTIN);
7122 }
7123 }
7124
7125 /* Block some signals */
7126 init_sigmasks();
7127
7128 if (G_saved_tty_pgrp) {
7129 /* Set other signals to restore saved_tty_pgrp */
7130 set_fatal_handlers();
7131 /* Put ourselves in our own process group
7132 * (bash, too, does this only if ctty is available) */
7133 bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
7134 /* Grab control of the terminal */
7135 tcsetpgrp(G_interactive_fd, getpid());
7136 }
7137 /* -1 is special - makes xfuncs longjmp, not exit
7138 * (we reset die_sleep = 0 whereever we [v]fork) */
7139 enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */
7140 } else {
7141 init_sigmasks();
7142 }
7143 #elif ENABLE_HUSH_INTERACTIVE
7144 /* No job control compiled in, only prompt/line editing */
7145 if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
7146 G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255);
7147 if (G_interactive_fd < 0) {
7148 /* try to dup to any fd */
7149 G_interactive_fd = dup(STDIN_FILENO);
7150 if (G_interactive_fd < 0)
7151 /* give up */
7152 G_interactive_fd = 0;
7153 }
7154 }
7155 if (G_interactive_fd) {
7156 close_on_exec_on(G_interactive_fd);
7157 }
7158 init_sigmasks();
7159 #else
7160 /* We have interactiveness code disabled */
7161 init_sigmasks();
7162 #endif
7163 /* bash:
7164 * if interactive but not a login shell, sources ~/.bashrc
7165 * (--norc turns this off, --rcfile <file> overrides)
7166 */
7167
7168 if (!ENABLE_FEATURE_SH_EXTRA_QUIET && G_interactive_fd) {
7169 /* note: ash and hush share this string */
7170 printf("\n\n%s %s\n"
7171 IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n")
7172 "\n",
7173 bb_banner,
7174 "hush - the humble shell"
7175 );
7176 }
7177
7178 parse_and_run_file(stdin);
7179
7180 final_return:
7181 #if ENABLE_FEATURE_CLEAN_UP
7182 if (G.cwd != bb_msg_unknown)
7183 free((char*)G.cwd);
7184 cur_var = G.top_var->next;
7185 while (cur_var) {
7186 struct variable *tmp = cur_var;
7187 if (!cur_var->max_len)
7188 free(cur_var->varstr);
7189 cur_var = cur_var->next;
7190 free(tmp);
7191 }
7192 #endif
7193 hush_exit(G.last_exitcode);
7194 }
7195
7196
7197 #if ENABLE_LASH
7198 int lash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
7199 int lash_main(int argc, char **argv)
7200 {
7201 bb_error_msg("lash is deprecated, please use hush instead");
7202 return hush_main(argc, argv);
7203 }
7204 #endif
7205
7206 #if ENABLE_MSH
7207 int msh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
7208 int msh_main(int argc, char **argv)
7209 {
7210 //bb_error_msg("msh is deprecated, please use hush instead");
7211 return hush_main(argc, argv);
7212 }
7213 #endif
7214
7215
7216 /*
7217 * Built-ins
7218 */
7219 static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM)
7220 {
7221 return 0;
7222 }
7223
7224 static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv))
7225 {
7226 int argc = 0;
7227 while (*argv) {
7228 argc++;
7229 argv++;
7230 }
7231 return applet_main_func(argc, argv - argc);
7232 }
7233
7234 static int FAST_FUNC builtin_test(char **argv)
7235 {
7236 return run_applet_main(argv, test_main);
7237 }
7238
7239 static int FAST_FUNC builtin_echo(char **argv)
7240 {
7241 return run_applet_main(argv, echo_main);
7242 }
7243
7244 #if ENABLE_PRINTF
7245 static int FAST_FUNC builtin_printf(char **argv)
7246 {
7247 return run_applet_main(argv, printf_main);
7248 }
7249 #endif
7250
7251 static int FAST_FUNC builtin_eval(char **argv)
7252 {
7253 int rcode = EXIT_SUCCESS;
7254
7255 if (*++argv) {
7256 char *str = expand_strvec_to_string(argv);
7257 /* bash:
7258 * eval "echo Hi; done" ("done" is syntax error):
7259 * "echo Hi" will not execute too.
7260 */
7261 parse_and_run_string(str);
7262 free(str);
7263 rcode = G.last_exitcode;
7264 }
7265 return rcode;
7266 }
7267
7268 static int FAST_FUNC builtin_cd(char **argv)
7269 {
7270 const char *newdir = argv[1];
7271 if (newdir == NULL) {
7272 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
7273 * bash says "bash: cd: HOME not set" and does nothing
7274 * (exitcode 1)
7275 */
7276 const char *home = get_local_var_value("HOME");
7277 newdir = home ? home : "/";
7278 }
7279 if (chdir(newdir)) {
7280 /* Mimic bash message exactly */
7281 bb_perror_msg("cd: %s", newdir);
7282 return EXIT_FAILURE;
7283 }
7284 /* Read current dir (get_cwd(1) is inside) and set PWD.
7285 * Note: do not enforce exporting. If PWD was unset or unexported,
7286 * set it again, but do not export. bash does the same.
7287 */
7288 set_pwd_var(/*exp:*/ 0);
7289 return EXIT_SUCCESS;
7290 }
7291
7292 static int FAST_FUNC builtin_exec(char **argv)
7293 {
7294 if (*++argv == NULL)
7295 return EXIT_SUCCESS; /* bash does this */
7296
7297 /* Careful: we can end up here after [v]fork. Do not restore
7298 * tty pgrp then, only top-level shell process does that */
7299 if (G_saved_tty_pgrp && getpid() == G.root_pid)
7300 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
7301
7302 /* TODO: if exec fails, bash does NOT exit! We do.
7303 * We'll need to undo sigprocmask (it's inside execvp_or_die)
7304 * and tcsetpgrp, and this is inherently racy.
7305 */
7306 execvp_or_die(argv);
7307 }
7308
7309 static int FAST_FUNC builtin_exit(char **argv)
7310 {
7311 debug_printf_exec("%s()\n", __func__);
7312
7313 /* interactive bash:
7314 * # trap "echo EEE" EXIT
7315 * # exit
7316 * exit
7317 * There are stopped jobs.
7318 * (if there are _stopped_ jobs, running ones don't count)
7319 * # exit
7320 * exit
7321 # EEE (then bash exits)
7322 *
7323 * we can use G.exiting = -1 as indicator "last cmd was exit"
7324 */
7325
7326 /* note: EXIT trap is run by hush_exit */
7327 if (*++argv == NULL)
7328 hush_exit(G.last_exitcode);
7329 /* mimic bash: exit 123abc == exit 255 + error msg */
7330 xfunc_error_retval = 255;
7331 /* bash: exit -2 == exit 254, no error msg */
7332 hush_exit(xatoi(*argv) & 0xff);
7333 }
7334
7335 static void print_escaped(const char *s)
7336 {
7337 if (*s == '\'')
7338 goto squote;
7339 do {
7340 const char *p = strchrnul(s, '\'');
7341 /* print 'xxxx', possibly just '' */
7342 printf("'%.*s'", (int)(p - s), s);
7343 if (*p == '\0')
7344 break;
7345 s = p;
7346 squote:
7347 /* s points to '; print "'''...'''" */
7348 putchar('"');
7349 do putchar('\''); while (*++s == '\'');
7350 putchar('"');
7351 } while (*s);
7352 }
7353
7354 #if !ENABLE_HUSH_LOCAL
7355 #define helper_export_local(argv, exp, lvl) \
7356 helper_export_local(argv, exp)
7357 #endif
7358 static void helper_export_local(char **argv, int exp, int lvl)
7359 {
7360 do {
7361 char *name = *argv;
7362
7363 /* So far we do not check that name is valid (TODO?) */
7364
7365 if (strchr(name, '=') == NULL) {
7366 struct variable *var;
7367
7368 var = get_local_var(name);
7369 if (exp == -1) { /* unexporting? */
7370 /* export -n NAME (without =VALUE) */
7371 if (var) {
7372 var->flg_export = 0;
7373 debug_printf_env("%s: unsetenv '%s'\n", __func__, name);
7374 unsetenv(name);
7375 } /* else: export -n NOT_EXISTING_VAR: no-op */
7376 continue;
7377 }
7378 if (exp == 1) { /* exporting? */
7379 /* export NAME (without =VALUE) */
7380 if (var) {
7381 var->flg_export = 1;
7382 debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
7383 putenv(var->varstr);
7384 continue;
7385 }
7386 }
7387 /* Exporting non-existing variable.
7388 * bash does not put it in environment,
7389 * but remembers that it is exported,
7390 * and does put it in env when it is set later.
7391 * We just set it to "" and export. */
7392 /* Or, it's "local NAME" (without =VALUE).
7393 * bash sets the value to "". */
7394 name = xasprintf("%s=", name);
7395 } else {
7396 /* (Un)exporting/making local NAME=VALUE */
7397 name = xstrdup(name);
7398 }
7399 set_local_var(name, /*exp:*/ exp, /*lvl:*/ lvl, /*ro:*/ 0);
7400 } while (*++argv);
7401 }
7402
7403 static int FAST_FUNC builtin_export(char **argv)
7404 {
7405 unsigned opt_unexport;
7406
7407 #if ENABLE_HUSH_EXPORT_N
7408 /* "!": do not abort on errors */
7409 opt_unexport = getopt32(argv, "!n");
7410 if (opt_unexport == (uint32_t)-1)
7411 return EXIT_FAILURE;
7412 argv += optind;
7413 #else
7414 opt_unexport = 0;
7415 argv++;
7416 #endif
7417
7418 if (argv[0] == NULL) {
7419 char **e = environ;
7420 if (e) {
7421 while (*e) {
7422 #if 0
7423 puts(*e++);
7424 #else
7425 /* ash emits: export VAR='VAL'
7426 * bash: declare -x VAR="VAL"
7427 * we follow ash example */
7428 const char *s = *e++;
7429 const char *p = strchr(s, '=');
7430
7431 if (!p) /* wtf? take next variable */
7432 continue;
7433 /* export var= */
7434 printf("export %.*s", (int)(p - s) + 1, s);
7435 print_escaped(p + 1);
7436 putchar('\n');
7437 #endif
7438 }
7439 /*fflush_all(); - done after each builtin anyway */
7440 }
7441 return EXIT_SUCCESS;
7442 }
7443
7444 helper_export_local(argv, (opt_unexport ? -1 : 1), 0);
7445
7446 return EXIT_SUCCESS;
7447 }
7448
7449 #if ENABLE_HUSH_LOCAL
7450 static int FAST_FUNC builtin_local(char **argv)
7451 {
7452 if (G.func_nest_level == 0) {
7453 bb_error_msg("%s: not in a function", argv[0]);
7454 return EXIT_FAILURE; /* bash compat */
7455 }
7456 helper_export_local(argv, 0, G.func_nest_level);
7457 return EXIT_SUCCESS;
7458 }
7459 #endif
7460
7461 static int FAST_FUNC builtin_trap(char **argv)
7462 {
7463 int sig;
7464 char *new_cmd;
7465
7466 if (!G.traps)
7467 G.traps = xzalloc(sizeof(G.traps[0]) * NSIG);
7468
7469 argv++;
7470 if (!*argv) {
7471 int i;
7472 /* No args: print all trapped */
7473 for (i = 0; i < NSIG; ++i) {
7474 if (G.traps[i]) {
7475 printf("trap -- ");
7476 print_escaped(G.traps[i]);
7477 /* note: bash adds "SIG", but only if invoked
7478 * as "bash". If called as "sh", or if set -o posix,
7479 * then it prints short signal names.
7480 * We are printing short names: */
7481 printf(" %s\n", get_signame(i));
7482 }
7483 }
7484 /*fflush_all(); - done after each builtin anyway */
7485 return EXIT_SUCCESS;
7486 }
7487
7488 new_cmd = NULL;
7489 /* If first arg is a number: reset all specified signals */
7490 sig = bb_strtou(*argv, NULL, 10);
7491 if (errno == 0) {
7492 int ret;
7493 process_sig_list:
7494 ret = EXIT_SUCCESS;
7495 while (*argv) {
7496 sig = get_signum(*argv++);
7497 if (sig < 0 || sig >= NSIG) {
7498 ret = EXIT_FAILURE;
7499 /* Mimic bash message exactly */
7500 bb_perror_msg("trap: %s: invalid signal specification", argv[-1]);
7501 continue;
7502 }
7503
7504 free(G.traps[sig]);
7505 G.traps[sig] = xstrdup(new_cmd);
7506
7507 debug_printf("trap: setting SIG%s (%i) to '%s'\n",
7508 get_signame(sig), sig, G.traps[sig]);
7509
7510 /* There is no signal for 0 (EXIT) */
7511 if (sig == 0)
7512 continue;
7513
7514 if (new_cmd) {
7515 sigaddset(&G.blocked_set, sig);
7516 } else {
7517 /* There was a trap handler, we are removing it
7518 * (if sig has non-DFL handling,
7519 * we don't need to do anything) */
7520 if (sig < 32 && (G.non_DFL_mask & (1 << sig)))
7521 continue;
7522 sigdelset(&G.blocked_set, sig);
7523 }
7524 }
7525 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
7526 return ret;
7527 }
7528
7529 if (!argv[1]) { /* no second arg */
7530 bb_error_msg("trap: invalid arguments");
7531 return EXIT_FAILURE;
7532 }
7533
7534 /* First arg is "-": reset all specified to default */
7535 /* First arg is "--": skip it, the rest is "handler SIGs..." */
7536 /* Everything else: set arg as signal handler
7537 * (includes "" case, which ignores signal) */
7538 if (argv[0][0] == '-') {
7539 if (argv[0][1] == '\0') { /* "-" */
7540 /* new_cmd remains NULL: "reset these sigs" */
7541 goto reset_traps;
7542 }
7543 if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */
7544 argv++;
7545 }
7546 /* else: "-something", no special meaning */
7547 }
7548 new_cmd = *argv;
7549 reset_traps:
7550 argv++;
7551 goto process_sig_list;
7552 }
7553
7554 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
7555 static int FAST_FUNC builtin_type(char **argv)
7556 {
7557 int ret = EXIT_SUCCESS;
7558
7559 while (*++argv) {
7560 const char *type;
7561 char *path = NULL;
7562
7563 if (0) {} /* make conditional compile easier below */
7564 /*else if (find_alias(*argv))
7565 type = "an alias";*/
7566 #if ENABLE_HUSH_FUNCTIONS
7567 else if (find_function(*argv))
7568 type = "a function";
7569 #endif
7570 else if (find_builtin(*argv))
7571 type = "a shell builtin";
7572 else if ((path = find_in_path(*argv)) != NULL)
7573 type = path;
7574 else {
7575 bb_error_msg("type: %s: not found", *argv);
7576 ret = EXIT_FAILURE;
7577 continue;
7578 }
7579
7580 printf("%s is %s\n", *argv, type);
7581 free(path);
7582 }
7583
7584 return ret;
7585 }
7586
7587 #if ENABLE_HUSH_JOB
7588 /* built-in 'fg' and 'bg' handler */
7589 static int FAST_FUNC builtin_fg_bg(char **argv)
7590 {
7591 int i, jobnum;
7592 struct pipe *pi;
7593
7594 if (!G_interactive_fd)
7595 return EXIT_FAILURE;
7596
7597 /* If they gave us no args, assume they want the last backgrounded task */
7598 if (!argv[1]) {
7599 for (pi = G.job_list; pi; pi = pi->next) {
7600 if (pi->jobid == G.last_jobid) {
7601 goto found;
7602 }
7603 }
7604 bb_error_msg("%s: no current job", argv[0]);
7605 return EXIT_FAILURE;
7606 }
7607 if (sscanf(argv[1], "%%%d", &jobnum) != 1) {
7608 bb_error_msg("%s: bad argument '%s'", argv[0], argv[1]);
7609 return EXIT_FAILURE;
7610 }
7611 for (pi = G.job_list; pi; pi = pi->next) {
7612 if (pi->jobid == jobnum) {
7613 goto found;
7614 }
7615 }
7616 bb_error_msg("%s: %d: no such job", argv[0], jobnum);
7617 return EXIT_FAILURE;
7618 found:
7619 /* TODO: bash prints a string representation
7620 * of job being foregrounded (like "sleep 1 | cat") */
7621 if (argv[0][0] == 'f' && G_saved_tty_pgrp) {
7622 /* Put the job into the foreground. */
7623 tcsetpgrp(G_interactive_fd, pi->pgrp);
7624 }
7625
7626 /* Restart the processes in the job */
7627 debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp);
7628 for (i = 0; i < pi->num_cmds; i++) {
7629 debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid);
7630 pi->cmds[i].is_stopped = 0;
7631 }
7632 pi->stopped_cmds = 0;
7633
7634 i = kill(- pi->pgrp, SIGCONT);
7635 if (i < 0) {
7636 if (errno == ESRCH) {
7637 delete_finished_bg_job(pi);
7638 return EXIT_SUCCESS;
7639 }
7640 bb_perror_msg("kill (SIGCONT)");
7641 }
7642
7643 if (argv[0][0] == 'f') {
7644 remove_bg_job(pi);
7645 return checkjobs_and_fg_shell(pi);
7646 }
7647 return EXIT_SUCCESS;
7648 }
7649 #endif
7650
7651 #if ENABLE_HUSH_HELP
7652 static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
7653 {
7654 const struct built_in_command *x;
7655
7656 printf(
7657 "Built-in commands:\n"
7658 "------------------\n");
7659 for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
7660 if (x->descr)
7661 printf("%s\t%s\n", x->cmd, x->descr);
7662 }
7663 bb_putchar('\n');
7664 return EXIT_SUCCESS;
7665 }
7666 #endif
7667
7668 #if ENABLE_HUSH_JOB
7669 static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM)
7670 {
7671 struct pipe *job;
7672 const char *status_string;
7673
7674 for (job = G.job_list; job; job = job->next) {
7675 if (job->alive_cmds == job->stopped_cmds)
7676 status_string = "Stopped";
7677 else
7678 status_string = "Running";
7679
7680 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
7681 }
7682 return EXIT_SUCCESS;
7683 }
7684 #endif
7685
7686 #if HUSH_DEBUG
7687 static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM)
7688 {
7689 void *p;
7690 unsigned long l;
7691
7692 # ifdef M_TRIM_THRESHOLD
7693 /* Optional. Reduces probability of false positives */
7694 malloc_trim(0);
7695 # endif
7696 /* Crude attempt to find where "free memory" starts,
7697 * sans fragmentation. */
7698 p = malloc(240);
7699 l = (unsigned long)p;
7700 free(p);
7701 p = malloc(3400);
7702 if (l < (unsigned long)p) l = (unsigned long)p;
7703 free(p);
7704
7705 if (!G.memleak_value)
7706 G.memleak_value = l;
7707
7708 l -= G.memleak_value;
7709 if ((long)l < 0)
7710 l = 0;
7711 l /= 1024;
7712 if (l > 127)
7713 l = 127;
7714
7715 /* Exitcode is "how many kilobytes we leaked since 1st call" */
7716 return l;
7717 }
7718 #endif
7719
7720 static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM)
7721 {
7722 puts(get_cwd(0));
7723 return EXIT_SUCCESS;
7724 }
7725
7726 static int FAST_FUNC builtin_read(char **argv)
7727 {
7728 const char *r;
7729 char *opt_n = NULL;
7730 char *opt_p = NULL;
7731 char *opt_t = NULL;
7732 char *opt_u = NULL;
7733 int read_flags;
7734
7735 /* "!": do not abort on errors.
7736 * Option string must start with "sr" to match BUILTIN_READ_xxx
7737 */
7738 read_flags = getopt32(argv, "!srn:p:t:u:", &opt_n, &opt_p, &opt_t, &opt_u);
7739 if (read_flags == (uint32_t)-1)
7740 return EXIT_FAILURE;
7741 argv += optind;
7742
7743 r = shell_builtin_read(set_local_var_from_halves,
7744 argv,
7745 get_local_var_value("IFS"), /* can be NULL */
7746 read_flags,
7747 opt_n,
7748 opt_p,
7749 opt_t,
7750 opt_u
7751 );
7752
7753 if ((uintptr_t)r > 1) {
7754 bb_error_msg("%s", r);
7755 r = (char*)(uintptr_t)1;
7756 }
7757
7758 return (uintptr_t)r;
7759 }
7760
7761 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
7762 * built-in 'set' handler
7763 * SUSv3 says:
7764 * set [-abCefhmnuvx] [-o option] [argument...]
7765 * set [+abCefhmnuvx] [+o option] [argument...]
7766 * set -- [argument...]
7767 * set -o
7768 * set +o
7769 * Implementations shall support the options in both their hyphen and
7770 * plus-sign forms. These options can also be specified as options to sh.
7771 * Examples:
7772 * Write out all variables and their values: set
7773 * Set $1, $2, and $3 and set "$#" to 3: set c a b
7774 * Turn on the -x and -v options: set -xv
7775 * Unset all positional parameters: set --
7776 * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
7777 * Set the positional parameters to the expansion of x, even if x expands
7778 * with a leading '-' or '+': set -- $x
7779 *
7780 * So far, we only support "set -- [argument...]" and some of the short names.
7781 */
7782 static int FAST_FUNC builtin_set(char **argv)
7783 {
7784 int n;
7785 char **pp, **g_argv;
7786 char *arg = *++argv;
7787
7788 if (arg == NULL) {
7789 struct variable *e;
7790 for (e = G.top_var; e; e = e->next)
7791 puts(e->varstr);
7792 return EXIT_SUCCESS;
7793 }
7794
7795 do {
7796 if (!strcmp(arg, "--")) {
7797 ++argv;
7798 goto set_argv;
7799 }
7800 if (arg[0] != '+' && arg[0] != '-')
7801 break;
7802 for (n = 1; arg[n]; ++n)
7803 if (set_mode(arg[0], arg[n]))
7804 goto error;
7805 } while ((arg = *++argv) != NULL);
7806 /* Now argv[0] is 1st argument */
7807
7808 if (arg == NULL)
7809 return EXIT_SUCCESS;
7810 set_argv:
7811
7812 /* NB: G.global_argv[0] ($0) is never freed/changed */
7813 g_argv = G.global_argv;
7814 if (G.global_args_malloced) {
7815 pp = g_argv;
7816 while (*++pp)
7817 free(*pp);
7818 g_argv[1] = NULL;
7819 } else {
7820 G.global_args_malloced = 1;
7821 pp = xzalloc(sizeof(pp[0]) * 2);
7822 pp[0] = g_argv[0]; /* retain $0 */
7823 g_argv = pp;
7824 }
7825 /* This realloc's G.global_argv */
7826 G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1);
7827
7828 n = 1;
7829 while (*++pp)
7830 n++;
7831 G.global_argc = n;
7832
7833 return EXIT_SUCCESS;
7834
7835 /* Nothing known, so abort */
7836 error:
7837 bb_error_msg("set: %s: invalid option", arg);
7838 return EXIT_FAILURE;
7839 }
7840
7841 static int FAST_FUNC builtin_shift(char **argv)
7842 {
7843 int n = 1;
7844 if (argv[1]) {
7845 n = atoi(argv[1]);
7846 }
7847 if (n >= 0 && n < G.global_argc) {
7848 if (G.global_args_malloced) {
7849 int m = 1;
7850 while (m <= n)
7851 free(G.global_argv[m++]);
7852 }
7853 G.global_argc -= n;
7854 memmove(&G.global_argv[1], &G.global_argv[n+1],
7855 G.global_argc * sizeof(G.global_argv[0]));
7856 return EXIT_SUCCESS;
7857 }
7858 return EXIT_FAILURE;
7859 }
7860
7861 static int FAST_FUNC builtin_source(char **argv)
7862 {
7863 char *arg_path;
7864 FILE *input;
7865 save_arg_t sv;
7866 #if ENABLE_HUSH_FUNCTIONS
7867 smallint sv_flg;
7868 #endif
7869
7870 if (*++argv == NULL)
7871 return EXIT_FAILURE;
7872
7873 if (strchr(*argv, '/') == NULL && (arg_path = find_in_path(*argv)) != NULL) {
7874 input = fopen_for_read(arg_path);
7875 free(arg_path);
7876 } else
7877 input = fopen_or_warn(*argv, "r");
7878 if (!input) {
7879 /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
7880 return EXIT_FAILURE;
7881 }
7882 close_on_exec_on(fileno(input));
7883
7884 #if ENABLE_HUSH_FUNCTIONS
7885 sv_flg = G.flag_return_in_progress;
7886 /* "we are inside sourced file, ok to use return" */
7887 G.flag_return_in_progress = -1;
7888 #endif
7889 save_and_replace_G_args(&sv, argv);
7890
7891 parse_and_run_file(input);
7892 fclose(input);
7893
7894 restore_G_args(&sv, argv);
7895 #if ENABLE_HUSH_FUNCTIONS
7896 G.flag_return_in_progress = sv_flg;
7897 #endif
7898
7899 return G.last_exitcode;
7900 }
7901
7902 static int FAST_FUNC builtin_umask(char **argv)
7903 {
7904 int rc;
7905 mode_t mask;
7906
7907 mask = umask(0);
7908 if (argv[1]) {
7909 mode_t old_mask = mask;
7910
7911 mask ^= 0777;
7912 rc = bb_parse_mode(argv[1], &mask);
7913 mask ^= 0777;
7914 if (rc == 0) {
7915 mask = old_mask;
7916 /* bash messages:
7917 * bash: umask: 'q': invalid symbolic mode operator
7918 * bash: umask: 999: octal number out of range
7919 */
7920 bb_error_msg("%s: '%s' invalid mode", argv[0], argv[1]);
7921 }
7922 } else {
7923 rc = 1;
7924 /* Mimic bash */
7925 printf("%04o\n", (unsigned) mask);
7926 /* fall through and restore mask which we set to 0 */
7927 }
7928 umask(mask);
7929
7930 return !rc; /* rc != 0 - success */
7931 }
7932
7933 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
7934 static int FAST_FUNC builtin_unset(char **argv)
7935 {
7936 int ret;
7937 unsigned opts;
7938
7939 /* "!": do not abort on errors */
7940 /* "+": stop at 1st non-option */
7941 opts = getopt32(argv, "!+vf");
7942 if (opts == (unsigned)-1)
7943 return EXIT_FAILURE;
7944 if (opts == 3) {
7945 bb_error_msg("unset: -v and -f are exclusive");
7946 return EXIT_FAILURE;
7947 }
7948 argv += optind;
7949
7950 ret = EXIT_SUCCESS;
7951 while (*argv) {
7952 if (!(opts & 2)) { /* not -f */
7953 if (unset_local_var(*argv)) {
7954 /* unset <nonexistent_var> doesn't fail.
7955 * Error is when one tries to unset RO var.
7956 * Message was printed by unset_local_var. */
7957 ret = EXIT_FAILURE;
7958 }
7959 }
7960 #if ENABLE_HUSH_FUNCTIONS
7961 else {
7962 unset_func(*argv);
7963 }
7964 #endif
7965 argv++;
7966 }
7967 return ret;
7968 }
7969
7970 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
7971 static int FAST_FUNC builtin_wait(char **argv)
7972 {
7973 int ret = EXIT_SUCCESS;
7974 int status, sig;
7975
7976 if (*++argv == NULL) {
7977 /* Don't care about wait results */
7978 /* Note 1: must wait until there are no more children */
7979 /* Note 2: must be interruptible */
7980 /* Examples:
7981 * $ sleep 3 & sleep 6 & wait
7982 * [1] 30934 sleep 3
7983 * [2] 30935 sleep 6
7984 * [1] Done sleep 3
7985 * [2] Done sleep 6
7986 * $ sleep 3 & sleep 6 & wait
7987 * [1] 30936 sleep 3
7988 * [2] 30937 sleep 6
7989 * [1] Done sleep 3
7990 * ^C <-- after ~4 sec from keyboard
7991 * $
7992 */
7993 sigaddset(&G.blocked_set, SIGCHLD);
7994 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
7995 while (1) {
7996 checkjobs(NULL);
7997 if (errno == ECHILD)
7998 break;
7999 /* Wait for SIGCHLD or any other signal of interest */
8000 /* sigtimedwait with infinite timeout: */
8001 sig = sigwaitinfo(&G.blocked_set, NULL);
8002 if (sig > 0) {
8003 sig = check_and_run_traps(sig);
8004 if (sig && sig != SIGCHLD) { /* see note 2 */
8005 ret = 128 + sig;
8006 break;
8007 }
8008 }
8009 }
8010 sigdelset(&G.blocked_set, SIGCHLD);
8011 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
8012 return ret;
8013 }
8014
8015 /* This is probably buggy wrt interruptible-ness */
8016 while (*argv) {
8017 pid_t pid = bb_strtou(*argv, NULL, 10);
8018 if (errno) {
8019 /* mimic bash message */
8020 bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
8021 return EXIT_FAILURE;
8022 }
8023 if (waitpid(pid, &status, 0) == pid) {
8024 if (WIFSIGNALED(status))
8025 ret = 128 + WTERMSIG(status);
8026 else if (WIFEXITED(status))
8027 ret = WEXITSTATUS(status);
8028 else /* wtf? */
8029 ret = EXIT_FAILURE;
8030 } else {
8031 bb_perror_msg("wait %s", *argv);
8032 ret = 127;
8033 }
8034 argv++;
8035 }
8036
8037 return ret;
8038 }
8039
8040 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS
8041 static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min)
8042 {
8043 if (argv[1]) {
8044 def = bb_strtou(argv[1], NULL, 10);
8045 if (errno || def < def_min || argv[2]) {
8046 bb_error_msg("%s: bad arguments", argv[0]);
8047 def = UINT_MAX;
8048 }
8049 }
8050 return def;
8051 }
8052 #endif
8053
8054 #if ENABLE_HUSH_LOOPS
8055 static int FAST_FUNC builtin_break(char **argv)
8056 {
8057 unsigned depth;
8058 if (G.depth_of_loop == 0) {
8059 bb_error_msg("%s: only meaningful in a loop", argv[0]);
8060 return EXIT_SUCCESS; /* bash compat */
8061 }
8062 G.flag_break_continue++; /* BC_BREAK = 1 */
8063
8064 G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1);
8065 if (depth == UINT_MAX)
8066 G.flag_break_continue = BC_BREAK;
8067 if (G.depth_of_loop < depth)
8068 G.depth_break_continue = G.depth_of_loop;
8069
8070 return EXIT_SUCCESS;
8071 }
8072
8073 static int FAST_FUNC builtin_continue(char **argv)
8074 {
8075 G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */
8076 return builtin_break(argv);
8077 }
8078 #endif
8079
8080 #if ENABLE_HUSH_FUNCTIONS
8081 static int FAST_FUNC builtin_return(char **argv)
8082 {
8083 int rc;
8084
8085 if (G.flag_return_in_progress != -1) {
8086 bb_error_msg("%s: not in a function or sourced script", argv[0]);
8087 return EXIT_FAILURE; /* bash compat */
8088 }
8089
8090 G.flag_return_in_progress = 1;
8091
8092 /* bash:
8093 * out of range: wraps around at 256, does not error out
8094 * non-numeric param:
8095 * f() { false; return qwe; }; f; echo $?
8096 * bash: return: qwe: numeric argument required <== we do this
8097 * 255 <== we also do this
8098 */
8099 rc = parse_numeric_argv1(argv, G.last_exitcode, 0);
8100 return rc;
8101 }
8102 #endif