1 /* vi: set sw=4 ts=4: */
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.
8 * Copyright (C) 2000,2001 Larry Doolittle <larry@doolittle.boa.org>
9 * Copyright (C) 2008,2009 Denys Vlasenko <vda.linux@googlemail.com>
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
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.
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.
40 * POSIX syntax not implemented:
42 * <(list) and >(list) Process Substitution
45 * Bash stuff (maybe optionally enable?):
46 * &> and >& redirection of stdout+stderr
48 * reserved words: [[ ]] function select
49 * substrings ${var:1:5}
52 * grep for "TODO" and fix (some of them are easy)
54 * follow IFS rules more precisely, including update semantics
56 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
58 #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */
60 /* #include <dmalloc.h> */
67 # define PIPE_BUF 4096 /* amount of buffering in a pipe */
72 #define LEAK_HUNTING 0
73 #define BUILD_AS_NOMMU 0
74 /* Enable/disable sanity checks. Ok to enable in production,
75 * only adds a bit of bloat. Set to >1 to get non-production level verbosity.
76 * Keeping 1 for now even in released versions.
79 /* Slightly bigger (+200 bytes), but faster hush.
80 * So far it only enables a trick with counting SIGCHLDs and forks,
81 * which allows us to do fewer waitpid's.
82 * (we can detect a case where neither forks were done nor SIGCHLDs happened
83 * and therefore waitpid will return the same result as last time)
85 #define ENABLE_HUSH_FAST 0
93 # define USE_FOR_NOMMU(...) __VA_ARGS__
94 # define USE_FOR_MMU(...)
97 #if defined SINGLE_APPLET_MAIN
98 /* STANDALONE does not make sense, and won't compile */
99 # undef CONFIG_FEATURE_SH_STANDALONE
100 # undef ENABLE_FEATURE_SH_STANDALONE
101 # undef USE_FEATURE_SH_STANDALONE
102 # define USE_FEATURE_SH_STANDALONE(...)
103 # define SKIP_FEATURE_SH_STANDALONE(...) __VA_ARGS__
104 # define ENABLE_FEATURE_SH_STANDALONE 0
107 #if !ENABLE_HUSH_INTERACTIVE
108 # undef ENABLE_FEATURE_EDITING
109 # define ENABLE_FEATURE_EDITING 0
110 # undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
111 # define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
114 /* Do we support ANY keywords? */
115 #if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
116 # define HAS_KEYWORDS 1
117 # define IF_HAS_KEYWORDS(...) __VA_ARGS__
118 # define IF_HAS_NO_KEYWORDS(...)
120 # define HAS_KEYWORDS 0
121 # define IF_HAS_KEYWORDS(...)
122 # define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
125 /* If you comment out one of these below, it will be #defined later
126 * to perform debug printfs to stderr: */
127 #define debug_printf(...) do {} while (0)
128 /* Finer-grained debug switches */
129 #define debug_printf_parse(...) do {} while (0)
130 #define debug_print_tree(a, b) do {} while (0)
131 #define debug_printf_exec(...) do {} while (0)
132 #define debug_printf_env(...) do {} while (0)
133 #define debug_printf_jobs(...) do {} while (0)
134 #define debug_printf_expand(...) do {} while (0)
135 #define debug_printf_glob(...) do {} while (0)
136 #define debug_printf_list(...) do {} while (0)
137 #define debug_printf_subst(...) do {} while (0)
138 #define debug_printf_clean(...) do {} while (0)
140 #define ERR_PTR ((void*)(long)1)
142 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
144 #define SPECIAL_VAR_SYMBOL 3
148 static const char hush_version_str
[] ALIGN1
= "HUSH_VERSION="BB_VER
;
150 /* This supports saving pointers malloced in vfork child,
151 * to be freed in the parent.
154 typedef struct nommu_save_t
{
156 struct variable
*old_vars
;
158 char **argv_from_re_execing
;
162 /* The descrip member of this structure is only used to make
163 * debugging output pretty */
164 static const struct {
166 signed char default_fd
;
170 { O_RDONLY
, 0, "<" },
171 { O_CREAT
|O_TRUNC
|O_WRONLY
, 1, ">" },
172 { O_CREAT
|O_APPEND
|O_WRONLY
, 1, ">>" },
173 { O_RDONLY
, 0, "<<" },
174 { O_CREAT
|O_RDWR
, 1, "<>" },
175 /* Should not be needed. Bogus default_fd helps in debugging */
176 /* { O_RDONLY, 77, "<<" }, */
179 typedef enum reserved_style
{
188 #if ENABLE_HUSH_LOOPS
195 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
200 /* three pseudo-keywords support contrived "case" syntax: */
201 RES_CASE_IN
, /* "case ... IN", turns into RES_MATCH when IN is observed */
202 RES_MATCH
, /* "word)" */
203 RES_CASE_BODY
, /* "this command is inside CASE" */
210 typedef struct o_string
{
212 int length
; /* position where data is appended */
214 /* Protect newly added chars against globbing
215 * (by prepending \ to *, ?, [, \) */
218 /* At least some part of the string was inside '' or "",
219 * possibly empty one: word"", wo''rd etc. */
221 smallint has_empty_slot
;
222 smallint o_assignment
; /* 0:maybe, 1:yes, 2:no */
225 MAYBE_ASSIGNMENT
= 0,
226 DEFINITELY_ASSIGNMENT
= 1,
228 WORD_IS_KEYWORD
= 3, /* not assigment, but next word may be: "if v=xyz cmd;" */
230 /* Used for initialization: o_string foo = NULL_O_STRING; */
231 #define NULL_O_STRING { NULL }
233 /* I can almost use ordinary FILE*. Is open_memstream() universally
234 * available? Where is it documented? */
235 typedef struct in_str
{
237 /* eof_flag=1: last char in ->p is really an EOF */
238 char eof_flag
; /* meaningless if ->p == NULL */
240 #if ENABLE_HUSH_INTERACTIVE
242 smallint promptmode
; /* 0: PS1, 1: PS2 */
245 int (*get
) (struct in_str
*);
246 int (*peek
) (struct in_str
*);
248 #define i_getch(input) ((input)->get(input))
249 #define i_peek(input) ((input)->peek(input))
251 struct redir_struct
{
252 struct redir_struct
*next
;
253 char *rd_filename
; /* filename */
254 int rd_fd
; /* fd to redirect */
255 /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */
257 smallint rd_type
; /* (enum redir_type) */
258 /* note: for heredocs, rd_filename contains heredoc delimiter,
259 * and subsequently heredoc itself; and rd_dup is a bitmask:
260 * 1: do we need to trim leading tabs?
261 * 2: is heredoc quoted (<<'delim' syntax) ?
264 typedef enum redir_type
{
265 REDIRECT_INVALID
= 0,
267 REDIRECT_OVERWRITE
= 2,
269 REDIRECT_HEREDOC
= 4,
271 REDIRECT_HEREDOC2
= 6, /* REDIRECT_HEREDOC after heredoc is loaded */
274 REDIRFD_SYNTAX_ERR
= -2,
275 REDIRFD_TO_FILE
= -1,
276 /* otherwise, rd_fd is redirected to rd_dup */
278 HEREDOC_SKIPTABS
= 1,
284 pid_t pid
; /* 0 if exited */
285 int assignment_cnt
; /* how many argv[i] are assignments? */
286 smallint is_stopped
; /* is the command currently running? */
287 smallint grp_type
; /* GRP_xxx */
289 #define GRP_SUBSHELL 1
290 #if ENABLE_HUSH_FUNCTIONS
291 # define GRP_FUNCTION 2
293 /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
296 char *group_as_string
;
298 #if ENABLE_HUSH_FUNCTIONS
299 struct function
*child_func
;
300 /* This field is used to prevent a bug here:
301 * while...do f1() {a;}; f1; f1 {b;}; f1; done
302 * When we execute "f1() {a;}" cmd, we create new function and clear
303 * cmd->group, cmd->group_as_string, cmd->argv[0].
304 * when we execute "f1 {b;}", we notice that f1 exists,
305 * and that it's "parent cmd" struct is still "alive",
306 * we put those fields back into cmd->xxx
307 * (struct function has ->parent_cmd ptr to facilitate that).
308 * When we loop back, we can execute "f1() {a;}" again and set f1 correctly.
309 * Without this trick, loop would execute a;b;b;b;...
310 * instead of correct sequence a;b;a;b;...
311 * When command is freed, it severs the link
312 * (sets ->child_func->parent_cmd to NULL).
315 char **argv
; /* command name and arguments */
316 /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
317 * and on execution these are substituted with their values.
318 * Substitution can make _several_ words out of one argv[n]!
319 * Example: argv[0]=='.^C*^C.' here: echo .$*.
320 * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
322 struct redir_struct
*redirects
; /* I/O redirections */
324 /* Is there anything in this command at all? */
325 #define IS_NULL_CMD(cmd) \
326 (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects)
331 int num_cmds
; /* total number of commands in pipe */
332 int alive_cmds
; /* number of commands running (not exited) */
333 int stopped_cmds
; /* number of commands alive, but stopped */
335 int jobid
; /* job number */
336 pid_t pgrp
; /* process group ID for the job */
337 char *cmdtext
; /* name of job */
339 struct command
*cmds
; /* array of commands in pipe */
340 smallint followup
; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
341 IF_HAS_KEYWORDS(smallint pi_inverted
;) /* "! cmd | cmd" */
342 IF_HAS_KEYWORDS(smallint res_word
;) /* needed for if, for, while, until... */
344 typedef enum pipe_style
{
350 /* Is there anything in this pipe at all? */
351 #define IS_NULL_PIPE(pi) \
352 ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE))
354 /* This holds pointers to the various results of parsing */
355 struct parse_context
{
356 /* linked list of pipes */
357 struct pipe
*list_head
;
358 /* last pipe (being constructed right now) */
360 /* last command in pipe (being constructed right now) */
361 struct command
*command
;
362 /* last redirect in command->redirects list */
363 struct redir_struct
*pending_redirect
;
369 smallint ctx_inverted
; /* "! cmd | cmd" */
371 smallint ctx_dsemicolon
; /* ";;" seen */
373 /* bitmask of FLAG_xxx, for figuring out valid reserved words */
375 /* group we are enclosed in:
376 * example: "if pipe1; pipe2; then pipe3; fi"
377 * when we see "if" or "then", we malloc and copy current context,
378 * and make ->stack point to it. then we parse pipeN.
379 * when closing "then" / fi" / whatever is found,
380 * we move list_head into ->stack->command->group,
381 * copy ->stack into current context, and delete ->stack.
382 * (parsing of { list } and ( list ) doesn't use this method)
384 struct parse_context
*stack
;
388 /* On program start, environ points to initial environment.
389 * putenv adds new pointers into it, unsetenv removes them.
390 * Neither of these (de)allocates the strings.
391 * setenv allocates new strings in malloc space and does putenv,
392 * and thus setenv is unusable (leaky) for shell's purposes */
393 #define setenv(...) setenv_is_leaky_dont_use()
395 struct variable
*next
;
396 char *varstr
; /* points to "name=" portion */
397 int max_len
; /* if > 0, name is part of initial env; else name is malloced */
398 smallint flg_export
; /* putenv should be done on this var */
399 smallint flg_read_only
;
407 #if ENABLE_HUSH_FUNCTIONS
409 struct function
*next
;
411 struct command
*parent_cmd
;
414 char *body_as_string
;
420 /* "Globals" within this file */
421 /* Sorted roughly by size (smaller offsets == smaller code) */
423 /* interactive_fd != 0 means we are an interactive shell.
424 * If we are, then saved_tty_pgrp can also be != 0, meaning
425 * that controlling tty is available. With saved_tty_pgrp == 0,
426 * job control still works, but terminal signals
427 * (^C, ^Z, ^Y, ^\) won't work at all, and background
428 * process groups can only be created with "cmd &".
429 * With saved_tty_pgrp != 0, hush will use tcsetpgrp()
430 * to give tty to the foreground process group,
431 * and will take it back when the group is stopped (^Z)
434 #if ENABLE_HUSH_INTERACTIVE
435 /* 'interactive_fd' is a fd# open to ctty, if we have one
436 * _AND_ if we decided to act interactively */
440 # define G_interactive_fd (G.interactive_fd)
442 # define G_interactive_fd 0
444 #if ENABLE_FEATURE_EDITING
445 line_input_t
*line_input_state
;
452 pid_t saved_tty_pgrp
;
453 struct pipe
*job_list
;
454 # define G_saved_tty_pgrp (G.saved_tty_pgrp)
456 # define G_saved_tty_pgrp 0
458 smallint flag_SIGINT
;
459 #if ENABLE_HUSH_LOOPS
460 smallint flag_break_continue
;
462 #if ENABLE_HUSH_FUNCTIONS
463 /* 0: outside of a function (or sourced file)
464 * -1: inside of a function, ok to use return builtin
465 * 1: return is invoked, skip all till end of func
467 smallint flag_return_in_progress
;
470 smallint exiting
; /* used to prevent EXIT trap recursion */
471 /* These four support $?, $#, and $1 */
472 smalluint last_exitcode
;
473 /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */
474 smalluint global_args_malloced
;
475 /* how many non-NULL argv's we have. NB: $# + 1 */
479 char *argv0_for_re_execing
;
481 #if ENABLE_HUSH_LOOPS
482 unsigned depth_break_continue
;
483 unsigned depth_of_loop
;
487 struct variable
*top_var
; /* = &G.shell_ver (set in main()) */
488 struct variable shell_ver
;
489 #if ENABLE_HUSH_FUNCTIONS
490 struct function
*top_func
;
492 /* Signal and trap handling */
494 unsigned count_SIGCHLD
;
495 unsigned handled_SIGCHLD
;
496 smallint we_have_children
;
498 /* which signals have non-DFL handler (even with no traps set)? */
499 unsigned non_DFL_mask
;
500 char **traps
; /* char *traps[NSIG] */
501 sigset_t blocked_set
;
502 sigset_t inherited_set
;
504 unsigned long memleak_value
;
507 char user_input_buf
[ENABLE_FEATURE_EDITING
? BUFSIZ
: 2];
509 #define G (*ptr_to_globals)
510 /* Not #defining name to G.name - this quickly gets unwieldy
511 * (too many defines). Also, I actually prefer to see when a variable
512 * is global, thus "G." prefix is a useful hint */
513 #define INIT_G() do { \
514 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
518 /* Function prototypes for builtins */
519 static int builtin_cd(char **argv
);
520 static int builtin_echo(char **argv
);
521 static int builtin_eval(char **argv
);
522 static int builtin_exec(char **argv
);
523 static int builtin_exit(char **argv
);
524 static int builtin_export(char **argv
);
526 static int builtin_fg_bg(char **argv
);
527 static int builtin_jobs(char **argv
);
530 static int builtin_help(char **argv
);
533 static int builtin_memleak(char **argv
);
535 static int builtin_pwd(char **argv
);
536 static int builtin_read(char **argv
);
537 static int builtin_set(char **argv
);
538 static int builtin_shift(char **argv
);
539 static int builtin_source(char **argv
);
540 static int builtin_test(char **argv
);
541 static int builtin_trap(char **argv
);
542 static int builtin_true(char **argv
);
543 static int builtin_umask(char **argv
);
544 static int builtin_unset(char **argv
);
545 static int builtin_wait(char **argv
);
546 #if ENABLE_HUSH_LOOPS
547 static int builtin_break(char **argv
);
548 static int builtin_continue(char **argv
);
550 #if ENABLE_HUSH_FUNCTIONS
551 static int builtin_return(char **argv
);
554 /* Table of built-in functions. They can be forked or not, depending on
555 * context: within pipes, they fork. As simple commands, they do not.
556 * When used in non-forking context, they can change global variables
557 * in the parent shell process. If forked, of course they cannot.
558 * For example, 'unset foo | whatever' will parse and run, but foo will
559 * still be set at the end. */
560 struct built_in_command
{
562 int (*function
)(char **argv
);
565 #define BLTIN(cmd, func, help) { cmd, func, help }
567 #define BLTIN(cmd, func, help) { cmd, func }
571 /* For now, echo and test are unconditionally enabled.
572 * Maybe make it configurable? */
573 static const struct built_in_command bltins
[] = {
574 BLTIN("." , builtin_source
, "Run commands in a file"),
575 BLTIN(":" , builtin_true
, "No-op"),
576 BLTIN("[" , builtin_test
, "Test condition"),
578 BLTIN("bg" , builtin_fg_bg
, "Resume a job in the background"),
580 #if ENABLE_HUSH_LOOPS
581 BLTIN("break" , builtin_break
, "Exit from a loop"),
583 BLTIN("cd" , builtin_cd
, "Change directory"),
584 #if ENABLE_HUSH_LOOPS
585 BLTIN("continue", builtin_continue
, "Start new loop iteration"),
587 BLTIN("echo" , builtin_echo
, "Write to stdout"),
588 BLTIN("eval" , builtin_eval
, "Construct and run shell command"),
589 BLTIN("exec" , builtin_exec
, "Execute command, don't return to shell"),
590 BLTIN("exit" , builtin_exit
, "Exit"),
591 BLTIN("export" , builtin_export
, "Set environment variable"),
593 BLTIN("fg" , builtin_fg_bg
, "Bring job into the foreground"),
596 BLTIN("help" , builtin_help
, "List shell built-in commands"),
599 BLTIN("jobs" , builtin_jobs
, "List active jobs"),
602 BLTIN("memleak" , builtin_memleak
, "Debug tool"),
604 BLTIN("pwd" , builtin_pwd
, "Print current directory"),
605 BLTIN("read" , builtin_read
, "Input environment variable"),
606 #if ENABLE_HUSH_FUNCTIONS
607 BLTIN("return" , builtin_return
, "Return from a function"),
609 BLTIN("set" , builtin_set
, "Set/unset shell local variables"),
610 BLTIN("shift" , builtin_shift
, "Shift positional parameters"),
611 BLTIN("test" , builtin_test
, "Test condition"),
612 BLTIN("trap" , builtin_trap
, "Trap signals"),
613 // BLTIN("ulimit" , builtin_return , "Control resource limits"),
614 BLTIN("umask" , builtin_umask
, "Set file creation mask"),
615 BLTIN("unset" , builtin_unset
, "Unset environment variable"),
616 BLTIN("wait" , builtin_wait
, "Wait for process"),
623 /* prevent disasters with G.debug_indent < 0 */
624 # define indent() fprintf(stderr, "%*s", (G.debug_indent * 2) & 0xff, "")
625 # define debug_enter() (G.debug_indent++)
626 # define debug_leave() (G.debug_indent--)
628 # define indent() ((void)0)
629 # define debug_enter() ((void)0)
630 # define debug_leave() ((void)0)
634 # define debug_printf(...) (indent(), fprintf(stderr, __VA_ARGS__))
637 #ifndef debug_printf_parse
638 # define debug_printf_parse(...) (indent(), fprintf(stderr, __VA_ARGS__))
641 #ifndef debug_printf_exec
642 #define debug_printf_exec(...) (indent(), fprintf(stderr, __VA_ARGS__))
645 #ifndef debug_printf_env
646 # define debug_printf_env(...) (indent(), fprintf(stderr, __VA_ARGS__))
649 #ifndef debug_printf_jobs
650 # define debug_printf_jobs(...) (indent(), fprintf(stderr, __VA_ARGS__))
651 # define DEBUG_JOBS 1
653 # define DEBUG_JOBS 0
656 #ifndef debug_printf_expand
657 # define debug_printf_expand(...) (indent(), fprintf(stderr, __VA_ARGS__))
658 # define DEBUG_EXPAND 1
660 # define DEBUG_EXPAND 0
663 #ifndef debug_printf_glob
664 # define debug_printf_glob(...) (indent(), fprintf(stderr, __VA_ARGS__))
665 # define DEBUG_GLOB 1
667 # define DEBUG_GLOB 0
670 #ifndef debug_printf_list
671 # define debug_printf_list(...) (indent(), fprintf(stderr, __VA_ARGS__))
674 #ifndef debug_printf_subst
675 # define debug_printf_subst(...) (indent(), fprintf(stderr, __VA_ARGS__))
678 #ifndef debug_printf_clean
679 # define debug_printf_clean(...) (indent(), fprintf(stderr, __VA_ARGS__))
680 # define DEBUG_CLEAN 1
682 # define DEBUG_CLEAN 0
686 static void debug_print_strings(const char *prefix
, char **vv
)
689 fprintf(stderr
, "%s:\n", prefix
);
691 fprintf(stderr
, " '%s'\n", *vv
++);
694 #define debug_print_strings(prefix, vv) ((void)0)
698 /* Leak hunting. Use hush_leaktool.sh for post-processing.
701 static void *xxmalloc(int lineno
, size_t size
)
703 void *ptr
= xmalloc((size
+ 0xff) & ~0xff);
704 fdprintf(2, "line %d: malloc %p\n", lineno
, ptr
);
707 static void *xxrealloc(int lineno
, void *ptr
, size_t size
)
709 ptr
= xrealloc(ptr
, (size
+ 0xff) & ~0xff);
710 fdprintf(2, "line %d: realloc %p\n", lineno
, ptr
);
713 static char *xxstrdup(int lineno
, const char *str
)
715 char *ptr
= xstrdup(str
);
716 fdprintf(2, "line %d: strdup %p\n", lineno
, ptr
);
719 static void xxfree(void *ptr
)
721 fdprintf(2, "free %p\n", ptr
);
724 #define xmalloc(s) xxmalloc(__LINE__, s)
725 #define xrealloc(p, s) xxrealloc(__LINE__, p, s)
726 #define xstrdup(s) xxstrdup(__LINE__, s)
727 #define free(p) xxfree(p)
731 /* Syntax and runtime errors. They always abort scripts.
732 * In interactive use they usually discard unparsed and/or unexecuted commands
733 * and return to the prompt.
734 * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
737 # define die_if_script(lineno, fmt...) die_if_script(fmt)
738 # define syntax_error(lineno, msg) syntax_error(msg)
739 # define syntax_error_at(lineno, msg) syntax_error_at(msg)
740 # define syntax_error_unterm_ch(lineno, ch) syntax_error_unterm_ch(ch)
741 # define syntax_error_unterm_str(lineno, s) syntax_error_unterm_str(s)
742 # define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch)
745 static void die_if_script(unsigned lineno
, const char *fmt
, ...)
750 bb_error_msg("hush.c:%u", lineno
);
753 bb_verror_msg(fmt
, p
, NULL
);
755 if (!G_interactive_fd
)
759 static void syntax_error(unsigned lineno
, const char *msg
)
762 die_if_script(lineno
, "syntax error: %s", msg
);
764 die_if_script(lineno
, "syntax error", NULL
);
767 static void syntax_error_at(unsigned lineno
, const char *msg
)
769 die_if_script(lineno
, "syntax error at '%s'", msg
);
772 /* It so happens that all such cases are totally fatal
773 * even if shell is interactive: EOF while looking for closing
774 * delimiter. There is nowhere to read stuff from after that,
775 * it's EOF! The only choice is to terminate.
777 static void syntax_error_unterm_ch(unsigned lineno
, char ch
) NORETURN
;
778 static void syntax_error_unterm_ch(unsigned lineno
, char ch
)
783 die_if_script(lineno
, "syntax error: unterminated %s", msg
);
787 static void syntax_error_unterm_str(unsigned lineno
, const char *s
)
789 die_if_script(lineno
, "syntax error: unterminated %s", s
);
792 static void syntax_error_unexpected_ch(unsigned lineno
, int ch
)
797 die_if_script(lineno
, "syntax error: unexpected %s", ch
== EOF
? "EOF" : msg
);
801 # undef die_if_script
803 # undef syntax_error_at
804 # undef syntax_error_unterm_ch
805 # undef syntax_error_unterm_str
806 # undef syntax_error_unexpected_ch
808 # define die_if_script(fmt...) die_if_script(__LINE__, fmt)
809 # define syntax_error(msg) syntax_error(__LINE__, msg)
810 # define syntax_error_at(msg) syntax_error_at(__LINE__, msg)
811 # define syntax_error_unterm_ch(ch) syntax_error_unterm_ch(__LINE__, ch)
812 # define syntax_error_unterm_str(s) syntax_error_unterm_str(__LINE__, s)
813 # define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch)
817 #if ENABLE_HUSH_INTERACTIVE
818 static void cmdedit_update_prompt(void);
820 # define cmdedit_update_prompt()
826 static int glob_needed(const char *s
)
831 if (*s
== '*' || *s
== '[' || *s
== '?')
838 static int is_well_formed_var_name(const char *s
, char terminator
)
840 if (!s
|| !(isalpha(*s
) || *s
== '_'))
843 while (isalnum(*s
) || *s
== '_')
845 return *s
== terminator
;
848 /* Replace each \x with x in place, return ptr past NUL. */
849 static char *unbackslash(char *src
)
855 if ((*dst
++ = *src
++) == '\0')
861 static char **add_strings_to_strings(char **strings
, char **add
, int need_to_dup
)
882 v
= xrealloc(strings
, (count1
+ count2
+ 1) * sizeof(char*));
883 v
[count1
+ count2
] = NULL
;
886 v
[count1
+ i
] = (need_to_dup
? xstrdup(add
[i
]) : add
[i
]);
890 static char **xx_add_strings_to_strings(int lineno
, char **strings
, char **add
, int need_to_dup
)
892 char **ptr
= add_strings_to_strings(strings
, add
, need_to_dup
);
893 fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno
, ptr
);
896 #define add_strings_to_strings(strings, add, need_to_dup) \
897 xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup)
900 /* Note: takes ownership of "add" ptr (it is not strdup'ed) */
901 static char **add_string_to_strings(char **strings
, char *add
)
906 return add_strings_to_strings(strings
, v
, /*dup:*/ 0);
909 static char **xx_add_string_to_strings(int lineno
, char **strings
, char *add
)
911 char **ptr
= add_string_to_strings(strings
, add
);
912 fdprintf(2, "line %d: add_string_to_strings %p\n", lineno
, ptr
);
915 #define add_string_to_strings(strings, add) \
916 xx_add_string_to_strings(__LINE__, strings, add)
919 static void free_strings(char **strings
)
934 /* Helpers for setting new $n and restoring them back
936 typedef struct save_arg_t
{
940 smallint sv_g_malloced
;
943 static void save_and_replace_G_args(save_arg_t
*sv
, char **argv
)
947 sv
->sv_argv0
= argv
[0];
948 sv
->sv_g_argv
= G
.global_argv
;
949 sv
->sv_g_argc
= G
.global_argc
;
950 sv
->sv_g_malloced
= G
.global_args_malloced
;
952 argv
[0] = G
.global_argv
[0]; /* retain $0 */
953 G
.global_argv
= argv
;
954 G
.global_args_malloced
= 0;
962 static void restore_G_args(save_arg_t
*sv
, char **argv
)
966 if (G
.global_args_malloced
) {
967 /* someone ran "set -- arg1 arg2 ...", undo */
969 while (*++pp
) /* note: does not free $0 */
973 argv
[0] = sv
->sv_argv0
;
974 G
.global_argv
= sv
->sv_g_argv
;
975 G
.global_argc
= sv
->sv_g_argc
;
976 G
.global_args_malloced
= sv
->sv_g_malloced
;
980 /* Basic theory of signal handling in shell
981 * ========================================
982 * This does not describe what hush does, rather, it is current understanding
983 * what it _should_ do. If it doesn't, it's a bug.
984 * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
986 * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
987 * is finished or backgrounded. It is the same in interactive and
988 * non-interactive shells, and is the same regardless of whether
989 * a user trap handler is installed or a shell special one is in effect.
990 * ^C or ^Z from keyboard seem to execute "at once" because it usually
991 * backgrounds (i.e. stops) or kills all members of currently running
994 * Wait builtin in interruptible by signals for which user trap is set
995 * or by SIGINT in interactive shell.
997 * Trap handlers will execute even within trap handlers. (right?)
999 * User trap handlers are forgotten when subshell ("(cmd)") is entered.
1001 * If job control is off, backgrounded commands ("cmd &")
1002 * have SIGINT, SIGQUIT set to SIG_IGN.
1004 * Commands run in command substitution ("`cmd`")
1005 * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
1007 * Ordinary commands have signals set to SIG_IGN/DFL set as inherited
1008 * by the shell from its parent.
1010 * Siganls which differ from SIG_DFL action
1011 * (note: child (i.e., [v]forked) shell is not an interactive shell):
1014 * SIGTERM (interactive): ignore
1015 * SIGHUP (interactive):
1016 * send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit
1017 * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
1018 * Note that ^Z is handled not by trapping SIGTSTP, but by seeing
1019 * that all pipe members are stopped. Try this in bash:
1020 * while :; do :; done - ^Z does not background it
1021 * (while :; do :; done) - ^Z backgrounds it
1022 * SIGINT (interactive): wait for last pipe, ignore the rest
1023 * of the command line, show prompt. NB: ^C does not send SIGINT
1024 * to interactive shell while shell is waiting for a pipe,
1025 * since shell is bg'ed (is not in foreground process group).
1026 * Example 1: this waits 5 sec, but does not execute ls:
1027 * "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
1028 * Example 2: this does not wait and does not execute ls:
1029 * "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1030 * Example 3: this does not wait 5 sec, but executes ls:
1031 * "sleep 5; ls -l" + press ^C
1033 * (What happens to signals which are IGN on shell start?)
1034 * (What happens with signal mask on shell start?)
1036 * Implementation in hush
1037 * ======================
1038 * We use in-kernel pending signal mask to determine which signals were sent.
1039 * We block all signals which we don't want to take action immediately,
1040 * i.e. we block all signals which need to have special handling as described
1041 * above, and all signals which have traps set.
1042 * After each pipe execution, we extract any pending signals via sigtimedwait()
1045 * unsigned non_DFL_mask: a mask of such "special" signals
1046 * sigset_t blocked_set: current blocked signal set
1049 * clear bit in blocked_set unless it is also in non_DFL_mask
1050 * "trap 'cmd' SIGxxx":
1051 * set bit in blocked_set (even if 'cmd' is '')
1052 * after [v]fork, if we plan to be a shell:
1053 * unblock signals with special interactive handling
1054 * (child shell is not interactive),
1055 * unset all traps (note: regardless of child shell's type - {}, (), etc)
1056 * after [v]fork, if we plan to exec:
1057 * POSIX says pending signal mask is cleared in child - no need to clear it.
1058 * Restore blocked signal set to one inherited by shell just prior to exec.
1060 * Note: as a result, we do not use signal handlers much. The only uses
1061 * are to count SIGCHLDs
1062 * and to restore tty pgrp on signal-induced exit.
1065 SPECIAL_INTERACTIVE_SIGS
= 0
1070 SPECIAL_JOB_SIGS
= 0
1078 #if ENABLE_HUSH_FAST
1079 static void SIGCHLD_handler(int sig UNUSED_PARAM
)
1082 //bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1088 /* After [v]fork, in child: do not restore tty pgrp on xfunc death */
1089 #define disable_restore_tty_pgrp_on_exit() (die_sleep = 0)
1090 /* After [v]fork, in parent: restore tty pgrp on xfunc death */
1091 #define enable_restore_tty_pgrp_on_exit() (die_sleep = -1)
1093 /* Restores tty foreground process group, and exits.
1094 * May be called as signal handler for fatal signal
1095 * (will resend signal to itself, producing correct exit state)
1096 * or called directly with -EXITCODE.
1097 * We also call it if xfunc is exiting. */
1098 static void sigexit(int sig
) NORETURN
;
1099 static void sigexit(int sig
)
1101 /* Disable all signals: job control, SIGPIPE, etc. */
1102 sigprocmask_allsigs(SIG_BLOCK
);
1104 /* Careful: we can end up here after [v]fork. Do not restore
1105 * tty pgrp then, only top-level shell process does that */
1106 if (G_saved_tty_pgrp
&& getpid() == G
.root_pid
)
1107 tcsetpgrp(G_interactive_fd
, G_saved_tty_pgrp
);
1109 /* Not a signal, just exit */
1113 kill_myself_with_sig(sig
); /* does not return */
1117 #define disable_restore_tty_pgrp_on_exit() ((void)0)
1118 #define enable_restore_tty_pgrp_on_exit() ((void)0)
1122 /* Restores tty foreground process group, and exits. */
1123 static void hush_exit(int exitcode
) NORETURN
;
1124 static void hush_exit(int exitcode
)
1126 if (G
.exiting
<= 0 && G
.traps
&& G
.traps
[0] && G
.traps
[0][0]) {
1127 /* Prevent recursion:
1128 * trap "echo Hi; exit" EXIT; exit
1130 char *argv
[] = { NULL
, G
.traps
[0], NULL
};
1138 fflush(NULL
); /* flush all streams */
1139 sigexit(- (exitcode
& 0xff));
1145 static int check_and_run_traps(int sig
)
1147 static const struct timespec zero_timespec
= { 0, 0 };
1148 smalluint save_rcode
;
1154 sig
= sigtimedwait(&G
.blocked_set
, NULL
, &zero_timespec
);
1159 if (G
.traps
&& G
.traps
[sig
]) {
1160 if (G
.traps
[sig
][0]) {
1161 /* We have user-defined handler */
1162 char *argv
[] = { NULL
, xstrdup(G
.traps
[sig
]), NULL
};
1163 save_rcode
= G
.last_exitcode
;
1166 G
.last_exitcode
= save_rcode
;
1167 } /* else: "" trap, ignoring signal */
1170 /* not a trap: special action */
1172 #if ENABLE_HUSH_FAST
1175 //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1179 /* Builtin was ^C'ed, make it look prettier: */
1186 /* bash is observed to signal whole process groups,
1187 * not individual processes */
1188 for (job
= G
.job_list
; job
; job
= job
->next
) {
1191 debug_printf_exec("HUPing pgrp %d\n", job
->pgrp
);
1192 if (kill(- job
->pgrp
, SIGHUP
) == 0)
1193 kill(- job
->pgrp
, SIGCONT
);
1198 default: /* ignored: */
1199 /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
1207 static const char *set_cwd(void)
1209 /* xrealloc_getcwd_or_warn(arg) calls free(arg),
1210 * we must not try to free(bb_msg_unknown) */
1211 if (G
.cwd
== bb_msg_unknown
)
1213 G
.cwd
= xrealloc_getcwd_or_warn((char *)G
.cwd
);
1215 G
.cwd
= bb_msg_unknown
;
1221 * Shell and environment variable support
1223 static struct variable
**get_ptr_to_local_var(const char *name
)
1225 struct variable
**pp
;
1226 struct variable
*cur
;
1231 while ((cur
= *pp
) != NULL
) {
1232 if (strncmp(cur
->varstr
, name
, len
) == 0 && cur
->varstr
[len
] == '=')
1239 static struct variable
*get_local_var(const char *name
)
1241 struct variable
**pp
= get_ptr_to_local_var(name
);
1247 static const char *get_local_var_value(const char *name
)
1249 struct variable
**pp
= get_ptr_to_local_var(name
);
1251 return strchr((*pp
)->varstr
, '=') + 1;
1255 /* str holds "NAME=VAL" and is expected to be malloced.
1256 * We take ownership of it.
1258 * 0: do not change export flag
1259 * (if creating new variable, flag will be 0)
1260 * 1: set export flag and putenv the variable
1261 * -1: clear export flag and unsetenv the variable
1262 * flg_read_only is set only when we handle -R var=val
1265 #define set_local_var(str, flg_export, flg_read_only) \
1266 set_local_var(str, flg_export)
1268 static int set_local_var(char *str
, int flg_export
, int flg_read_only
)
1270 struct variable
*cur
;
1274 eq_sign
= strchr(str
, '=');
1275 if (!eq_sign
) { /* not expected to ever happen? */
1280 name_len
= eq_sign
- str
+ 1; /* including '=' */
1281 cur
= G
.top_var
; /* cannot be NULL (we have HUSH_VERSION and it's RO) */
1283 if (strncmp(cur
->varstr
, str
, name_len
) != 0) {
1285 /* Bail out. Note that now cur points
1286 * to last var in linked list */
1292 /* We found an existing var with this name */
1293 if (cur
->flg_read_only
) {
1297 bb_error_msg("%s: readonly variable", str
);
1301 if (flg_export
== -1) {
1302 debug_printf_env("%s: unsetenv '%s'\n", __func__
, str
);
1307 if (strcmp(cur
->varstr
+ name_len
, eq_sign
+ 1) == 0) {
1312 if (cur
->max_len
>= strlen(str
)) {
1313 /* This one is from startup env, reuse space */
1314 strcpy(cur
->varstr
, str
);
1317 /* max_len == 0 signifies "malloced" var, which we can
1318 * (and has to) free */
1322 goto set_str_and_exp
;
1325 /* Not found - create next variable struct */
1326 cur
->next
= xzalloc(sizeof(*cur
));
1332 cur
->flg_read_only
= flg_read_only
;
1335 if (flg_export
== 1)
1336 cur
->flg_export
= 1;
1337 if (name_len
== 4 && cur
->varstr
[0] == 'P' && cur
->varstr
[1] == 'S')
1338 cmdedit_update_prompt();
1339 if (cur
->flg_export
) {
1340 if (flg_export
== -1) {
1341 cur
->flg_export
= 0;
1342 /* unsetenv was already done */
1344 debug_printf_env("%s: putenv '%s'\n", __func__
, cur
->varstr
);
1345 return putenv(cur
->varstr
);
1351 static int unset_local_var_len(const char *name
, int name_len
)
1353 struct variable
*cur
;
1354 struct variable
**var_pp
;
1357 return EXIT_SUCCESS
;
1358 var_pp
= &G
.top_var
;
1359 while ((cur
= *var_pp
) != NULL
) {
1360 if (strncmp(cur
->varstr
, name
, name_len
) == 0 && cur
->varstr
[name_len
] == '=') {
1361 if (cur
->flg_read_only
) {
1362 bb_error_msg("%s: readonly variable", name
);
1363 return EXIT_FAILURE
;
1365 *var_pp
= cur
->next
;
1366 debug_printf_env("%s: unsetenv '%s'\n", __func__
, cur
->varstr
);
1367 bb_unsetenv(cur
->varstr
);
1368 if (name_len
== 3 && cur
->varstr
[0] == 'P' && cur
->varstr
[1] == 'S')
1369 cmdedit_update_prompt();
1373 return EXIT_SUCCESS
;
1375 var_pp
= &cur
->next
;
1377 return EXIT_SUCCESS
;
1380 static int unset_local_var(const char *name
)
1382 return unset_local_var_len(name
, strlen(name
));
1385 static void unset_vars(char **strings
)
1393 const char *eq
= strchrnul(*v
, '=');
1394 unset_local_var_len(*v
, (int)(eq
- *v
));
1400 #if ENABLE_SH_MATH_SUPPORT
1401 #define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
1402 #define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
1403 static char *endofname(const char *name
)
1411 if (!is_in_name(*p
))
1417 static void arith_set_local_var(const char *name
, const char *val
, int flags
)
1419 /* arith code doesnt malloc space, so do it for it */
1420 char *var
= xasprintf("%s=%s", name
, val
);
1421 set_local_var(var
, flags
, 0);
1427 * Helpers for "var1=val1 var2=val2 cmd" feature
1429 static void add_vars(struct variable
*var
)
1431 struct variable
*next
;
1435 var
->next
= G
.top_var
;
1437 if (var
->flg_export
) {
1438 debug_printf_env("%s: restoring exported '%s'\n", __func__
, var
->varstr
);
1439 putenv(var
->varstr
);
1441 debug_printf_env("%s: restoring local '%s'\n", __func__
, var
->varstr
);
1447 static struct variable
*set_vars_and_save_old(char **strings
)
1450 struct variable
*old
= NULL
;
1456 struct variable
*var_p
;
1457 struct variable
**var_pp
;
1460 eq
= strchr(*s
, '=');
1463 var_pp
= get_ptr_to_local_var(*s
);
1466 /* Remove variable from global linked list */
1468 debug_printf_env("%s: removing '%s'\n", __func__
, var_p
->varstr
);
1469 *var_pp
= var_p
->next
;
1470 /* Add it to returned list */
1474 set_local_var(*s
, 1, 0);
1485 static int static_get(struct in_str
*i
)
1494 static int static_peek(struct in_str
*i
)
1499 #if ENABLE_HUSH_INTERACTIVE
1501 static void cmdedit_update_prompt(void)
1503 if (ENABLE_FEATURE_EDITING_FANCY_PROMPT
) {
1504 G
.PS1
= get_local_var_value("PS1");
1507 G
.PS2
= get_local_var_value("PS2");
1515 static const char* setup_prompt_string(int promptmode
)
1517 const char *prompt_str
;
1518 debug_printf("setup_prompt_string %d ", promptmode
);
1519 if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT
) {
1520 /* Set up the prompt */
1521 if (promptmode
== 0) { /* PS1 */
1523 G
.PS1
= xasprintf("%s %c ", G
.cwd
, (geteuid() != 0) ? '$' : '#');
1528 prompt_str
= (promptmode
== 0) ? G
.PS1
: G
.PS2
;
1529 debug_printf("result '%s'\n", prompt_str
);
1533 static void get_user_input(struct in_str
*i
)
1536 const char *prompt_str
;
1538 prompt_str
= setup_prompt_string(i
->promptmode
);
1539 #if ENABLE_FEATURE_EDITING
1540 /* Enable command line editing only while a command line
1541 * is actually being read */
1544 /* buglet: SIGINT will not make new prompt to appear _at once_,
1545 * only after <Enter>. (^C will work) */
1546 r
= read_line_input(prompt_str
, G
.user_input_buf
, BUFSIZ
-1, G
.line_input_state
);
1547 /* catch *SIGINT* etc (^C is handled by read_line_input) */
1548 check_and_run_traps(0);
1549 } while (r
== 0 || G
.flag_SIGINT
); /* repeat if ^C or SIGINT */
1550 i
->eof_flag
= (r
< 0);
1551 if (i
->eof_flag
) { /* EOF/error detected */
1552 G
.user_input_buf
[0] = EOF
; /* yes, it will be truncated, it's ok */
1553 G
.user_input_buf
[1] = '\0';
1558 fputs(prompt_str
, stdout
);
1560 G
.user_input_buf
[0] = r
= fgetc(i
->file
);
1561 /*G.user_input_buf[1] = '\0'; - already is and never changed */
1562 //do we need check_and_run_traps(0)? (maybe only if stdin)
1563 } while (G
.flag_SIGINT
);
1564 i
->eof_flag
= (r
== EOF
);
1566 i
->p
= G
.user_input_buf
;
1569 #endif /* INTERACTIVE */
1571 /* This is the magic location that prints prompts
1572 * and gets data back from the user */
1573 static int file_get(struct in_str
*i
)
1577 /* If there is data waiting, eat it up */
1578 if (i
->p
&& *i
->p
) {
1579 #if ENABLE_HUSH_INTERACTIVE
1583 if (i
->eof_flag
&& !*i
->p
)
1585 /* note: ch is never NUL */
1587 /* need to double check i->file because we might be doing something
1588 * more complicated by now, like sourcing or substituting. */
1589 #if ENABLE_HUSH_INTERACTIVE
1590 if (G_interactive_fd
&& i
->promptme
&& i
->file
== stdin
) {
1593 } while (!*i
->p
); /* need non-empty line */
1594 i
->promptmode
= 1; /* PS2 */
1599 do ch
= fgetc(i
->file
); while (ch
== '\0');
1601 debug_printf("file_get: got '%c' %d\n", ch
, ch
);
1602 #if ENABLE_HUSH_INTERACTIVE
1609 /* All callers guarantee this routine will never
1610 * be used right after a newline, so prompting is not needed.
1612 static int file_peek(struct in_str
*i
)
1615 if (i
->p
&& *i
->p
) {
1616 if (i
->eof_flag
&& !i
->p
[1])
1619 /* note: ch is never NUL */
1621 do ch
= fgetc(i
->file
); while (ch
== '\0');
1622 i
->eof_flag
= (ch
== EOF
);
1623 i
->peek_buf
[0] = ch
;
1624 i
->peek_buf
[1] = '\0';
1626 debug_printf("file_peek: got '%c' %d\n", ch
, ch
);
1630 static void setup_file_in_str(struct in_str
*i
, FILE *f
)
1632 i
->peek
= file_peek
;
1634 #if ENABLE_HUSH_INTERACTIVE
1636 i
->promptmode
= 0; /* PS1 */
1642 static void setup_string_in_str(struct in_str
*i
, const char *s
)
1644 i
->peek
= static_peek
;
1645 i
->get
= static_get
;
1646 #if ENABLE_HUSH_INTERACTIVE
1648 i
->promptmode
= 0; /* PS1 */
1658 #define B_CHUNK (32 * sizeof(char*))
1660 static void o_reset_to_empty_unquoted(o_string
*o
)
1668 static void o_free(o_string
*o
)
1671 memset(o
, 0, sizeof(*o
));
1674 static ALWAYS_INLINE
void o_free_unsafe(o_string
*o
)
1679 static void o_grow_by(o_string
*o
, int len
)
1681 if (o
->length
+ len
> o
->maxlen
) {
1682 o
->maxlen
+= (2*len
> B_CHUNK
? 2*len
: B_CHUNK
);
1683 o
->data
= xrealloc(o
->data
, 1 + o
->maxlen
);
1687 static void o_addchr(o_string
*o
, int ch
)
1689 debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch
, o
->length
, o
);
1691 o
->data
[o
->length
] = ch
;
1693 o
->data
[o
->length
] = '\0';
1696 static void o_addblock(o_string
*o
, const char *str
, int len
)
1699 memcpy(&o
->data
[o
->length
], str
, len
);
1701 o
->data
[o
->length
] = '\0';
1705 static void o_addstr(o_string
*o
, const char *str
)
1707 o_addblock(o
, str
, strlen(str
));
1709 static void nommu_addchr(o_string
*o
, int ch
)
1715 #define nommu_addchr(o, str) ((void)0)
1718 static void o_addstr_with_NUL(o_string
*o
, const char *str
)
1720 o_addblock(o
, str
, strlen(str
) + 1);
1723 static void o_addblock_duplicate_backslash(o_string
*o
, const char *str
, int len
)
1728 && (*str
!= '*' && *str
!= '?' && *str
!= '[')
1736 /* My analysis of quoting semantics tells me that state information
1737 * is associated with a destination, not a source.
1739 static void o_addqchr(o_string
*o
, int ch
)
1742 char *found
= strchr("*?[\\", ch
);
1747 o
->data
[o
->length
] = '\\';
1750 o
->data
[o
->length
] = ch
;
1752 o
->data
[o
->length
] = '\0';
1755 static void o_addQchr(o_string
*o
, int ch
)
1758 if (o
->o_escape
&& strchr("*?[\\", ch
)) {
1760 o
->data
[o
->length
] = '\\';
1764 o
->data
[o
->length
] = ch
;
1766 o
->data
[o
->length
] = '\0';
1769 static void o_addQstr(o_string
*o
, const char *str
, int len
)
1772 o_addblock(o
, str
, len
);
1778 int ordinary_cnt
= strcspn(str
, "*?[\\");
1779 if (ordinary_cnt
> len
) /* paranoia */
1781 o_addblock(o
, str
, ordinary_cnt
);
1782 if (ordinary_cnt
== len
)
1784 str
+= ordinary_cnt
;
1785 len
-= ordinary_cnt
+ 1; /* we are processing + 1 char below */
1789 if (ch
) { /* it is necessarily one of "*?[\\" */
1791 o
->data
[o
->length
] = '\\';
1795 o
->data
[o
->length
] = ch
;
1797 o
->data
[o
->length
] = '\0';
1801 /* A special kind of o_string for $VAR and `cmd` expansion.
1802 * It contains char* list[] at the beginning, which is grown in 16 element
1803 * increments. Actual string data starts at the next multiple of 16 * (char*).
1804 * list[i] contains an INDEX (int!) into this string data.
1805 * It means that if list[] needs to grow, data needs to be moved higher up
1806 * but list[i]'s need not be modified.
1807 * NB: remembering how many list[i]'s you have there is crucial.
1808 * o_finalize_list() operation post-processes this structure - calculates
1809 * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
1811 #if DEBUG_EXPAND || DEBUG_GLOB
1812 static void debug_print_list(const char *prefix
, o_string
*o
, int n
)
1814 char **list
= (char**)o
->data
;
1815 int string_start
= ((n
+ 0xf) & ~0xf) * sizeof(list
[0]);
1819 fprintf(stderr
, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d\n",
1820 prefix
, list
, n
, string_start
, o
->length
, o
->maxlen
);
1823 fprintf(stderr
, " list[%d]=%d '%s' %p\n", i
, (int)list
[i
],
1824 o
->data
+ (int)list
[i
] + string_start
,
1825 o
->data
+ (int)list
[i
] + string_start
);
1829 const char *p
= o
->data
+ (int)list
[n
- 1] + string_start
;
1831 fprintf(stderr
, " total_sz:%ld\n", (long)((p
+ strlen(p
) + 1) - o
->data
));
1835 #define debug_print_list(prefix, o, n) ((void)0)
1838 /* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
1839 * in list[n] so that it points past last stored byte so far.
1840 * It returns n+1. */
1841 static int o_save_ptr_helper(o_string
*o
, int n
)
1843 char **list
= (char**)o
->data
;
1847 if (!o
->has_empty_slot
) {
1848 string_start
= ((n
+ 0xf) & ~0xf) * sizeof(list
[0]);
1849 string_len
= o
->length
- string_start
;
1850 if (!(n
& 0xf)) { /* 0, 0x10, 0x20...? */
1851 debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n
, string_len
, string_start
);
1852 /* list[n] points to string_start, make space for 16 more pointers */
1853 o
->maxlen
+= 0x10 * sizeof(list
[0]);
1854 o
->data
= xrealloc(o
->data
, o
->maxlen
+ 1);
1855 list
= (char**)o
->data
;
1856 memmove(list
+ n
+ 0x10, list
+ n
, string_len
);
1857 o
->length
+= 0x10 * sizeof(list
[0]);
1859 debug_printf_list("list[%d]=%d string_start=%d\n",
1860 n
, string_len
, string_start
);
1863 /* We have empty slot at list[n], reuse without growth */
1864 string_start
= ((n
+1 + 0xf) & ~0xf) * sizeof(list
[0]); /* NB: n+1! */
1865 string_len
= o
->length
- string_start
;
1866 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
1867 n
, string_len
, string_start
);
1868 o
->has_empty_slot
= 0;
1870 list
[n
] = (char*)(ptrdiff_t)string_len
;
1874 /* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
1875 static int o_get_last_ptr(o_string
*o
, int n
)
1877 char **list
= (char**)o
->data
;
1878 int string_start
= ((n
+ 0xf) & ~0xf) * sizeof(list
[0]);
1880 return ((int)(ptrdiff_t)list
[n
-1]) + string_start
;
1883 /* o_glob performs globbing on last list[], saving each result
1884 * as a new list[]. */
1885 static int o_glob(o_string
*o
, int n
)
1891 debug_printf_glob("start o_glob: n:%d o->data:%p\n", n
, o
->data
);
1893 return o_save_ptr_helper(o
, n
);
1894 pattern
= o
->data
+ o_get_last_ptr(o
, n
);
1895 debug_printf_glob("glob pattern '%s'\n", pattern
);
1896 if (!glob_needed(pattern
)) {
1898 o
->length
= unbackslash(pattern
) - o
->data
;
1899 debug_printf_glob("glob pattern '%s' is literal\n", pattern
);
1900 return o_save_ptr_helper(o
, n
);
1903 memset(&globdata
, 0, sizeof(globdata
));
1904 gr
= glob(pattern
, 0, NULL
, &globdata
);
1905 debug_printf_glob("glob('%s'):%d\n", pattern
, gr
);
1906 if (gr
== GLOB_NOSPACE
)
1907 bb_error_msg_and_die("out of memory during glob");
1908 if (gr
== GLOB_NOMATCH
) {
1909 globfree(&globdata
);
1912 if (gr
!= 0) { /* GLOB_ABORTED ? */
1913 /* TODO: testcase for bad glob pattern behavior */
1914 bb_error_msg("glob(3) error %d on '%s'", gr
, pattern
);
1916 if (globdata
.gl_pathv
&& globdata
.gl_pathv
[0]) {
1917 char **argv
= globdata
.gl_pathv
;
1918 o
->length
= pattern
- o
->data
; /* "forget" pattern */
1920 o_addstr_with_NUL(o
, *argv
);
1921 n
= o_save_ptr_helper(o
, n
);
1927 globfree(&globdata
);
1929 debug_print_list("o_glob returning", o
, n
);
1933 /* If o->o_glob == 1, glob the string so far remembered.
1934 * Otherwise, just finish current list[] and start new */
1935 static int o_save_ptr(o_string
*o
, int n
)
1937 if (o
->o_glob
) { /* if globbing is requested */
1938 /* If o->has_empty_slot, list[n] was already globbed
1939 * (if it was requested back then when it was filled)
1940 * so don't do that again! */
1941 if (!o
->has_empty_slot
)
1942 return o_glob(o
, n
); /* o_save_ptr_helper is inside */
1944 return o_save_ptr_helper(o
, n
);
1947 /* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
1948 static char **o_finalize_list(o_string
*o
, int n
)
1953 n
= o_save_ptr(o
, n
); /* force growth for list[n] if necessary */
1955 debug_print_list("finalized", o
, n
);
1956 debug_printf_expand("finalized n:%d\n", n
);
1957 list
= (char**)o
->data
;
1958 string_start
= ((n
+ 0xf) & ~0xf) * sizeof(list
[0]);
1962 list
[n
] = o
->data
+ (int)(ptrdiff_t)list
[n
] + string_start
;
1968 /* Expansion can recurse */
1969 #if ENABLE_HUSH_TICK
1970 static int process_command_subs(o_string
*dest
, const char *s
);
1972 static char *expand_string_to_string(const char *str
);
1974 #define parse_stream_dquoted(as_string, dest, input, dquote_end) \
1975 parse_stream_dquoted(dest, input, dquote_end)
1977 static int parse_stream_dquoted(o_string
*as_string
,
1979 struct in_str
*input
,
1982 /* expand_strvec_to_strvec() takes a list of strings, expands
1983 * all variable references within and returns a pointer to
1984 * a list of expanded strings, possibly with larger number
1985 * of strings. (Think VAR="a b"; echo $VAR).
1986 * This new list is allocated as a single malloc block.
1987 * NULL-terminated list of char* pointers is at the beginning of it,
1988 * followed by strings themself.
1989 * Caller can deallocate entire list by single free(list). */
1991 /* Store given string, finalizing the word and starting new one whenever
1992 * we encounter IFS char(s). This is used for expanding variable values.
1993 * End-of-string does NOT finalize word: think about 'echo -$VAR-' */
1994 static int expand_on_ifs(o_string
*output
, int n
, const char *str
)
1997 int word_len
= strcspn(str
, G
.ifs
);
1999 if (output
->o_escape
|| !output
->o_glob
)
2000 o_addQstr(output
, str
, word_len
);
2001 else /* protect backslashes against globbing up :) */
2002 o_addblock_duplicate_backslash(output
, str
, word_len
);
2005 if (!*str
) /* EOL - do not finalize word */
2007 o_addchr(output
, '\0');
2008 debug_print_list("expand_on_ifs", output
, n
);
2009 n
= o_save_ptr(output
, n
);
2010 str
+= strspn(str
, G
.ifs
); /* skip ifs chars */
2012 debug_print_list("expand_on_ifs[1]", output
, n
);
2016 /* Helper to expand $((...)) and heredoc body. These act as if
2017 * they are in double quotes, with the exception that they are not :).
2018 * Just the rules are similar: "expand only $var and `cmd`"
2020 * Returns malloced string.
2021 * As an optimization, we return NULL if expansion is not needed.
2023 static char *expand_pseudo_dquoted(const char *str
)
2026 struct in_str input
;
2027 o_string dest
= NULL_O_STRING
;
2029 if (strchr(str
, '$') == NULL
2030 #if ENABLE_HUSH_TICK
2031 && strchr(str
, '`') == NULL
2037 /* We need to expand. Example:
2038 * echo $(($a + `echo 1`)) $((1 + $((2)) ))
2040 setup_string_in_str(&input
, str
);
2041 parse_stream_dquoted(NULL
, &dest
, &input
, EOF
);
2042 //bb_error_msg("'%s' -> '%s'", str, dest.data);
2043 exp_str
= expand_string_to_string(dest
.data
);
2044 //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
2045 o_free_unsafe(&dest
);
2049 /* Expand all variable references in given string, adding words to list[]
2050 * at n, n+1,... positions. Return updated n (so that list[n] is next one
2051 * to be filled). This routine is extremely tricky: has to deal with
2052 * variables/parameters with whitespace, $* and $@, and constructs like
2053 * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
2054 static int expand_vars_to_list(o_string
*output
, int n
, char *arg
, char or_mask
)
2056 /* or_mask is either 0 (normal case) or 0x80 -
2057 * expansion of right-hand side of assignment == 1-element expand.
2058 * It will also do no globbing, and thus we must not backslash-quote!
2065 debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg
);
2066 debug_print_list("expand_vars_to_list", output
, n
);
2067 n
= o_save_ptr(output
, n
);
2068 debug_print_list("expand_vars_to_list[0]", output
, n
);
2070 while ((p
= strchr(arg
, SPECIAL_VAR_SYMBOL
)) != NULL
) {
2073 char *dyn_val
= NULL
;
2074 const char *val
= NULL
;
2075 #if ENABLE_HUSH_TICK
2076 o_string subst_result
= NULL_O_STRING
;
2078 #if ENABLE_SH_MATH_SUPPORT
2079 char arith_buf
[sizeof(arith_t
)*3 + 2];
2081 o_addblock(output
, arg
, p
- arg
);
2082 debug_print_list("expand_vars_to_list[1]", output
, n
);
2084 p
= strchr(p
, SPECIAL_VAR_SYMBOL
);
2086 first_ch
= arg
[0] | or_mask
; /* forced to "quoted" if or_mask = 0x80 */
2087 /* "$@" is special. Even if quoted, it can still
2088 * expand to nothing (not even an empty string) */
2089 if ((first_ch
& 0x7f) != '@')
2090 ored_ch
|= first_ch
;
2092 switch (first_ch
& 0x7f) {
2093 /* Highest bit in first_ch indicates that var is double-quoted */
2095 val
= utoa(G
.root_pid
);
2097 case '!': /* bg pid */
2098 val
= G
.last_bg_pid
? utoa(G
.last_bg_pid
) : (char*)"";
2100 case '?': /* exitcode */
2101 val
= utoa(G
.last_exitcode
);
2103 case '#': /* argc */
2104 if (arg
[1] != SPECIAL_VAR_SYMBOL
)
2105 /* actually, it's a ${#var} */
2107 val
= utoa(G
.global_argc
? G
.global_argc
-1 : 0);
2112 if (!G
.global_argv
[i
])
2114 ored_ch
|= first_ch
; /* do it for "$@" _now_, when we know it's not empty */
2115 if (!(first_ch
& 0x80)) { /* unquoted $* or $@ */
2116 smallint sv
= output
->o_escape
;
2117 /* unquoted var's contents should be globbed, so don't escape */
2118 output
->o_escape
= 0;
2119 while (G
.global_argv
[i
]) {
2120 n
= expand_on_ifs(output
, n
, G
.global_argv
[i
]);
2121 debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i
, G
.global_argc
- 1);
2122 if (G
.global_argv
[i
++][0] && G
.global_argv
[i
]) {
2123 /* this argv[] is not empty and not last:
2124 * put terminating NUL, start new word */
2125 o_addchr(output
, '\0');
2126 debug_print_list("expand_vars_to_list[2]", output
, n
);
2127 n
= o_save_ptr(output
, n
);
2128 debug_print_list("expand_vars_to_list[3]", output
, n
);
2131 output
->o_escape
= sv
;
2133 /* If or_mask is nonzero, we handle assignment 'a=....$@.....'
2134 * and in this case should treat it like '$*' - see 'else...' below */
2135 if (first_ch
== ('@'|0x80) && !or_mask
) { /* quoted $@ */
2137 o_addQstr(output
, G
.global_argv
[i
], strlen(G
.global_argv
[i
]));
2138 if (++i
>= G
.global_argc
)
2140 o_addchr(output
, '\0');
2141 debug_print_list("expand_vars_to_list[4]", output
, n
);
2142 n
= o_save_ptr(output
, n
);
2144 } else { /* quoted $*: add as one word */
2146 o_addQstr(output
, G
.global_argv
[i
], strlen(G
.global_argv
[i
]));
2147 if (!G
.global_argv
[++i
])
2150 o_addchr(output
, G
.ifs
[0]);
2154 case SPECIAL_VAR_SYMBOL
: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
2155 /* "Empty variable", used to make "" etc to not disappear */
2159 #if ENABLE_HUSH_TICK
2160 case '`': /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
2163 /* Can't just stuff it into output o_string,
2164 * expanded result may need to be globbed
2165 * and $IFS-splitted */
2166 debug_printf_subst("SUBST '%s' first_ch %x\n", arg
, first_ch
);
2167 process_command_subs(&subst_result
, arg
);
2168 debug_printf_subst("SUBST RES '%s'\n", subst_result
.data
);
2169 val
= subst_result
.data
;
2172 #if ENABLE_SH_MATH_SUPPORT
2173 case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */
2174 arith_eval_hooks_t hooks
;
2179 arg
++; /* skip '+' */
2180 *p
= '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
2181 debug_printf_subst("ARITH '%s' first_ch %x\n", arg
, first_ch
);
2183 exp_str
= expand_pseudo_dquoted(arg
);
2184 hooks
.lookupvar
= get_local_var_value
;
2185 hooks
.setvar
= arith_set_local_var
;
2186 hooks
.endofname
= endofname
;
2187 res
= arith(exp_str
? exp_str
: arg
, &errcode
, &hooks
);
2191 const char *msg
= "error in arithmetic";
2194 msg
= "exponent less than 0";
2197 msg
= "divide by 0";
2200 msg
= "expression recursion loop detected";
2205 debug_printf_subst("ARITH RES '"arith_t_fmt
"'\n", res
);
2206 sprintf(arith_buf
, arith_t_fmt
, res
);
2211 default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
2213 bool exp_len
= false;
2214 bool exp_null
= false;
2216 char exp_save
= exp_save
; /* for compiler */
2217 char exp_op
= exp_op
; /* for compiler */
2218 char *exp_word
= exp_word
; /* for compiler */
2222 arg
[0] = first_ch
& 0x7f;
2224 /* prepare for expansions */
2225 if (var
[0] == '#') {
2226 /* handle length expansion ${#var} */
2230 /* maybe handle parameter expansion */
2231 exp_off
= strcspn(var
, ":-=+?%#");
2235 exp_save
= var
[exp_off
];
2236 exp_null
= exp_save
== ':';
2237 exp_word
= var
+ exp_off
;
2240 exp_op
= *exp_word
++;
2241 var
[exp_off
] = '\0';
2245 /* lookup the variable in question */
2246 if (isdigit(var
[0])) {
2247 /* handle_dollar() should have vetted var for us */
2249 if (i
< G
.global_argc
)
2250 val
= G
.global_argv
[i
];
2251 /* else val remains NULL: $N with too big N */
2253 val
= get_local_var_value(var
);
2255 /* handle any expansions */
2257 debug_printf_expand("expand: length of '%s' = ", val
);
2258 val
= utoa(val
? strlen(val
) : 0);
2259 debug_printf_expand("%s\n", val
);
2260 } else if (exp_off
) {
2261 if (exp_op
== '%' || exp_op
== '#') {
2263 /* we need to do a pattern match */
2266 scan_t scan
= pick_scan(exp_op
, *exp_word
, &match_at_left
);
2267 if (exp_op
== *exp_word
) /* ## or %% */
2269 val
= dyn_val
= xstrdup(val
);
2270 loc
= scan(dyn_val
, exp_word
, match_at_left
);
2271 if (match_at_left
) /* # or ## */
2273 else if (loc
) /* % or %% and match was found */
2277 /* we need to do an expansion */
2278 int exp_test
= (!val
|| (exp_null
&& !val
[0]));
2280 exp_test
= !exp_test
;
2281 debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op
,
2282 exp_null
? "true" : "false", exp_test
);
2284 if (exp_op
== '?') {
2285 //TODO: how interactive bash aborts expansion mid-command?
2286 /* ${var?[error_msg_if_unset]} */
2287 /* ${var:?[error_msg_if_unset_or_null]} */
2288 /* mimic bash message */
2289 die_if_script("%s: %s",
2291 exp_word
[0] ? exp_word
: "parameter null or not set"
2297 if (exp_op
== '=') {
2298 /* ${var=[word]} or ${var:=[word]} */
2299 if (isdigit(var
[0]) || var
[0] == '#') {
2300 /* mimic bash message */
2301 die_if_script("$%s: cannot assign in this way", var
);
2304 char *new_var
= xasprintf("%s=%s", var
, val
);
2305 set_local_var(new_var
, 0, 0);
2311 var
[exp_off
] = exp_save
;
2315 #if ENABLE_HUSH_TICK
2318 if (!(first_ch
& 0x80)) { /* unquoted $VAR */
2319 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val
, output
->o_escape
);
2321 /* unquoted var's contents should be globbed, so don't escape */
2322 smallint sv
= output
->o_escape
;
2323 output
->o_escape
= 0;
2324 n
= expand_on_ifs(output
, n
, val
);
2326 output
->o_escape
= sv
;
2328 } else { /* quoted $VAR, val will be appended below */
2329 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val
, output
->o_escape
);
2332 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
2335 o_addQstr(output
, val
, strlen(val
));
2338 /* Do the check to avoid writing to a const string */
2339 if (*p
!= SPECIAL_VAR_SYMBOL
)
2340 *p
= SPECIAL_VAR_SYMBOL
;
2342 #if ENABLE_HUSH_TICK
2343 o_free(&subst_result
);
2346 } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
2349 debug_print_list("expand_vars_to_list[a]", output
, n
);
2350 /* this part is literal, and it was already pre-quoted
2351 * if needed (much earlier), do not use o_addQstr here! */
2352 o_addstr_with_NUL(output
, arg
);
2353 debug_print_list("expand_vars_to_list[b]", output
, n
);
2354 } else if (output
->length
== o_get_last_ptr(output
, n
) /* expansion is empty */
2355 && !(ored_ch
& 0x80) /* and all vars were not quoted. */
2358 /* allow to reuse list[n] later without re-growth */
2359 output
->has_empty_slot
= 1;
2361 o_addchr(output
, '\0');
2366 static char **expand_variables(char **argv
, int or_mask
)
2371 o_string output
= NULL_O_STRING
;
2373 if (or_mask
& 0x100) {
2374 output
.o_escape
= 1; /* protect against globbing for "$var" */
2375 /* (unquoted $var will temporarily switch it off) */
2382 n
= expand_vars_to_list(&output
, n
, *v
, (char)or_mask
);
2385 debug_print_list("expand_variables", &output
, n
);
2387 /* output.data (malloced in one block) gets returned in "list" */
2388 list
= o_finalize_list(&output
, n
);
2389 debug_print_strings("expand_variables[1]", list
);
2393 static char **expand_strvec_to_strvec(char **argv
)
2395 return expand_variables(argv
, 0x100);
2398 /* Used for expansion of right hand of assignments */
2399 /* NB: should NOT do globbing! "export v=/bin/c*; env | grep ^v=" outputs
2401 static char *expand_string_to_string(const char *str
)
2403 char *argv
[2], **list
;
2405 argv
[0] = (char*)str
;
2407 list
= expand_variables(argv
, 0x80); /* 0x80: make one-element expansion */
2409 if (!list
[0] || list
[1])
2410 bb_error_msg_and_die("BUG in varexp2");
2411 /* actually, just move string 2*sizeof(char*) bytes back */
2412 overlapping_strcpy((char*)list
, list
[0]);
2413 unbackslash((char*)list
);
2414 debug_printf_expand("string_to_string='%s'\n", (char*)list
);
2418 /* Used for "eval" builtin */
2419 static char* expand_strvec_to_string(char **argv
)
2423 list
= expand_variables(argv
, 0x80);
2424 /* Convert all NULs to spaces */
2429 if (list
[n
-1] + strlen(list
[n
-1]) + 1 != list
[n
])
2430 bb_error_msg_and_die("BUG in varexp3");
2431 /* bash uses ' ' regardless of $IFS contents */
2436 overlapping_strcpy((char*)list
, list
[0]);
2437 debug_printf_expand("strvec_to_string='%s'\n", (char*)list
);
2441 static char **expand_assignments(char **argv
, int count
)
2445 /* Expand assignments into one string each */
2446 for (i
= 0; i
< count
; i
++) {
2447 p
= add_string_to_strings(p
, expand_string_to_string(argv
[i
]));
2455 void re_execute_shell(char ***to_free
, const char *s
, char *argv0
, char **argv
);
2457 static void reset_traps_to_defaults(void)
2459 /* This function is always called in a child shell
2460 * after fork (not vfork, NOMMU doesn't use this function).
2461 * Child shells are not interactive.
2462 * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
2463 * Testcase: (while :; do :; done) + ^Z should background.
2464 * Same goes for SIGTERM, SIGHUP, SIGINT.
2469 if (!G
.traps
&& !(G
.non_DFL_mask
& SPECIAL_INTERACTIVE_SIGS
))
2472 /* Stupid. It can be done with *single* &= op, but we can't use
2473 * the fact that G.blocked_set is implemented as a bitmask... */
2474 mask
= (SPECIAL_INTERACTIVE_SIGS
>> 1);
2478 sigdelset(&G
.blocked_set
, sig
);
2485 G
.non_DFL_mask
&= ~SPECIAL_INTERACTIVE_SIGS
;
2486 mask
= G
.non_DFL_mask
;
2487 if (G
.traps
) for (sig
= 0; sig
< NSIG
; sig
++, mask
>>= 1) {
2491 G
.traps
[sig
] = NULL
;
2492 /* There is no signal for 0 (EXIT) */
2495 /* There was a trap handler, we are removing it.
2496 * But if sig still has non-DFL handling,
2497 * we should not unblock it. */
2500 sigdelset(&G
.blocked_set
, sig
);
2502 sigprocmask(SIG_SETMASK
, &G
.blocked_set
, NULL
);
2507 static void re_execute_shell(char ***to_free
, const char *s
, char *g_argv0
, char **g_argv
) NORETURN
;
2508 static void re_execute_shell(char ***to_free
, const char *s
, char *g_argv0
, char **g_argv
)
2510 char param_buf
[sizeof("-$%x:%x:%x:%x") + sizeof(unsigned) * 4];
2511 char *heredoc_argv
[4];
2512 struct variable
*cur
;
2513 #if ENABLE_HUSH_FUNCTIONS
2514 struct function
*funcp
;
2519 if (!g_argv0
) { /* heredoc */
2520 argv
= heredoc_argv
;
2521 argv
[0] = (char *) G
.argv0_for_re_execing
;
2522 argv
[1] = (char *) "-<";
2523 argv
[2] = (char *) s
;
2525 pp
= &argv
[3]; /* used as pointer to empty environment */
2529 sprintf(param_buf
, "-$%x:%x:%x" USE_HUSH_LOOPS(":%x")
2530 , (unsigned) G
.root_pid
2531 , (unsigned) G
.last_bg_pid
2532 , (unsigned) G
.last_exitcode
2533 USE_HUSH_LOOPS(, G
.depth_of_loop
)
2535 /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<depth> <vars...> <funcs...>
2536 * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL
2539 for (cur
= G
.top_var
; cur
; cur
= cur
->next
) {
2540 if (!cur
->flg_export
|| cur
->flg_read_only
)
2543 #if ENABLE_HUSH_FUNCTIONS
2544 for (funcp
= G
.top_func
; funcp
; funcp
= funcp
->next
)
2550 *to_free
= argv
= pp
= xzalloc(sizeof(argv
[0]) * cnt
);
2551 *pp
++ = (char *) G
.argv0_for_re_execing
;
2553 for (cur
= G
.top_var
; cur
; cur
= cur
->next
) {
2554 if (cur
->varstr
== hush_version_str
)
2556 if (cur
->flg_read_only
) {
2557 *pp
++ = (char *) "-R";
2558 *pp
++ = cur
->varstr
;
2559 } else if (!cur
->flg_export
) {
2560 *pp
++ = (char *) "-V";
2561 *pp
++ = cur
->varstr
;
2564 #if ENABLE_HUSH_FUNCTIONS
2565 for (funcp
= G
.top_func
; funcp
; funcp
= funcp
->next
) {
2566 *pp
++ = (char *) "-F";
2567 *pp
++ = funcp
->name
;
2568 *pp
++ = funcp
->body_as_string
;
2571 /* We can pass activated traps here. Say, -Tnn:trap_string
2573 * However, POSIX says that subshells reset signals with traps
2575 * I tested bash-3.2 and it not only does that with true subshells
2576 * of the form ( list ), but with any forked children shells.
2577 * I set trap "echo W" WINCH; and then tried:
2579 * { echo 1; sleep 20; echo 2; } &
2580 * while true; do echo 1; sleep 20; echo 2; break; done &
2581 * true | { echo 1; sleep 20; echo 2; } | cat
2583 * In all these cases sending SIGWINCH to the child shell
2584 * did not run the trap. If I add trap "echo V" WINCH;
2585 * _inside_ group (just before echo 1), it works.
2587 * I conclude it means we don't need to pass active traps here.
2588 * exec syscall below resets them to SIG_DFL for us.
2590 *pp
++ = (char *) "-c";
2595 /* *pp = NULL; - is already there */
2599 debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s
);
2600 sigprocmask(SIG_SETMASK
, &G
.inherited_set
, NULL
);
2601 execve(bb_busybox_exec_path
, argv
, pp
);
2602 /* Fallback. Useful for init=/bin/hush usage etc */
2603 if (argv
[0][0] == '/')
2604 execve(argv
[0], argv
, pp
);
2605 xfunc_error_retval
= 127;
2606 bb_error_msg_and_die("can't re-execute the shell");
2608 #endif /* !BB_MMU */
2611 static void setup_heredoc(struct redir_struct
*redir
)
2613 struct fd_pair pair
;
2616 /* the _body_ of heredoc (misleading field name) */
2617 const char *heredoc
= redir
->rd_filename
;
2624 if (!(redir
->rd_dup
& HEREDOC_QUOTED
)) {
2625 expanded
= expand_pseudo_dquoted(heredoc
);
2629 len
= strlen(heredoc
);
2631 close(redir
->rd_fd
); /* often saves dup2+close in xmove_fd */
2633 xmove_fd(pair
.rd
, redir
->rd_fd
);
2635 /* Try writing without forking. Newer kernels have
2636 * dynamically growing pipes. Must use non-blocking write! */
2639 written
= write(pair
.wr
, heredoc
, len
);
2650 ndelay_off(pair
.wr
);
2652 /* Okay, pipe buffer was not big enough */
2653 /* Note: we must not create a stray child (bastard? :)
2654 * for the unsuspecting parent process. Child creates a grandchild
2655 * and exits before parent execs the process which consumes heredoc
2656 * (that exec happens after we return from this function) */
2662 bb_perror_msg_and_die("vfork");
2665 disable_restore_tty_pgrp_on_exit();
2666 pid
= BB_MMU
? fork() : vfork();
2668 bb_perror_msg_and_die(BB_MMU
? "fork" : "vfork");
2672 close(redir
->rd_fd
); /* read side of the pipe */
2674 full_write(pair
.wr
, heredoc
, len
); /* may loop or block */
2677 /* Delegate blocking writes to another process */
2678 xmove_fd(pair
.wr
, STDOUT_FILENO
);
2679 re_execute_shell(&to_free
, heredoc
, NULL
, NULL
);
2683 #if ENABLE_HUSH_FAST
2685 //bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
2687 enable_restore_tty_pgrp_on_exit();
2693 wait(NULL
); /* wait till child has died */
2696 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
2697 * and stderr if they are redirected. */
2698 static int setup_redirects(struct command
*prog
, int squirrel
[])
2701 struct redir_struct
*redir
;
2703 for (redir
= prog
->redirects
; redir
; redir
= redir
->next
) {
2704 if (redir
->rd_type
== REDIRECT_HEREDOC2
) {
2705 /* rd_fd<<HERE case */
2706 if (squirrel
&& redir
->rd_fd
< 3
2707 && squirrel
[redir
->rd_fd
] < 0
2709 squirrel
[redir
->rd_fd
] = dup(redir
->rd_fd
);
2711 /* for REDIRECT_HEREDOC2, rd_filename holds _contents_
2713 debug_printf_parse("set heredoc '%s'\n",
2714 redir
->rd_filename
);
2715 setup_heredoc(redir
);
2719 if (redir
->rd_dup
== REDIRFD_TO_FILE
) {
2720 /* rd_fd<*>file case (<*> is <,>,>>,<>) */
2722 if (redir
->rd_filename
== NULL
) {
2723 /* Something went wrong in the parse.
2724 * Pretend it didn't happen */
2725 bb_error_msg("bug in redirect parse");
2728 mode
= redir_table
[redir
->rd_type
].mode
;
2729 p
= expand_string_to_string(redir
->rd_filename
);
2730 openfd
= open_or_warn(p
, mode
);
2733 /* this could get lost if stderr has been redirected, but
2734 * bash and ash both lose it as well (though zsh doesn't!) */
2735 //what the above comment tries to say?
2739 /* rd_fd<*>rd_dup or rd_fd<*>- cases */
2740 openfd
= redir
->rd_dup
;
2743 if (openfd
!= redir
->rd_fd
) {
2744 if (squirrel
&& redir
->rd_fd
< 3
2745 && squirrel
[redir
->rd_fd
] < 0
2747 squirrel
[redir
->rd_fd
] = dup(redir
->rd_fd
);
2749 if (openfd
== REDIRFD_CLOSE
) {
2750 /* "n>-" means "close me" */
2751 close(redir
->rd_fd
);
2753 xdup2(openfd
, redir
->rd_fd
);
2754 if (redir
->rd_dup
== REDIRFD_TO_FILE
)
2762 static void restore_redirects(int squirrel
[])
2765 for (i
= 0; i
< 3; i
++) {
2768 /* We simply die on error */
2775 static void free_pipe_list(struct pipe
*head
);
2777 /* Return code is the exit status of the pipe */
2778 static void free_pipe(struct pipe
*pi
)
2781 struct command
*command
;
2782 struct redir_struct
*r
, *rnext
;
2785 if (pi
->stopped_cmds
> 0) /* why? */
2787 debug_printf_clean("run pipe: (pid %d)\n", getpid());
2788 for (i
= 0; i
< pi
->num_cmds
; i
++) {
2789 command
= &pi
->cmds
[i
];
2790 debug_printf_clean(" command %d:\n", i
);
2791 if (command
->argv
) {
2792 for (a
= 0, p
= command
->argv
; *p
; a
++, p
++) {
2793 debug_printf_clean(" argv[%d] = %s\n", a
, *p
);
2795 free_strings(command
->argv
);
2796 command
->argv
= NULL
;
2798 /* not "else if": on syntax error, we may have both! */
2799 if (command
->group
) {
2800 debug_printf_clean(" begin group (grp_type:%d)\n",
2802 free_pipe_list(command
->group
);
2803 debug_printf_clean(" end group\n");
2804 command
->group
= NULL
;
2806 /* else is crucial here.
2807 * If group != NULL, child_func is meaningless */
2808 #if ENABLE_HUSH_FUNCTIONS
2809 else if (command
->child_func
) {
2810 debug_printf_exec("cmd %p releases child func at %p\n", command
, command
->child_func
);
2811 command
->child_func
->parent_cmd
= NULL
;
2815 free(command
->group_as_string
);
2816 command
->group_as_string
= NULL
;
2818 for (r
= command
->redirects
; r
; r
= rnext
) {
2819 debug_printf_clean(" redirect %d%s",
2820 r
->rd_fd
, redir_table
[r
->rd_type
].descrip
);
2821 /* guard against the case >$FOO, where foo is unset or blank */
2822 if (r
->rd_filename
) {
2823 debug_printf_clean(" fname:'%s'\n", r
->rd_filename
);
2824 free(r
->rd_filename
);
2825 r
->rd_filename
= NULL
;
2827 debug_printf_clean(" rd_dup:%d\n", r
->rd_dup
);
2831 command
->redirects
= NULL
;
2833 free(pi
->cmds
); /* children are an array, they get freed all at once */
2841 static void free_pipe_list(struct pipe
*head
)
2843 struct pipe
*pi
, *next
;
2845 for (pi
= head
; pi
; pi
= next
) {
2847 debug_printf_clean(" pipe reserved word %d\n", pi
->res_word
);
2850 debug_printf_clean("pipe followup code %d\n", pi
->followup
);
2852 /*pi->next = NULL;*/
2858 static int run_list(struct pipe
*pi
);
2860 #define parse_stream(pstring, input, end_trigger) \
2861 parse_stream(input, end_trigger)
2863 static struct pipe
*parse_stream(char **pstring
,
2864 struct in_str
*input
,
2866 static void parse_and_run_string(const char *s
);
2869 static const struct built_in_command
* find_builtin(const char *name
)
2871 const struct built_in_command
*x
;
2872 for (x
= bltins
; x
!= &bltins
[ARRAY_SIZE(bltins
)]; x
++) {
2873 if (strcmp(name
, x
->cmd
) != 0)
2875 debug_printf_exec("found builtin '%s'\n", name
);
2881 #if ENABLE_HUSH_FUNCTIONS
2882 static const struct function
*find_function(const char *name
)
2884 const struct function
*funcp
= G
.top_func
;
2886 if (strcmp(name
, funcp
->name
) == 0) {
2889 funcp
= funcp
->next
;
2892 debug_printf_exec("found function '%s'\n", name
);
2896 /* Note: takes ownership on name ptr */
2897 static struct function
*new_function(char *name
)
2899 struct function
*funcp
;
2900 struct function
**funcpp
= &G
.top_func
;
2902 while ((funcp
= *funcpp
) != NULL
) {
2903 struct command
*cmd
;
2905 if (strcmp(funcp
->name
, name
) != 0) {
2906 funcpp
= &funcp
->next
;
2910 cmd
= funcp
->parent_cmd
;
2911 debug_printf_exec("func %p parent_cmd %p\n", funcp
, cmd
);
2913 debug_printf_exec("freeing & replacing function '%s'\n", funcp
->name
);
2915 /* Note: if !funcp->body, do not free body_as_string!
2916 * This is a special case of "-F name body" function:
2917 * body_as_string was not malloced! */
2919 free_pipe_list(funcp
->body
);
2921 free(funcp
->body_as_string
);
2925 debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp
->name
);
2926 cmd
->argv
[0] = funcp
->name
;
2927 cmd
->group
= funcp
->body
;
2929 cmd
->group_as_string
= funcp
->body_as_string
;
2934 debug_printf_exec("remembering new function '%s'\n", name
);
2935 funcp
= *funcpp
= xzalloc(sizeof(*funcp
));
2936 /*funcp->next = NULL;*/
2942 static void unset_func(const char *name
)
2944 struct function
*funcp
;
2945 struct function
**funcpp
= &G
.top_func
;
2947 while ((funcp
= *funcpp
) != NULL
) {
2948 if (strcmp(funcp
->name
, name
) == 0) {
2949 *funcpp
= funcp
->next
;
2950 /* funcp is unlinked now, deleting it.
2951 * Note: if !funcp->body, the function was created by
2952 * "-F name body", do not free ->body_as_string
2953 * and ->name as they were not malloced. */
2955 free_pipe_list(funcp
->body
);
2958 free(funcp
->body_as_string
);
2964 funcpp
= &funcp
->next
;
2969 #define exec_function(nommu_save, funcp, argv) \
2970 exec_function(funcp, argv)
2972 static void exec_function(nommu_save_t
*nommu_save
,
2973 const struct function
*funcp
,
2974 char **argv
) NORETURN
;
2975 static void exec_function(nommu_save_t
*nommu_save
,
2976 const struct function
*funcp
,
2982 argv
[0] = G
.global_argv
[0];
2983 G
.global_argv
= argv
;
2987 /* On MMU, funcp->body is always non-NULL */
2988 n
= run_list(funcp
->body
);
2992 re_execute_shell(&nommu_save
->argv_from_re_execing
,
2993 funcp
->body_as_string
,
2999 static int run_function(const struct function
*funcp
, char **argv
)
3005 save_and_replace_G_args(&sv
, argv
);
3006 /* "we are in function, ok to use return" */
3007 sv_flg
= G
.flag_return_in_progress
;
3008 G
.flag_return_in_progress
= -1;
3010 /* On MMU, funcp->body is always non-NULL */
3013 /* Function defined by -F */
3014 parse_and_run_string(funcp
->body_as_string
);
3015 rc
= G
.last_exitcode
;
3019 rc
= run_list(funcp
->body
);
3022 G
.flag_return_in_progress
= sv_flg
;
3023 restore_G_args(&sv
, argv
);
3027 #endif /* ENABLE_HUSH_FUNCTIONS */
3031 #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
3032 pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
3033 #define pseudo_exec(nommu_save, command, argv_expanded) \
3034 pseudo_exec(command, argv_expanded)
3037 /* Called after [v]fork() in run_pipe, or from builtin_exec.
3039 * Don't exit() here. If you don't exec, use _exit instead.
3040 * The at_exit handlers apparently confuse the calling process,
3041 * in particular stdin handling. Not sure why? -- because of vfork! (vda) */
3042 static void pseudo_exec_argv(nommu_save_t
*nommu_save
,
3043 char **argv
, int assignment_cnt
,
3044 char **argv_expanded
) NORETURN
;
3045 static void pseudo_exec_argv(nommu_save_t
*nommu_save
,
3046 char **argv
, int assignment_cnt
,
3047 char **argv_expanded
)
3051 /* Case when we are here: ... | var=val | ... */
3052 if (!argv
[assignment_cnt
])
3053 _exit(EXIT_SUCCESS
);
3055 new_env
= expand_assignments(argv
, assignment_cnt
);
3057 set_vars_and_save_old(new_env
);
3058 free(new_env
); /* optional */
3059 /* we can also destroy set_vars_and_save_old's return value,
3062 nommu_save
->new_env
= new_env
;
3063 nommu_save
->old_vars
= set_vars_and_save_old(new_env
);
3065 if (argv_expanded
) {
3066 argv
= argv_expanded
;
3068 argv
= expand_strvec_to_strvec(argv
+ assignment_cnt
);
3070 nommu_save
->argv
= argv
;
3074 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
3075 if (strchr(argv
[0], '/') != NULL
)
3079 /* On NOMMU, we must never block!
3080 * Example: { sleep 99999 | read line } & echo Ok
3081 * read builtin will block on read syscall, leaving parent blocked
3082 * in vfork. Therefore we can't do this:
3085 /* Check if the command matches any of the builtins.
3086 * Depending on context, this might be redundant. But it's
3087 * easier to waste a few CPU cycles than it is to figure out
3088 * if this is one of those cases.
3092 const struct built_in_command
*x
= find_builtin(argv
[0]);
3094 rcode
= x
->function(argv
);
3100 #if ENABLE_HUSH_FUNCTIONS
3101 /* Check if the command matches any functions */
3103 const struct function
*funcp
= find_function(argv
[0]);
3105 exec_function(nommu_save
, funcp
, argv
);
3110 #if ENABLE_FEATURE_SH_STANDALONE
3111 /* Check if the command matches any busybox applets */
3113 int a
= find_applet_by_name(argv
[0]);
3115 # if BB_MMU /* see above why on NOMMU it is not allowed */
3116 if (APPLET_IS_NOEXEC(a
)) {
3117 debug_printf_exec("running applet '%s'\n", argv
[0]);
3118 run_applet_no_and_exit(a
, argv
);
3121 /* Re-exec ourselves */
3122 debug_printf_exec("re-execing applet '%s'\n", argv
[0]);
3123 sigprocmask(SIG_SETMASK
, &G
.inherited_set
, NULL
);
3124 execv(bb_busybox_exec_path
, argv
);
3125 /* If they called chroot or otherwise made the binary no longer
3126 * executable, fall through */
3131 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
3134 debug_printf_exec("execing '%s'\n", argv
[0]);
3135 sigprocmask(SIG_SETMASK
, &G
.inherited_set
, NULL
);
3136 execvp(argv
[0], argv
);
3137 bb_perror_msg("can't execute '%s'", argv
[0]);
3138 _exit(EXIT_FAILURE
);
3141 /* Called after [v]fork() in run_pipe
3143 static void pseudo_exec(nommu_save_t
*nommu_save
,
3144 struct command
*command
,
3145 char **argv_expanded
) NORETURN
;
3146 static void pseudo_exec(nommu_save_t
*nommu_save
,
3147 struct command
*command
,
3148 char **argv_expanded
)
3150 if (command
->argv
) {
3151 pseudo_exec_argv(nommu_save
, command
->argv
,
3152 command
->assignment_cnt
, argv_expanded
);
3155 if (command
->group
) {
3156 /* Cases when we are here:
3159 * ... | ( list ) | ...
3160 * ... | { list } | ...
3164 debug_printf_exec("pseudo_exec: run_list\n");
3165 reset_traps_to_defaults();
3166 rcode
= run_list(command
->group
);
3167 /* OK to leak memory by not calling free_pipe_list,
3168 * since this process is about to exit */
3171 re_execute_shell(&nommu_save
->argv_from_re_execing
,
3172 command
->group_as_string
,
3178 /* Case when we are here: ... | >file */
3179 debug_printf_exec("pseudo_exec'ed null command\n");
3180 _exit(EXIT_SUCCESS
);
3184 static const char *get_cmdtext(struct pipe
*pi
)
3190 /* This is subtle. ->cmdtext is created only on first backgrounding.
3191 * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
3192 * On subsequent bg argv is trashed, but we won't use it */
3195 argv
= pi
->cmds
[0].argv
;
3196 if (!argv
|| !argv
[0]) {
3197 pi
->cmdtext
= xzalloc(1);
3203 len
+= strlen(*argv
) + 1;
3207 argv
= pi
->cmds
[0].argv
;
3209 len
= strlen(*argv
);
3210 memcpy(p
, *argv
, len
);
3218 static void insert_bg_job(struct pipe
*pi
)
3220 struct pipe
*job
, **jobp
;
3223 /* Linear search for the ID of the job to use */
3225 for (job
= G
.job_list
; job
; job
= job
->next
)
3226 if (job
->jobid
>= pi
->jobid
)
3227 pi
->jobid
= job
->jobid
+ 1;
3229 /* Add job to the list of running jobs */
3231 while ((job
= *jobp
) != NULL
)
3233 job
= *jobp
= xmalloc(sizeof(*job
));
3235 *job
= *pi
; /* physical copy */
3237 job
->cmds
= xzalloc(sizeof(pi
->cmds
[0]) * pi
->num_cmds
);
3238 /* Cannot copy entire pi->cmds[] vector! This causes double frees */
3239 for (i
= 0; i
< pi
->num_cmds
; i
++) {
3240 job
->cmds
[i
].pid
= pi
->cmds
[i
].pid
;
3241 /* all other fields are not used and stay zero */
3243 job
->cmdtext
= xstrdup(get_cmdtext(pi
));
3245 if (G_interactive_fd
)
3246 printf("[%d] %d %s\n", job
->jobid
, job
->cmds
[0].pid
, job
->cmdtext
);
3247 /* Last command's pid goes to $! */
3248 G
.last_bg_pid
= job
->cmds
[job
->num_cmds
- 1].pid
;
3249 G
.last_jobid
= job
->jobid
;
3252 static void remove_bg_job(struct pipe
*pi
)
3254 struct pipe
*prev_pipe
;
3256 if (pi
== G
.job_list
) {
3257 G
.job_list
= pi
->next
;
3259 prev_pipe
= G
.job_list
;
3260 while (prev_pipe
->next
!= pi
)
3261 prev_pipe
= prev_pipe
->next
;
3262 prev_pipe
->next
= pi
->next
;
3265 G
.last_jobid
= G
.job_list
->jobid
;
3270 /* Remove a backgrounded job */
3271 static void delete_finished_bg_job(struct pipe
*pi
)
3274 pi
->stopped_cmds
= 0;
3280 /* Check to see if any processes have exited -- if they
3281 * have, figure out why and see if a job has completed */
3282 static int checkjobs(struct pipe
* fg_pipe
)
3292 debug_printf_jobs("checkjobs %p\n", fg_pipe
);
3294 attributes
= WUNTRACED
;
3295 if (fg_pipe
== NULL
)
3296 attributes
|= WNOHANG
;
3299 #if ENABLE_HUSH_FAST
3300 if (G
.handled_SIGCHLD
== G
.count_SIGCHLD
) {
3301 //bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p",
3302 //getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe);
3303 /* There was neither fork nor SIGCHLD since last waitpid */
3304 /* Avoid doing waitpid syscall if possible */
3305 if (!G
.we_have_children
) {
3309 if (fg_pipe
== NULL
) { /* is WNOHANG set? */
3310 /* We have children, but they did not exit
3311 * or stop yet (we saw no SIGCHLD) */
3314 /* else: !WNOHANG, waitpid will block, can't short-circuit */
3318 /* Do we do this right?
3319 * bash-3.00# sleep 20 | false
3321 * [3]+ Stopped sleep 20 | false
3322 * bash-3.00# echo $?
3323 * 1 <========== bg pipe is not fully done, but exitcode is already known!
3324 * [hush 1.14.0: yes we do it right]
3331 #if ENABLE_HUSH_FAST
3332 i
= G
.count_SIGCHLD
;
3334 childpid
= waitpid(-1, &status
, attributes
);
3335 if (childpid
<= 0) {
3336 if (childpid
&& errno
!= ECHILD
)
3337 bb_perror_msg("waitpid");
3338 #if ENABLE_HUSH_FAST
3339 else { /* Until next SIGCHLD, waitpid's are useless */
3340 G
.we_have_children
= (childpid
== 0);
3341 G
.handled_SIGCHLD
= i
;
3342 //bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
3347 dead
= WIFEXITED(status
) || WIFSIGNALED(status
);
3350 if (WIFSTOPPED(status
))
3351 debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
3352 childpid
, WSTOPSIG(status
), WEXITSTATUS(status
));
3353 if (WIFSIGNALED(status
))
3354 debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
3355 childpid
, WTERMSIG(status
), WEXITSTATUS(status
));
3356 if (WIFEXITED(status
))
3357 debug_printf_jobs("pid %d exited, exitcode %d\n",
3358 childpid
, WEXITSTATUS(status
));
3360 /* Were we asked to wait for fg pipe? */
3362 for (i
= 0; i
< fg_pipe
->num_cmds
; i
++) {
3363 debug_printf_jobs("check pid %d\n", fg_pipe
->cmds
[i
].pid
);
3364 if (fg_pipe
->cmds
[i
].pid
!= childpid
)
3367 fg_pipe
->cmds
[i
].pid
= 0;
3368 fg_pipe
->alive_cmds
--;
3369 if (i
== fg_pipe
->num_cmds
- 1) {
3370 /* last process gives overall exitstatus */
3371 /* Note: is WIFSIGNALED, WEXITSTATUS = sig + 128 */
3372 rcode
= WEXITSTATUS(status
);
3373 IF_HAS_KEYWORDS(if (fg_pipe
->pi_inverted
) rcode
= !rcode
;)
3374 /* bash prints killing signal's name for *last*
3375 * process in pipe (prints just newline for SIGINT).
3376 * Mimic this. Example: "sleep 5" + ^\
3378 if (WIFSIGNALED(status
)) {
3379 int sig
= WTERMSIG(status
);
3380 printf("%s\n", sig
== SIGINT
? "" : get_signame(sig
));
3384 fg_pipe
->cmds
[i
].is_stopped
= 1;
3385 fg_pipe
->stopped_cmds
++;
3387 debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
3388 fg_pipe
->alive_cmds
, fg_pipe
->stopped_cmds
);
3389 if (fg_pipe
->alive_cmds
- fg_pipe
->stopped_cmds
<= 0) {
3390 /* All processes in fg pipe have exited or stopped */
3391 /* Note: *non-interactive* bash does not continue if all processes in fg pipe
3392 * are stopped. Testcase: "cat | cat" in a script (not on command line!)
3393 * and "killall -STOP cat" */
3394 if (G_interactive_fd
) {
3396 if (fg_pipe
->alive_cmds
)
3397 insert_bg_job(fg_pipe
);
3401 if (!fg_pipe
->alive_cmds
)
3404 /* There are still running processes in the fg pipe */
3405 goto wait_more
; /* do waitpid again */
3407 /* it wasnt fg_pipe, look for process in bg pipes */
3411 /* We asked to wait for bg or orphaned children */
3412 /* No need to remember exitcode in this case */
3413 for (pi
= G
.job_list
; pi
; pi
= pi
->next
) {
3414 for (i
= 0; i
< pi
->num_cmds
; i
++) {
3415 if (pi
->cmds
[i
].pid
== childpid
)
3416 goto found_pi_and_prognum
;
3419 /* Happens when shell is used as init process (init=/bin/sh) */
3420 debug_printf("checkjobs: pid %d was not in our list!\n", childpid
);
3421 continue; /* do waitpid again */
3423 found_pi_and_prognum
:
3426 pi
->cmds
[i
].pid
= 0;
3428 if (!pi
->alive_cmds
) {
3429 if (G_interactive_fd
)
3430 printf(JOB_STATUS_FORMAT
, pi
->jobid
,
3431 "Done", pi
->cmdtext
);
3432 delete_finished_bg_job(pi
);
3436 pi
->cmds
[i
].is_stopped
= 1;
3440 } /* while (waitpid succeeds)... */
3446 static int checkjobs_and_fg_shell(struct pipe
* fg_pipe
)
3449 int rcode
= checkjobs(fg_pipe
);
3450 if (G_saved_tty_pgrp
) {
3451 /* Job finished, move the shell to the foreground */
3452 p
= getpgrp(); /* our process group id */
3453 debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p
);
3454 tcsetpgrp(G_interactive_fd
, p
);
3460 /* Start all the jobs, but don't wait for anything to finish.
3463 * Return code is normally -1, when the caller has to wait for children
3464 * to finish to determine the exit status of the pipe. If the pipe
3465 * is a simple builtin command, however, the action is done by the
3466 * time run_pipe returns, and the exit code is provided as the
3469 * Returns -1 only if started some children. IOW: we have to
3470 * mask out retvals of builtins etc with 0xff!
3472 * The only case when we do not need to [v]fork is when the pipe
3473 * is single, non-backgrounded, non-subshell command. Examples:
3474 * cmd ; ... { list } ; ...
3475 * cmd && ... { list } && ...
3476 * cmd || ... { list } || ...
3477 * If it is, then we can run cmd as a builtin, NOFORK [do we do this?],
3478 * or (if SH_STANDALONE) an applet, and we can run the { list }
3479 * with run_list. If it isn't one of these, we fork and exec cmd.
3481 * Cases when we must fork:
3482 * non-single: cmd | cmd
3483 * backgrounded: cmd & { list } &
3484 * subshell: ( list ) [&]
3486 static int run_pipe(struct pipe
*pi
)
3488 static const char *const null_ptr
= NULL
;
3491 struct command
*command
;
3492 char **argv_expanded
;
3495 /* it is not always needed, but we aim to smaller code */
3496 int squirrel
[] = { -1, -1, -1 };
3499 debug_printf_exec("run_pipe start: members:%d\n", pi
->num_cmds
);
3502 USE_HUSH_JOB(pi
->pgrp
= -1;)
3503 pi
->stopped_cmds
= 0;
3504 command
= &(pi
->cmds
[0]);
3505 argv_expanded
= NULL
;
3507 if (pi
->num_cmds
!= 1
3508 || pi
->followup
== PIPE_BG
3509 || command
->grp_type
== GRP_SUBSHELL
3516 debug_printf_exec(": group:%p argv:'%s'\n",
3517 command
->group
, command
->argv
? command
->argv
[0] : "NONE");
3519 if (command
->group
) {
3520 #if ENABLE_HUSH_FUNCTIONS
3521 if (command
->grp_type
== GRP_FUNCTION
) {
3522 /* "executing" func () { list } */
3523 struct function
*funcp
;
3525 funcp
= new_function(command
->argv
[0]);
3526 /* funcp->name is already set to argv[0] */
3527 funcp
->body
= command
->group
;
3529 funcp
->body_as_string
= command
->group_as_string
;
3530 command
->group_as_string
= NULL
;
3532 command
->group
= NULL
;
3533 command
->argv
[0] = NULL
;
3534 debug_printf_exec("cmd %p has child func at %p\n", command
, funcp
);
3535 funcp
->parent_cmd
= command
;
3536 command
->child_func
= funcp
;
3538 debug_printf_exec("run_pipe: return EXIT_SUCCESS\n");
3540 return EXIT_SUCCESS
;
3544 debug_printf("non-subshell group\n");
3545 rcode
= 1; /* exitcode if redir failed */
3546 if (setup_redirects(command
, squirrel
) == 0) {
3547 debug_printf_exec(": run_list\n");
3548 rcode
= run_list(command
->group
) & 0xff;
3550 restore_redirects(squirrel
);
3551 IF_HAS_KEYWORDS(if (pi
->pi_inverted
) rcode
= !rcode
;)
3553 debug_printf_exec("run_pipe: return %d\n", rcode
);
3557 argv
= command
->argv
? command
->argv
: (char **) &null_ptr
;
3559 const struct built_in_command
*x
;
3560 #if ENABLE_HUSH_FUNCTIONS
3561 const struct function
*funcp
;
3565 char **new_env
= NULL
;
3566 struct variable
*old_vars
= NULL
;
3568 if (argv
[command
->assignment_cnt
] == NULL
) {
3569 /* Assignments, but no command */
3570 /* Ensure redirects take effect. Try "a=t >file" */
3571 rcode
= setup_redirects(command
, squirrel
);
3572 restore_redirects(squirrel
);
3573 /* Set shell variables */
3575 p
= expand_string_to_string(*argv
);
3576 debug_printf_exec("set shell var:'%s'->'%s'\n",
3578 set_local_var(p
, 0, 0);
3581 /* Do we need to flag set_local_var() errors?
3582 * "assignment to readonly var" and "putenv error"
3584 IF_HAS_KEYWORDS(if (pi
->pi_inverted
) rcode
= !rcode
;)
3586 debug_printf_exec("run_pipe: return %d\n", rcode
);
3590 /* Expand the rest into (possibly) many strings each */
3591 argv_expanded
= expand_strvec_to_strvec(argv
+ command
->assignment_cnt
);
3593 x
= find_builtin(argv_expanded
[0]);
3594 #if ENABLE_HUSH_FUNCTIONS
3597 funcp
= find_function(argv_expanded
[0]);
3601 if (x
->function
== builtin_exec
&& argv_expanded
[1] == NULL
) {
3602 debug_printf("exec with redirects only\n");
3603 rcode
= setup_redirects(command
, NULL
);
3604 goto clean_up_and_ret1
;
3607 /* setup_redirects acts on file descriptors, not FILEs.
3608 * This is perfect for work that comes after exec().
3609 * Is it really safe for inline use? Experimentally,
3610 * things seem to work. */
3611 rcode
= setup_redirects(command
, squirrel
);
3613 new_env
= expand_assignments(argv
, command
->assignment_cnt
);
3614 old_vars
= set_vars_and_save_old(new_env
);
3616 debug_printf_exec(": builtin '%s' '%s'...\n",
3617 x
->cmd
, argv_expanded
[1]);
3618 rcode
= x
->function(argv_expanded
) & 0xff;
3621 #if ENABLE_HUSH_FUNCTIONS
3623 debug_printf_exec(": function '%s' '%s'...\n",
3624 funcp
->name
, argv_expanded
[1]);
3625 rcode
= run_function(funcp
, argv_expanded
) & 0xff;
3629 #if ENABLE_FEATURE_SH_STANDALONE
3632 restore_redirects(squirrel
);
3633 unset_vars(new_env
);
3636 free(argv_expanded
);
3637 IF_HAS_KEYWORDS(if (pi
->pi_inverted
) rcode
= !rcode
;)
3639 debug_printf_exec("run_pipe return %d\n", rcode
);
3643 #if ENABLE_FEATURE_SH_STANDALONE
3644 i
= find_applet_by_name(argv_expanded
[0]);
3645 if (i
>= 0 && APPLET_IS_NOFORK(i
)) {
3646 rcode
= setup_redirects(command
, squirrel
);
3648 new_env
= expand_assignments(argv
, command
->assignment_cnt
);
3649 old_vars
= set_vars_and_save_old(new_env
);
3650 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
3651 argv_expanded
[0], argv_expanded
[1]);
3652 rcode
= run_nofork_applet(i
, argv_expanded
);
3654 goto clean_up_and_ret
;
3657 /* It is neither builtin nor applet. We must fork. */
3661 /* NB: argv_expanded may already be created, and that
3662 * might include `cmd` runs! Do not rerun it! We *must*
3663 * use argv_expanded if it's non-NULL */
3665 /* Going to fork a child per each pipe member */
3669 for (i
= 0; i
< pi
->num_cmds
; i
++) {
3670 struct fd_pair pipefds
;
3672 volatile nommu_save_t nommu_save
;
3673 nommu_save
.new_env
= NULL
;
3674 nommu_save
.old_vars
= NULL
;
3675 nommu_save
.argv
= NULL
;
3676 nommu_save
.argv_from_re_execing
= NULL
;
3678 command
= &(pi
->cmds
[i
]);
3679 if (command
->argv
) {
3680 debug_printf_exec(": pipe member '%s' '%s'...\n",
3681 command
->argv
[0], command
->argv
[1]);
3683 debug_printf_exec(": pipe member with no argv\n");
3686 /* pipes are inserted between pairs of commands */
3689 if ((i
+ 1) < pi
->num_cmds
)
3690 xpiped_pair(pipefds
);
3692 command
->pid
= BB_MMU
? fork() : vfork();
3693 if (!command
->pid
) { /* child */
3695 disable_restore_tty_pgrp_on_exit();
3697 /* Every child adds itself to new process group
3698 * with pgid == pid_of_first_child_in_pipe */
3699 if (G
.run_list_level
== 1 && G_interactive_fd
) {
3702 if (pgrp
< 0) /* true for 1st process only */
3704 if (setpgid(0, pgrp
) == 0
3705 && pi
->followup
!= PIPE_BG
3706 && G_saved_tty_pgrp
/* we have ctty */
3708 /* We do it in *every* child, not just first,
3710 tcsetpgrp(G_interactive_fd
, pgrp
);
3714 if (pi
->alive_cmds
== 0 && pi
->followup
== PIPE_BG
) {
3715 /* 1st cmd in backgrounded pipe
3716 * should have its stdin /dev/null'ed */
3718 if (open(bb_dev_null
, O_RDONLY
))
3719 xopen("/", O_RDONLY
);
3721 xmove_fd(nextin
, 0);
3723 xmove_fd(pipefds
.wr
, 1);
3726 /* Like bash, explicit redirects override pipes,
3727 * and the pipe fd is available for dup'ing. */
3728 if (setup_redirects(command
, NULL
))
3731 /* Restore default handlers just prior to exec */
3732 /*signal(SIGCHLD, SIG_DFL); - so far we don't have any handlers */
3734 /* Stores to nommu_save list of env vars putenv'ed
3735 * (NOMMU, on MMU we don't need that) */
3736 /* cast away volatility... */
3737 pseudo_exec((nommu_save_t
*) &nommu_save
, command
, argv_expanded
);
3738 /* pseudo_exec() does not return */
3741 /* parent or error */
3742 #if ENABLE_HUSH_FAST
3744 //bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
3746 enable_restore_tty_pgrp_on_exit();
3748 /* Clean up after vforked child */
3749 free(nommu_save
.argv
);
3750 free(nommu_save
.argv_from_re_execing
);
3751 unset_vars(nommu_save
.new_env
);
3752 add_vars(nommu_save
.old_vars
);
3754 free(argv_expanded
);
3755 argv_expanded
= NULL
;
3756 if (command
->pid
< 0) { /* [v]fork failed */
3757 /* Clearly indicate, was it fork or vfork */
3758 bb_perror_msg(BB_MMU
? "fork" : "vfork");
3762 /* Second and next children need to know pid of first one */
3764 pi
->pgrp
= command
->pid
;
3770 if ((i
+ 1) < pi
->num_cmds
)
3772 /* Pass read (output) pipe end to next iteration */
3773 nextin
= pipefds
.rd
;
3776 if (!pi
->alive_cmds
) {
3778 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
3783 debug_printf_exec("run_pipe return -1 (%u children started)\n", pi
->alive_cmds
);
3787 #ifndef debug_print_tree
3788 static void debug_print_tree(struct pipe
*pi
, int lvl
)
3790 static const char *const PIPE
[] = {
3796 static const char *RES
[] = {
3797 [RES_NONE
] = "NONE" ,
3800 [RES_THEN
] = "THEN" ,
3801 [RES_ELIF
] = "ELIF" ,
3802 [RES_ELSE
] = "ELSE" ,
3805 #if ENABLE_HUSH_LOOPS
3806 [RES_FOR
] = "FOR" ,
3807 [RES_WHILE
] = "WHILE",
3808 [RES_UNTIL
] = "UNTIL",
3810 [RES_DONE
] = "DONE" ,
3812 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
3815 #if ENABLE_HUSH_CASE
3816 [RES_CASE
] = "CASE" ,
3817 [RES_CASE_IN
] = "CASE_IN" ,
3818 [RES_MATCH
] = "MATCH",
3819 [RES_CASE_BODY
] = "CASE_BODY",
3820 [RES_ESAC
] = "ESAC" ,
3822 [RES_XXXX
] = "XXXX" ,
3823 [RES_SNTX
] = "SNTX" ,
3825 static const char *const GRPTYPE
[] = {
3828 #if ENABLE_HUSH_FUNCTIONS
3837 fprintf(stderr
, "%*spipe %d res_word=%s followup=%d %s\n", lvl
*2, "",
3838 pin
, RES
[pi
->res_word
], pi
->followup
, PIPE
[pi
->followup
]);
3840 while (prn
< pi
->num_cmds
) {
3841 struct command
*command
= &pi
->cmds
[prn
];
3842 char **argv
= command
->argv
;
3844 fprintf(stderr
, "%*s cmd %d assignment_cnt:%d",
3846 command
->assignment_cnt
);
3847 if (command
->group
) {
3848 fprintf(stderr
, " group %s: (argv=%p)\n",
3849 GRPTYPE
[command
->grp_type
],
3851 debug_print_tree(command
->group
, lvl
+1);
3855 if (argv
) while (*argv
) {
3856 fprintf(stderr
, " '%s'", *argv
);
3859 fprintf(stderr
, "\n");
3868 /* NB: called by pseudo_exec, and therefore must not modify any
3869 * global data until exec/_exit (we can be a child after vfork!) */
3870 static int run_list(struct pipe
*pi
)
3872 #if ENABLE_HUSH_CASE
3873 char *case_word
= NULL
;
3875 #if ENABLE_HUSH_LOOPS
3876 struct pipe
*loop_top
= NULL
;
3877 char **for_lcur
= NULL
;
3878 char **for_list
= NULL
;
3880 smallint last_followup
;
3882 #if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
3883 smalluint cond_code
= 0;
3885 enum { cond_code
= 0 };
3888 smallint rword
; /* enum reserved_style */
3889 smallint last_rword
; /* ditto */
3892 debug_printf_exec("run_list start lvl %d\n", G
.run_list_level
);
3895 #if ENABLE_HUSH_LOOPS
3896 /* Check syntax for "for" */
3897 for (struct pipe
*cpipe
= pi
; cpipe
; cpipe
= cpipe
->next
) {
3898 if (cpipe
->res_word
!= RES_FOR
&& cpipe
->res_word
!= RES_IN
)
3900 /* current word is FOR or IN (BOLD in comments below) */
3901 if (cpipe
->next
== NULL
) {
3902 syntax_error("malformed for");
3904 debug_printf_exec("run_list lvl %d return 1\n", G
.run_list_level
);
3907 /* "FOR v; do ..." and "for v IN a b; do..." are ok */
3908 if (cpipe
->next
->res_word
== RES_DO
)
3910 /* next word is not "do". It must be "in" then ("FOR v in ...") */
3911 if (cpipe
->res_word
== RES_IN
/* "for v IN a b; not_do..."? */
3912 || cpipe
->next
->res_word
!= RES_IN
/* FOR v not_do_and_not_in..."? */
3914 syntax_error("malformed for");
3916 debug_printf_exec("run_list lvl %d return 1\n", G
.run_list_level
);
3922 /* Past this point, all code paths should jump to ret: label
3923 * in order to return, no direct "return" statements please.
3924 * This helps to ensure that no memory is leaked. */
3932 last_rword
= RES_XXXX
;
3934 last_followup
= PIPE_SEQ
;
3935 rcode
= G
.last_exitcode
;
3937 /* Go through list of pipes, (maybe) executing them. */
3938 for (; pi
; pi
= USE_HUSH_LOOPS(rword
== RES_DONE
? loop_top
: ) pi
->next
) {
3942 IF_HAS_KEYWORDS(rword
= pi
->res_word
;)
3943 debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n",
3944 rword
, cond_code
, last_rword
);
3945 #if ENABLE_HUSH_LOOPS
3946 if ((rword
== RES_WHILE
|| rword
== RES_UNTIL
|| rword
== RES_FOR
)
3947 && loop_top
== NULL
/* avoid bumping G.depth_of_loop twice */
3949 /* start of a loop: remember where loop starts */
3954 /* Still in the same "if...", "then..." or "do..." branch? */
3955 if (IF_HAS_KEYWORDS(rword
== last_rword
&&) 1) {
3956 if ((rcode
== 0 && last_followup
== PIPE_OR
)
3957 || (rcode
!= 0 && last_followup
== PIPE_AND
)
3959 /* It is "<true> || CMD" or "<false> && CMD"
3960 * and we should not execute CMD */
3961 debug_printf_exec("skipped cmd because of || or &&\n");
3962 last_followup
= pi
->followup
;
3966 last_followup
= pi
->followup
;
3967 IF_HAS_KEYWORDS(last_rword
= rword
;)
3970 if (rword
== RES_THEN
) {
3971 /* if false; then ... fi has exitcode 0! */
3972 G
.last_exitcode
= rcode
= EXIT_SUCCESS
;
3973 /* "if <false> THEN cmd": skip cmd */
3977 if (rword
== RES_ELSE
|| rword
== RES_ELIF
) {
3978 /* "if <true> then ... ELSE/ELIF cmd":
3979 * skip cmd and all following ones */
3984 #if ENABLE_HUSH_LOOPS
3985 if (rword
== RES_FOR
) { /* && pi->num_cmds - always == 1 */
3987 /* first loop through for */
3989 static const char encoded_dollar_at
[] ALIGN1
= {
3990 SPECIAL_VAR_SYMBOL
, '@' | 0x80, SPECIAL_VAR_SYMBOL
, '\0'
3991 }; /* encoded representation of "$@" */
3992 static const char *const encoded_dollar_at_argv
[] = {
3993 encoded_dollar_at
, NULL
3994 }; /* argv list with one element: "$@" */
3997 vals
= (char**)encoded_dollar_at_argv
;
3998 if (pi
->next
->res_word
== RES_IN
) {
3999 /* if no variable values after "in" we skip "for" */
4000 if (!pi
->next
->cmds
[0].argv
) {
4001 G
.last_exitcode
= rcode
= EXIT_SUCCESS
;
4002 debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n");
4005 vals
= pi
->next
->cmds
[0].argv
;
4006 } /* else: "for var; do..." -> assume "$@" list */
4007 /* create list of variable values */
4008 debug_print_strings("for_list made from", vals
);
4009 for_list
= expand_strvec_to_strvec(vals
);
4010 for_lcur
= for_list
;
4011 debug_print_strings("for_list", for_list
);
4014 /* "for" loop is over, clean up */
4020 /* Insert next value from for_lcur */
4021 /* note: *for_lcur already has quotes removed, $var expanded, etc */
4022 set_local_var(xasprintf("%s=%s", pi
->cmds
[0].argv
[0], *for_lcur
++), 0, 0);
4025 if (rword
== RES_IN
) {
4026 continue; /* "for v IN list;..." - "in" has no cmds anyway */
4028 if (rword
== RES_DONE
) {
4029 continue; /* "done" has no cmds too */
4032 #if ENABLE_HUSH_CASE
4033 if (rword
== RES_CASE
) {
4034 case_word
= expand_strvec_to_string(pi
->cmds
->argv
);
4037 if (rword
== RES_MATCH
) {
4040 if (!case_word
) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
4042 /* all prev words didn't match, does this one match? */
4043 argv
= pi
->cmds
->argv
;
4045 char *pattern
= expand_string_to_string(*argv
);
4046 /* TODO: which FNM_xxx flags to use? */
4047 cond_code
= (fnmatch(pattern
, case_word
, /*flags:*/ 0) != 0);
4049 if (cond_code
== 0) { /* match! we will execute this branch */
4050 free(case_word
); /* make future "word)" stop */
4058 if (rword
== RES_CASE_BODY
) { /* inside of a case branch */
4060 continue; /* not matched yet, skip this pipe */
4063 /* Just pressing <enter> in shell should check for jobs.
4064 * OTOH, in non-interactive shell this is useless
4065 * and only leads to extra job checks */
4066 if (pi
->num_cmds
== 0) {
4067 if (G_interactive_fd
)
4068 goto check_jobs_and_continue
;
4072 /* After analyzing all keywords and conditions, we decided
4073 * to execute this pipe. NB: have to do checkjobs(NULL)
4074 * after run_pipe to collect any background children,
4075 * even if list execution is to be stopped. */
4076 debug_printf_exec(": run_pipe with %d members\n", pi
->num_cmds
);
4079 #if ENABLE_HUSH_LOOPS
4080 G
.flag_break_continue
= 0;
4082 rcode
= r
= run_pipe(pi
); /* NB: rcode is a smallint */
4084 /* We ran a builtin, function, or group.
4085 * rcode is already known
4086 * and we don't need to wait for anything. */
4087 G
.last_exitcode
= rcode
;
4088 debug_printf_exec(": builtin/func exitcode %d\n", rcode
);
4089 check_and_run_traps(0);
4090 #if ENABLE_HUSH_LOOPS
4091 /* Was it "break" or "continue"? */
4092 if (G
.flag_break_continue
) {
4093 smallint fbc
= G
.flag_break_continue
;
4094 /* We might fall into outer *loop*,
4095 * don't want to break it too */
4097 G
.depth_break_continue
--;
4098 if (G
.depth_break_continue
== 0)
4099 G
.flag_break_continue
= 0;
4100 /* else: e.g. "continue 2" should *break* once, *then* continue */
4101 } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
4102 if (G
.depth_break_continue
!= 0 || fbc
== BC_BREAK
)
4103 goto check_jobs_and_break
;
4104 /* "continue": simulate end of loop */
4109 #if ENABLE_HUSH_FUNCTIONS
4110 if (G
.flag_return_in_progress
== 1) {
4111 /* same as "goto check_jobs_and_break" */
4116 } else if (pi
->followup
== PIPE_BG
) {
4117 /* What does bash do with attempts to background builtins? */
4118 /* even bash 3.2 doesn't do that well with nested bg:
4119 * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
4120 * I'm NOT treating inner &'s as jobs */
4121 check_and_run_traps(0);
4123 if (G
.run_list_level
== 1)
4126 G
.last_exitcode
= rcode
= EXIT_SUCCESS
;
4127 debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
4130 if (G
.run_list_level
== 1 && G_interactive_fd
) {
4131 /* Waits for completion, then fg's main shell */
4132 rcode
= checkjobs_and_fg_shell(pi
);
4133 debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode
);
4134 check_and_run_traps(0);
4137 { /* This one just waits for completion */
4138 rcode
= checkjobs(pi
);
4139 debug_printf_exec(": checkjobs exitcode %d\n", rcode
);
4140 check_and_run_traps(0);
4142 G
.last_exitcode
= rcode
;
4146 /* Analyze how result affects subsequent commands */
4148 if (rword
== RES_IF
|| rword
== RES_ELIF
)
4151 #if ENABLE_HUSH_LOOPS
4152 /* Beware of "while false; true; do ..."! */
4153 if (pi
->next
&& pi
->next
->res_word
== RES_DO
) {
4154 if (rword
== RES_WHILE
) {
4156 /* "while false; do...done" - exitcode 0 */
4157 G
.last_exitcode
= rcode
= EXIT_SUCCESS
;
4158 debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
4159 goto check_jobs_and_break
;
4162 if (rword
== RES_UNTIL
) {
4164 debug_printf_exec(": until expr is true: breaking\n");
4165 check_jobs_and_break
:
4173 check_jobs_and_continue
:
4180 #if ENABLE_HUSH_LOOPS
4185 #if ENABLE_HUSH_CASE
4189 debug_printf_exec("run_list lvl %d return %d\n", G
.run_list_level
+ 1, rcode
);
4193 /* Select which version we will use */
4194 static int run_and_free_list(struct pipe
*pi
)
4197 debug_printf_exec("run_and_free_list entered\n");
4199 debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi
->num_cmds
);
4200 rcode
= run_list(pi
);
4202 /* free_pipe_list has the side effect of clearing memory.
4203 * In the long run that function can be merged with run_list,
4204 * but doing that now would hobble the debugging effort. */
4206 debug_printf_exec("run_and_free_list return %d\n", rcode
);
4211 static struct pipe
*new_pipe(void)
4214 pi
= xzalloc(sizeof(struct pipe
));
4215 /*pi->followup = 0; - deliberately invalid value */
4216 /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
4220 /* Command (member of a pipe) is complete, or we start a new pipe
4221 * if ctx->command is NULL.
4222 * No errors possible here.
4224 static int done_command(struct parse_context
*ctx
)
4226 /* The command is really already in the pipe structure, so
4227 * advance the pipe counter and make a new, null command. */
4228 struct pipe
*pi
= ctx
->pipe
;
4229 struct command
*command
= ctx
->command
;
4232 if (IS_NULL_CMD(command
)) {
4233 debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi
->num_cmds
);
4237 debug_printf_parse("done_command: ++num_cmds=%d\n", pi
->num_cmds
);
4238 //debug_print_tree(ctx->list_head, 20);
4240 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi
->num_cmds
);
4243 /* Only real trickiness here is that the uncommitted
4244 * command structure is not counted in pi->num_cmds. */
4245 pi
->cmds
= xrealloc(pi
->cmds
, sizeof(*pi
->cmds
) * (pi
->num_cmds
+1));
4246 ctx
->command
= command
= &pi
->cmds
[pi
->num_cmds
];
4248 memset(command
, 0, sizeof(*command
));
4249 return pi
->num_cmds
; /* used only for 0/nonzero check */
4252 static void done_pipe(struct parse_context
*ctx
, pipe_style type
)
4256 debug_printf_parse("done_pipe entered, followup %d\n", type
);
4257 /* Close previous command */
4258 not_null
= done_command(ctx
);
4259 ctx
->pipe
->followup
= type
;
4261 ctx
->pipe
->pi_inverted
= ctx
->ctx_inverted
;
4262 ctx
->ctx_inverted
= 0;
4263 ctx
->pipe
->res_word
= ctx
->ctx_res_w
;
4266 /* Without this check, even just <enter> on command line generates
4267 * tree of three NOPs (!). Which is harmless but annoying.
4268 * IOW: it is safe to do it unconditionally. */
4271 || ctx
->ctx_res_w
== RES_FI
4273 #if ENABLE_HUSH_LOOPS
4274 || ctx
->ctx_res_w
== RES_DONE
4275 || ctx
->ctx_res_w
== RES_FOR
4276 || ctx
->ctx_res_w
== RES_IN
4278 #if ENABLE_HUSH_CASE
4279 || ctx
->ctx_res_w
== RES_ESAC
4283 debug_printf_parse("done_pipe: adding new pipe: "
4284 "not_null:%d ctx->ctx_res_w:%d\n",
4285 not_null
, ctx
->ctx_res_w
);
4287 ctx
->pipe
->next
= new_p
;
4289 /* RES_THEN, RES_DO etc are "sticky" -
4290 * they remain set for pipes inside if/while.
4291 * This is used to control execution.
4292 * RES_FOR and RES_IN are NOT sticky (needed to support
4293 * cases where variable or value happens to match a keyword):
4295 #if ENABLE_HUSH_LOOPS
4296 if (ctx
->ctx_res_w
== RES_FOR
4297 || ctx
->ctx_res_w
== RES_IN
)
4298 ctx
->ctx_res_w
= RES_NONE
;
4300 #if ENABLE_HUSH_CASE
4301 if (ctx
->ctx_res_w
== RES_MATCH
)
4302 ctx
->ctx_res_w
= RES_CASE_BODY
;
4303 if (ctx
->ctx_res_w
== RES_CASE
)
4304 ctx
->ctx_res_w
= RES_CASE_IN
;
4306 ctx
->command
= NULL
; /* trick done_command below */
4307 /* Create the memory for command, roughly:
4308 * ctx->pipe->cmds = new struct command;
4309 * ctx->command = &ctx->pipe->cmds[0];
4312 //debug_print_tree(ctx->list_head, 10);
4314 debug_printf_parse("done_pipe return\n");
4317 static void initialize_context(struct parse_context
*ctx
)
4319 memset(ctx
, 0, sizeof(*ctx
));
4320 ctx
->pipe
= ctx
->list_head
= new_pipe();
4321 /* Create the memory for command, roughly:
4322 * ctx->pipe->cmds = new struct command;
4323 * ctx->command = &ctx->pipe->cmds[0];
4328 /* If a reserved word is found and processed, parse context is modified
4329 * and 1 is returned.
4332 struct reserved_combo
{
4335 unsigned char assignment_flag
;
4339 FLAG_END
= (1 << RES_NONE
),
4341 FLAG_IF
= (1 << RES_IF
),
4342 FLAG_THEN
= (1 << RES_THEN
),
4343 FLAG_ELIF
= (1 << RES_ELIF
),
4344 FLAG_ELSE
= (1 << RES_ELSE
),
4345 FLAG_FI
= (1 << RES_FI
),
4347 #if ENABLE_HUSH_LOOPS
4348 FLAG_FOR
= (1 << RES_FOR
),
4349 FLAG_WHILE
= (1 << RES_WHILE
),
4350 FLAG_UNTIL
= (1 << RES_UNTIL
),
4351 FLAG_DO
= (1 << RES_DO
),
4352 FLAG_DONE
= (1 << RES_DONE
),
4353 FLAG_IN
= (1 << RES_IN
),
4355 #if ENABLE_HUSH_CASE
4356 FLAG_MATCH
= (1 << RES_MATCH
),
4357 FLAG_ESAC
= (1 << RES_ESAC
),
4359 FLAG_START
= (1 << RES_XXXX
),
4362 static const struct reserved_combo
* match_reserved_word(o_string
*word
)
4364 /* Mostly a list of accepted follow-up reserved words.
4365 * FLAG_END means we are done with the sequence, and are ready
4366 * to turn the compound list into a command.
4367 * FLAG_START means the word must start a new compound list.
4369 static const struct reserved_combo reserved_list
[] = {
4371 { "!", RES_NONE
, NOT_ASSIGNMENT
, 0 },
4372 { "if", RES_IF
, WORD_IS_KEYWORD
, FLAG_THEN
| FLAG_START
},
4373 { "then", RES_THEN
, WORD_IS_KEYWORD
, FLAG_ELIF
| FLAG_ELSE
| FLAG_FI
},
4374 { "elif", RES_ELIF
, WORD_IS_KEYWORD
, FLAG_THEN
},
4375 { "else", RES_ELSE
, WORD_IS_KEYWORD
, FLAG_FI
},
4376 { "fi", RES_FI
, NOT_ASSIGNMENT
, FLAG_END
},
4378 #if ENABLE_HUSH_LOOPS
4379 { "for", RES_FOR
, NOT_ASSIGNMENT
, FLAG_IN
| FLAG_DO
| FLAG_START
},
4380 { "while", RES_WHILE
, WORD_IS_KEYWORD
, FLAG_DO
| FLAG_START
},
4381 { "until", RES_UNTIL
, WORD_IS_KEYWORD
, FLAG_DO
| FLAG_START
},
4382 { "in", RES_IN
, NOT_ASSIGNMENT
, FLAG_DO
},
4383 { "do", RES_DO
, WORD_IS_KEYWORD
, FLAG_DONE
},
4384 { "done", RES_DONE
, NOT_ASSIGNMENT
, FLAG_END
},
4386 #if ENABLE_HUSH_CASE
4387 { "case", RES_CASE
, NOT_ASSIGNMENT
, FLAG_MATCH
| FLAG_START
},
4388 { "esac", RES_ESAC
, NOT_ASSIGNMENT
, FLAG_END
},
4391 const struct reserved_combo
*r
;
4393 for (r
= reserved_list
; r
< reserved_list
+ ARRAY_SIZE(reserved_list
); r
++) {
4394 if (strcmp(word
->data
, r
->literal
) == 0)
4399 /* Return 0: not a keyword, 1: keyword
4401 static int reserved_word(o_string
*word
, struct parse_context
*ctx
)
4403 #if ENABLE_HUSH_CASE
4404 static const struct reserved_combo reserved_match
= {
4405 "", RES_MATCH
, NOT_ASSIGNMENT
, FLAG_MATCH
| FLAG_ESAC
4408 const struct reserved_combo
*r
;
4412 r
= match_reserved_word(word
);
4416 debug_printf("found reserved word %s, res %d\n", r
->literal
, r
->res
);
4417 #if ENABLE_HUSH_CASE
4418 if (r
->res
== RES_IN
&& ctx
->ctx_res_w
== RES_CASE_IN
) {
4419 /* "case word IN ..." - IN part starts first MATCH part */
4420 r
= &reserved_match
;
4423 if (r
->flag
== 0) { /* '!' */
4424 if (ctx
->ctx_inverted
) { /* bash doesn't accept '! ! true' */
4425 syntax_error("! ! command");
4426 ctx
->ctx_res_w
= RES_SNTX
;
4428 ctx
->ctx_inverted
= 1;
4431 if (r
->flag
& FLAG_START
) {
4432 struct parse_context
*old
;
4434 old
= xmalloc(sizeof(*old
));
4435 debug_printf_parse("push stack %p\n", old
);
4436 *old
= *ctx
; /* physical copy */
4437 initialize_context(ctx
);
4439 } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx
->old_flag
& (1 << r
->res
))) {
4440 syntax_error_at(word
->data
);
4441 ctx
->ctx_res_w
= RES_SNTX
;
4444 /* "{...} fi" is ok. "{...} if" is not
4446 * if { echo foo; } then { echo bar; } fi */
4447 if (ctx
->command
->group
)
4448 done_pipe(ctx
, PIPE_SEQ
);
4451 ctx
->ctx_res_w
= r
->res
;
4452 ctx
->old_flag
= r
->flag
;
4453 word
->o_assignment
= r
->assignment_flag
;
4455 if (ctx
->old_flag
& FLAG_END
) {
4456 struct parse_context
*old
;
4458 done_pipe(ctx
, PIPE_SEQ
);
4459 debug_printf_parse("pop stack %p\n", ctx
->stack
);
4461 old
->command
->group
= ctx
->list_head
;
4462 old
->command
->grp_type
= GRP_NORMAL
;
4464 o_addstr(&old
->as_string
, ctx
->as_string
.data
);
4465 o_free_unsafe(&ctx
->as_string
);
4466 old
->command
->group_as_string
= xstrdup(old
->as_string
.data
);
4467 debug_printf_parse("pop, remembering as:'%s'\n",
4468 old
->command
->group_as_string
);
4470 *ctx
= *old
; /* physical copy */
4477 /* Word is complete, look at it and update parsing context.
4478 * Normal return is 0. Syntax errors return 1.
4479 * Note: on return, word is reset, but not o_free'd!
4481 static int done_word(o_string
*word
, struct parse_context
*ctx
)
4483 struct command
*command
= ctx
->command
;
4485 debug_printf_parse("done_word entered: '%s' %p\n", word
->data
, command
);
4486 if (word
->length
== 0 && word
->o_quoted
== 0) {
4487 debug_printf_parse("done_word return 0: true null, ignored\n");
4491 if (ctx
->pending_redirect
) {
4492 /* We do not glob in e.g. >*.tmp case. bash seems to glob here
4493 * only if run as "bash", not "sh" */
4494 /* http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
4496 * ...the word that follows the redirection operator
4497 * shall be subjected to tilde expansion, parameter expansion,
4498 * command substitution, arithmetic expansion, and quote
4499 * removal. Pathname expansion shall not be performed
4500 * on the word by a non-interactive shell; an interactive
4501 * shell may perform it, but shall do so only when
4502 * the expansion would result in one word."
4504 ctx
->pending_redirect
->rd_filename
= xstrdup(word
->data
);
4505 /* Cater for >\file case:
4506 * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
4507 * Same with heredocs:
4508 * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
4510 if (ctx
->pending_redirect
->rd_type
== REDIRECT_HEREDOC
) {
4511 unbackslash(ctx
->pending_redirect
->rd_filename
);
4512 /* Is it <<"HEREDOC"? */
4513 if (word
->o_quoted
) {
4514 ctx
->pending_redirect
->rd_dup
|= HEREDOC_QUOTED
;
4517 debug_printf_parse("word stored in rd_filename: '%s'\n", word
->data
);
4518 ctx
->pending_redirect
= NULL
;
4520 /* If this word wasn't an assignment, next ones definitely
4521 * can't be assignments. Even if they look like ones. */
4522 if (word
->o_assignment
!= DEFINITELY_ASSIGNMENT
4523 && word
->o_assignment
!= WORD_IS_KEYWORD
4525 word
->o_assignment
= NOT_ASSIGNMENT
;
4527 if (word
->o_assignment
== DEFINITELY_ASSIGNMENT
)
4528 command
->assignment_cnt
++;
4529 word
->o_assignment
= MAYBE_ASSIGNMENT
;
4533 # if ENABLE_HUSH_CASE
4534 if (ctx
->ctx_dsemicolon
4535 && strcmp(word
->data
, "esac") != 0 /* not "... pattern) cmd;; esac" */
4537 /* already done when ctx_dsemicolon was set to 1: */
4538 /* ctx->ctx_res_w = RES_MATCH; */
4539 ctx
->ctx_dsemicolon
= 0;
4542 if (!command
->argv
/* if it's the first word... */
4543 # if ENABLE_HUSH_LOOPS
4544 && ctx
->ctx_res_w
!= RES_FOR
/* ...not after FOR or IN */
4545 && ctx
->ctx_res_w
!= RES_IN
4547 # if ENABLE_HUSH_CASE
4548 && ctx
->ctx_res_w
!= RES_CASE
4551 debug_printf_parse("checking '%s' for reserved-ness\n", word
->data
);
4552 if (reserved_word(word
, ctx
)) {
4553 o_reset_to_empty_unquoted(word
);
4554 debug_printf_parse("done_word return %d\n",
4555 (ctx
->ctx_res_w
== RES_SNTX
));
4556 return (ctx
->ctx_res_w
== RES_SNTX
);
4560 if (command
->group
) {
4561 /* "{ echo foo; } echo bar" - bad */
4562 syntax_error_at(word
->data
);
4563 debug_printf_parse("done_word return 1: syntax error, "
4564 "groups and arglists don't mix\n");
4567 if (word
->o_quoted
/* word had "xx" or 'xx' at least as part of it. */
4568 /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */
4569 && (word
->data
[0] == '\0' || word
->data
[0] == SPECIAL_VAR_SYMBOL
)
4570 /* (otherwise it's known to be not empty and is already safe) */
4572 /* exclude "$@" - it can expand to no word despite "" */
4573 char *p
= word
->data
;
4574 while (p
[0] == SPECIAL_VAR_SYMBOL
4575 && (p
[1] & 0x7f) == '@'
4576 && p
[2] == SPECIAL_VAR_SYMBOL
4580 if (p
== word
->data
|| p
[0] != '\0') {
4581 /* saw no "$@", or not only "$@" but some
4582 * real text is there too */
4583 /* insert "empty variable" reference, this makes
4584 * e.g. "", $empty"" etc to not disappear */
4585 o_addchr(word
, SPECIAL_VAR_SYMBOL
);
4586 o_addchr(word
, SPECIAL_VAR_SYMBOL
);
4589 command
->argv
= add_string_to_strings(command
->argv
, xstrdup(word
->data
));
4590 debug_print_strings("word appended to argv", command
->argv
);
4593 #if ENABLE_HUSH_LOOPS
4594 if (ctx
->ctx_res_w
== RES_FOR
) {
4596 || !is_well_formed_var_name(command
->argv
[0], '\0')
4598 /* bash says just "not a valid identifier" */
4599 syntax_error("not a valid identifier in for");
4602 /* Force FOR to have just one word (variable name) */
4603 /* NB: basically, this makes hush see "for v in ..."
4604 * syntax as if it is "for v; in ...". FOR and IN become
4605 * two pipe structs in parse tree. */
4606 done_pipe(ctx
, PIPE_SEQ
);
4609 #if ENABLE_HUSH_CASE
4610 /* Force CASE to have just one word */
4611 if (ctx
->ctx_res_w
== RES_CASE
) {
4612 done_pipe(ctx
, PIPE_SEQ
);
4616 o_reset_to_empty_unquoted(word
);
4618 debug_printf_parse("done_word return 0\n");
4623 /* Peek ahead in the input to find out if we have a "&n" construct,
4624 * as in "2>&1", that represents duplicating a file descriptor.
4626 * REDIRFD_CLOSE if >&- "close fd" construct is seen,
4627 * REDIRFD_SYNTAX_ERR if syntax error,
4628 * REDIRFD_TO_FILE if no & was seen,
4629 * or the number found.
4632 #define parse_redir_right_fd(as_string, input) \
4633 parse_redir_right_fd(input)
4635 static int parse_redir_right_fd(o_string
*as_string
, struct in_str
*input
)
4641 return REDIRFD_TO_FILE
;
4643 ch
= i_getch(input
); /* get the & */
4644 nommu_addchr(as_string
, ch
);
4647 ch
= i_getch(input
);
4648 nommu_addchr(as_string
, ch
);
4649 return REDIRFD_CLOSE
;
4653 while (ch
!= EOF
&& isdigit(ch
)) {
4654 d
= d
*10 + (ch
-'0');
4656 ch
= i_getch(input
);
4657 nommu_addchr(as_string
, ch
);
4662 //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
4664 bb_error_msg("ambiguous redirect");
4665 return REDIRFD_SYNTAX_ERR
;
4668 /* Return code is 0 normal, 1 if a syntax error is detected
4670 static int parse_redirect(struct parse_context
*ctx
,
4673 struct in_str
*input
)
4675 struct command
*command
= ctx
->command
;
4676 struct redir_struct
*redir
;
4677 struct redir_struct
**redirp
;
4680 dup_num
= REDIRFD_TO_FILE
;
4681 if (style
!= REDIRECT_HEREDOC
) {
4682 /* Check for a '>&1' type redirect */
4683 dup_num
= parse_redir_right_fd(&ctx
->as_string
, input
);
4684 if (dup_num
== REDIRFD_SYNTAX_ERR
)
4687 int ch
= i_peek(input
);
4688 dup_num
= (ch
== '-'); /* HEREDOC_SKIPTABS bit is 1 */
4689 if (dup_num
) { /* <<-... */
4690 ch
= i_getch(input
);
4691 nommu_addchr(&ctx
->as_string
, ch
);
4696 if (style
== REDIRECT_OVERWRITE
&& dup_num
== REDIRFD_TO_FILE
) {
4697 int ch
= i_peek(input
);
4699 /* >|FILE redirect ("clobbering" >).
4700 * Since we do not support "set -o noclobber" yet,
4701 * >| and > are the same for now. Just eat |.
4703 ch
= i_getch(input
);
4704 nommu_addchr(&ctx
->as_string
, ch
);
4708 /* Create a new redir_struct and append it to the linked list */
4709 redirp
= &command
->redirects
;
4710 while ((redir
= *redirp
) != NULL
) {
4711 redirp
= &(redir
->next
);
4713 *redirp
= redir
= xzalloc(sizeof(*redir
));
4714 /* redir->next = NULL; */
4715 /* redir->rd_filename = NULL; */
4716 redir
->rd_type
= style
;
4717 redir
->rd_fd
= (fd
== -1) ? redir_table
[style
].default_fd
: fd
;
4719 debug_printf_parse("redirect type %d %s\n", redir
->rd_fd
,
4720 redir_table
[style
].descrip
);
4722 redir
->rd_dup
= dup_num
;
4723 if (style
!= REDIRECT_HEREDOC
&& dup_num
!= REDIRFD_TO_FILE
) {
4724 /* Erik had a check here that the file descriptor in question
4725 * is legit; I postpone that to "run time"
4726 * A "-" representation of "close me" shows up as a -3 here */
4727 debug_printf_parse("duplicating redirect '%d>&%d'\n",
4728 redir
->rd_fd
, redir
->rd_dup
);
4730 /* Set ctx->pending_redirect, so we know what to do at the
4731 * end of the next parsed word. */
4732 ctx
->pending_redirect
= redir
;
4737 /* If a redirect is immediately preceded by a number, that number is
4738 * supposed to tell which file descriptor to redirect. This routine
4739 * looks for such preceding numbers. In an ideal world this routine
4740 * needs to handle all the following classes of redirects...
4741 * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo
4742 * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo
4743 * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo
4744 * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo
4746 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
4748 * ... If n is quoted, the number shall not be recognized as part of
4749 * the redirection expression. For example:
4751 * writes the character 2 into file a"
4752 * We are getting it right by setting ->o_quoted on any \<char>
4754 * A -1 return means no valid number was found,
4755 * the caller should use the appropriate default for this redirection.
4757 static int redirect_opt_num(o_string
*o
)
4761 if (o
->data
== NULL
)
4763 num
= bb_strtou(o
->data
, NULL
, 10);
4764 if (errno
|| num
< 0)
4766 o_reset_to_empty_unquoted(o
);
4771 #define fetch_till_str(as_string, input, word, skip_tabs) \
4772 fetch_till_str(input, word, skip_tabs)
4774 static char *fetch_till_str(o_string
*as_string
,
4775 struct in_str
*input
,
4779 o_string heredoc
= NULL_O_STRING
;
4785 ch
= i_getch(input
);
4786 nommu_addchr(as_string
, ch
);
4788 if (strcmp(heredoc
.data
+ past_EOL
, word
) == 0) {
4789 heredoc
.data
[past_EOL
] = '\0';
4790 debug_printf_parse("parsed heredoc '%s'\n", heredoc
.data
);
4791 return heredoc
.data
;
4794 o_addchr(&heredoc
, ch
);
4795 past_EOL
= heredoc
.length
;
4798 ch
= i_getch(input
);
4799 nommu_addchr(as_string
, ch
);
4800 } while (skip_tabs
&& ch
== '\t');
4801 } while (ch
== '\n');
4804 o_free_unsafe(&heredoc
);
4807 o_addchr(&heredoc
, ch
);
4808 nommu_addchr(as_string
, ch
);
4812 /* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
4813 * and load them all. There should be exactly heredoc_cnt of them.
4815 static int fetch_heredocs(int heredoc_cnt
, struct parse_context
*ctx
, struct in_str
*input
)
4817 struct pipe
*pi
= ctx
->list_head
;
4819 while (pi
&& heredoc_cnt
) {
4821 struct command
*cmd
= pi
->cmds
;
4823 debug_printf_parse("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n",
4825 cmd
->argv
? cmd
->argv
[0] : "NONE");
4826 for (i
= 0; i
< pi
->num_cmds
; i
++) {
4827 struct redir_struct
*redir
= cmd
->redirects
;
4829 debug_printf_parse("fetch_heredocs: %d cmd argv0:'%s'\n",
4830 i
, cmd
->argv
? cmd
->argv
[0] : "NONE");
4832 if (redir
->rd_type
== REDIRECT_HEREDOC
) {
4835 redir
->rd_type
= REDIRECT_HEREDOC2
;
4836 /* redir->dup is (ab)used to indicate <<- */
4837 p
= fetch_till_str(&ctx
->as_string
, input
,
4838 redir
->rd_filename
, redir
->rd_dup
& HEREDOC_SKIPTABS
);
4840 syntax_error("unexpected EOF in here document");
4843 free(redir
->rd_filename
);
4844 redir
->rd_filename
= p
;
4847 redir
= redir
->next
;
4854 /* Should be 0. If it isn't, it's a parse error */
4856 bb_error_msg_and_die("heredoc BUG 2");
4862 #if ENABLE_HUSH_TICK
4863 static FILE *generate_stream_from_string(const char *s
)
4866 int pid
, channel
[2];
4872 pid
= BB_MMU
? fork() : vfork();
4874 bb_perror_msg_and_die(BB_MMU
? "fork" : "vfork");
4876 if (pid
== 0) { /* child */
4877 disable_restore_tty_pgrp_on_exit();
4878 /* Process substitution is not considered to be usual
4879 * 'command execution'.
4880 * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
4887 close(channel
[0]); /* NB: close _first_, then move fd! */
4888 xmove_fd(channel
[1], 1);
4889 /* Prevent it from trying to handle ctrl-z etc */
4890 USE_HUSH_JOB(G
.run_list_level
= 1;)
4892 reset_traps_to_defaults();
4893 parse_and_run_string(s
);
4894 _exit(G
.last_exitcode
);
4896 /* We re-execute after vfork on NOMMU. This makes this script safe:
4897 * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG
4898 * huge=`cat BIG` # was blocking here forever
4901 re_execute_shell(&to_free
,
4909 #if ENABLE_HUSH_FAST
4911 //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);
4913 enable_restore_tty_pgrp_on_exit();
4918 pf
= fdopen(channel
[0], "r");
4922 /* Return code is exit status of the process that is run. */
4923 static int process_command_subs(o_string
*dest
, const char *s
)
4926 struct in_str pipe_str
;
4929 pf
= generate_stream_from_string(s
);
4932 close_on_exec_on(fileno(pf
));
4934 /* Now send results of command back into original context */
4935 setup_file_in_str(&pipe_str
, pf
);
4937 while ((ch
= i_getch(&pipe_str
)) != EOF
) {
4943 o_addchr(dest
, '\n');
4946 o_addQchr(dest
, ch
);
4949 debug_printf("done reading from pipe, pclose()ing\n");
4950 /* Note: we got EOF, and we just close the read end of the pipe.
4951 * We do not wait for the `cmd` child to terminate. bash and ash do.
4953 * echo `echo Hi; exec 1>&-; sleep 2` - bash waits 2 sec
4954 * `false`; echo $? - bash outputs "1"
4957 debug_printf("closed FILE from child. return 0\n");
4962 static int parse_group(o_string
*dest
, struct parse_context
*ctx
,
4963 struct in_str
*input
, int ch
)
4965 /* dest contains characters seen prior to ( or {.
4966 * Typically it's empty, but for function defs,
4967 * it contains function name (without '()'). */
4968 struct pipe
*pipe_list
;
4970 struct command
*command
= ctx
->command
;
4972 debug_printf_parse("parse_group entered\n");
4973 #if ENABLE_HUSH_FUNCTIONS
4974 if (ch
== '(' && !dest
->o_quoted
) {
4976 if (done_word(dest
, ctx
))
4979 goto skip
; /* (... */
4980 if (command
->argv
[1]) { /* word word ... (... */
4981 syntax_error_unexpected_ch('(');
4984 /* it is "word(..." or "word (..." */
4986 ch
= i_getch(input
);
4987 while (ch
== ' ' || ch
== '\t');
4989 syntax_error_unexpected_ch(ch
);
4992 nommu_addchr(&ctx
->as_string
, ch
);
4994 ch
= i_getch(input
);
4995 while (ch
== ' ' || ch
== '\t' || ch
== '\n');
4997 syntax_error_unexpected_ch(ch
);
5000 nommu_addchr(&ctx
->as_string
, ch
);
5001 command
->grp_type
= GRP_FUNCTION
;
5005 if (command
->argv
/* word [word]{... */
5006 || dest
->length
/* word{... */
5007 || dest
->o_quoted
/* ""{... */
5010 debug_printf_parse("parse_group return 1: "
5011 "syntax error, groups and arglists don't mix\n");
5015 #if ENABLE_HUSH_FUNCTIONS
5021 command
->grp_type
= GRP_SUBSHELL
;
5023 /* bash does not allow "{echo...", requires whitespace */
5024 ch
= i_getch(input
);
5025 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\n') {
5026 syntax_error_unexpected_ch(ch
);
5029 nommu_addchr(&ctx
->as_string
, ch
);
5034 char *as_string
= NULL
;
5036 pipe_list
= parse_stream(&as_string
, input
, endch
);
5039 o_addstr(&ctx
->as_string
, as_string
);
5041 /* empty ()/{} or parse error? */
5042 if (!pipe_list
|| pipe_list
== ERR_PTR
) {
5043 /* parse_stream already emitted error msg */
5047 debug_printf_parse("parse_group return 1: "
5048 "parse_stream returned %p\n", pipe_list
);
5051 command
->group
= pipe_list
;
5053 as_string
[strlen(as_string
) - 1] = '\0'; /* plink ')' or '}' */
5054 command
->group_as_string
= as_string
;
5055 debug_printf_parse("end of group, remembering as:'%s'\n",
5056 command
->group_as_string
);
5059 debug_printf_parse("parse_group return 0\n");
5061 /* command remains "open", available for possible redirects */
5064 #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT
5065 /* Subroutines for copying $(...) and `...` things */
5066 static void add_till_backquote(o_string
*dest
, struct in_str
*input
);
5068 static void add_till_single_quote(o_string
*dest
, struct in_str
*input
)
5071 int ch
= i_getch(input
);
5073 syntax_error_unterm_ch('\'');
5074 /*xfunc_die(); - redundant */
5081 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
5082 static void add_till_double_quote(o_string
*dest
, struct in_str
*input
)
5085 int ch
= i_getch(input
);
5087 syntax_error_unterm_ch('"');
5088 /*xfunc_die(); - redundant */
5092 if (ch
== '\\') { /* \x. Copy both chars. */
5094 ch
= i_getch(input
);
5098 add_till_backquote(dest
, input
);
5102 //if (ch == '$') ...
5105 /* Process `cmd` - copy contents until "`" is seen. Complicated by
5107 * "Within the backquoted style of command substitution, backslash
5108 * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
5109 * The search for the matching backquote shall be satisfied by the first
5110 * backquote found without a preceding backslash; during this search,
5111 * if a non-escaped backquote is encountered within a shell comment,
5112 * a here-document, an embedded command substitution of the $(command)
5113 * form, or a quoted string, undefined results occur. A single-quoted
5114 * or double-quoted string that begins, but does not end, within the
5115 * "`...`" sequence produces undefined results."
5117 * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST
5119 static void add_till_backquote(o_string
*dest
, struct in_str
*input
)
5122 int ch
= i_getch(input
);
5124 syntax_error_unterm_ch('`');
5125 /*xfunc_die(); - redundant */
5130 /* \x. Copy both chars unless it is \` */
5131 int ch2
= i_getch(input
);
5133 syntax_error_unterm_ch('`');
5134 /*xfunc_die(); - redundant */
5136 if (ch2
!= '`' && ch2
!= '$' && ch2
!= '\\')
5143 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
5144 * quoting and nested ()s.
5145 * "With the $(command) style of command substitution, all characters
5146 * following the open parenthesis to the matching closing parenthesis
5147 * constitute the command. Any valid shell script can be used for command,
5148 * except a script consisting solely of redirections which produces
5149 * unspecified results."
5151 * echo $(echo '(TEST)' BEST) (TEST) BEST
5152 * echo $(echo 'TEST)' BEST) TEST) BEST
5153 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST
5155 static void add_till_closing_paren(o_string
*dest
, struct in_str
*input
, bool dbl
)
5159 int ch
= i_getch(input
);
5161 syntax_error_unterm_ch(')');
5162 /*xfunc_die(); - redundant */
5170 if (i_peek(input
) == ')') {
5178 add_till_single_quote(dest
, input
);
5183 add_till_double_quote(dest
, input
);
5188 /* \x. Copy verbatim. Important for \(, \) */
5189 ch
= i_getch(input
);
5191 syntax_error_unterm_ch(')');
5192 /*xfunc_die(); - redundant */
5199 #endif /* ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT */
5201 /* Return code: 0 for OK, 1 for syntax error */
5203 #define handle_dollar(as_string, dest, input) \
5204 handle_dollar(dest, input)
5206 static int handle_dollar(o_string
*as_string
,
5208 struct in_str
*input
)
5211 int ch
= i_peek(input
); /* first character after the $ */
5212 unsigned char quote_mask
= dest
->o_escape
? 0x80 : 0;
5214 debug_printf_parse("handle_dollar entered: ch='%c'\n", ch
);
5216 ch
= i_getch(input
);
5217 nommu_addchr(as_string
, ch
);
5219 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5221 debug_printf_parse(": '%c'\n", ch
);
5222 o_addchr(dest
, ch
| quote_mask
);
5225 if (!isalnum(ch
) && ch
!= '_')
5227 ch
= i_getch(input
);
5228 nommu_addchr(as_string
, ch
);
5230 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5231 } else if (isdigit(ch
)) {
5233 ch
= i_getch(input
);
5234 nommu_addchr(as_string
, ch
);
5235 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5236 debug_printf_parse(": '%c'\n", ch
);
5237 o_addchr(dest
, ch
| quote_mask
);
5238 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5239 } else switch (ch
) {
5241 case '!': /* last bg pid */
5242 case '?': /* last exit code */
5243 case '#': /* number of args */
5244 case '*': /* args */
5245 case '@': /* args */
5246 goto make_one_char_var
;
5248 bool first_char
, all_digits
;
5250 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5251 ch
= i_getch(input
);
5252 nommu_addchr(as_string
, ch
);
5253 /* TODO: maybe someone will try to escape the '}' */
5258 ch
= i_getch(input
);
5259 nommu_addchr(as_string
, ch
);
5266 /* ${#var}: length of var contents */
5273 /* They're being verbose and doing ${?} */
5274 if (i_peek(input
) == '}' && strchr("$!?#*@_", ch
))
5279 && ( (all_digits
&& !isdigit(ch
))
5280 || (!all_digits
&& !isalnum(ch
) && ch
!= '_')
5283 /* handle parameter expansions
5284 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
5289 case ':': /* null modifier */
5290 if (expansion
== 0) {
5291 debug_printf_parse(": null modifier\n");
5296 case '#': /* remove prefix */
5297 case '%': /* remove suffix */
5298 if (expansion
== 0) {
5299 debug_printf_parse(": remove suffix/prefix\n");
5304 case '-': /* default value */
5305 case '=': /* assign default */
5306 case '+': /* alternative */
5307 case '?': /* error indicate */
5308 debug_printf_parse(": parameter expansion\n");
5313 syntax_error_unterm_str("${name}");
5314 debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");
5319 debug_printf_parse(": '%c'\n", ch
);
5320 o_addchr(dest
, ch
| quote_mask
);
5324 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5327 #if (ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_TICK)
5332 ch
= i_getch(input
);
5333 nommu_addchr(as_string
, ch
);
5334 # if ENABLE_SH_MATH_SUPPORT
5335 if (i_peek(input
) == '(') {
5336 ch
= i_getch(input
);
5337 nommu_addchr(as_string
, ch
);
5338 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5339 o_addchr(dest
, /*quote_mask |*/ '+');
5343 add_till_closing_paren(dest
, input
, true);
5346 o_addstr(as_string
, dest
->data
+ pos
);
5347 o_addchr(as_string
, ')');
5348 o_addchr(as_string
, ')');
5351 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5355 # if ENABLE_HUSH_TICK
5356 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5357 o_addchr(dest
, quote_mask
| '`');
5361 add_till_closing_paren(dest
, input
, false);
5364 o_addstr(as_string
, dest
->data
+ pos
);
5365 o_addchr(as_string
, '`');
5368 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5374 ch
= i_getch(input
);
5375 nommu_addchr(as_string
, ch
);
5377 if (isalnum(ch
)) { /* it's $_name or $_123 */
5383 /* $_ Shell or shell script name; or last cmd name */
5384 /* $- Option flags set by set builtin or shell options (-i etc) */
5386 o_addQchr(dest
, '$');
5388 debug_printf_parse("handle_dollar return 0\n");
5393 #define parse_stream_dquoted(as_string, dest, input, dquote_end) \
5394 parse_stream_dquoted(dest, input, dquote_end)
5396 static int parse_stream_dquoted(o_string
*as_string
,
5398 struct in_str
*input
,
5405 ch
= i_getch(input
);
5407 nommu_addchr(as_string
, ch
);
5408 if (ch
== dquote_end
) { /* may be only '"' or EOF */
5409 if (dest
->o_assignment
== NOT_ASSIGNMENT
)
5410 dest
->o_escape
^= 1;
5411 debug_printf_parse("parse_stream_dquoted return 0\n");
5414 /* note: can't move it above ch == dquote_end check! */
5416 syntax_error_unterm_ch('"');
5417 /*xfunc_die(); - redundant */
5421 next
= i_peek(input
);
5423 debug_printf_parse(": ch=%c (%d) escape=%d\n",
5424 ch
, ch
, dest
->o_escape
);
5427 syntax_error("\\<eof>");
5431 * "The backslash retains its special meaning [in "..."]
5432 * only when followed by one of the following characters:
5433 * $, `, ", \, or <newline>. A double quote may be quoted
5434 * within double quotes by preceding it with a backslash."
5436 if (strchr("$`\"\\\n", next
) != NULL
) {
5437 ch
= i_getch(input
);
5439 o_addqchr(dest
, ch
);
5440 nommu_addchr(as_string
, ch
);
5443 o_addqchr(dest
, '\\');
5444 nommu_addchr(as_string
, '\\');
5449 if (handle_dollar(as_string
, dest
, input
) != 0) {
5450 debug_printf_parse("parse_stream_dquoted return 1: "
5451 "handle_dollar returned non-0\n");
5456 #if ENABLE_HUSH_TICK
5458 //int pos = dest->length;
5459 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5460 o_addchr(dest
, 0x80 | '`');
5461 add_till_backquote(dest
, input
);
5462 o_addchr(dest
, SPECIAL_VAR_SYMBOL
);
5463 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
5467 o_addQchr(dest
, ch
);
5469 && (dest
->o_assignment
== MAYBE_ASSIGNMENT
5470 || dest
->o_assignment
== WORD_IS_KEYWORD
)
5471 && is_well_formed_var_name(dest
->data
, '=')
5473 dest
->o_assignment
= DEFINITELY_ASSIGNMENT
;
5479 * Scan input until EOF or end_trigger char.
5480 * Return a list of pipes to execute, or NULL on EOF
5481 * or if end_trigger character is met.
5482 * On syntax error, exit is shell is not interactive,
5483 * reset parsing machinery and start parsing anew,
5484 * or return ERR_PTR.
5486 static struct pipe
*parse_stream(char **pstring
,
5487 struct in_str
*input
,
5490 struct parse_context ctx
;
5491 o_string dest
= NULL_O_STRING
;
5495 /* Double-quote state is handled in the state variable is_in_dquote.
5496 * A single-quote triggers a bypass of the main loop until its mate is
5497 * found. When recursing, quote state is passed in via dest->o_escape.
5499 debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
5500 end_trigger
? : 'X');
5503 G
.ifs
= get_local_var_value("IFS");
5508 #if ENABLE_HUSH_INTERACTIVE
5509 input
->promptmode
= 0; /* PS1 */
5511 /* dest.o_assignment = MAYBE_ASSIGNMENT; - already is */
5512 initialize_context(&ctx
);
5517 const char *is_special
;
5521 redir_type redir_style
;
5524 /* dest.o_quoted = 1; - already is (see below) */
5525 if (parse_stream_dquoted(&ctx
.as_string
, &dest
, input
, '"')) {
5528 /* We reached closing '"' */
5531 ch
= i_getch(input
);
5532 debug_printf_parse(": ch=%c (%d) escape=%d\n",
5533 ch
, ch
, dest
.o_escape
);
5538 syntax_error_unterm_str("here document");
5541 /* end_trigger == '}' case errors out earlier,
5542 * checking only ')' */
5543 if (end_trigger
== ')') {
5544 syntax_error_unterm_ch('('); /* exits */
5545 /* goto parse_error; */
5548 if (done_word(&dest
, &ctx
)) {
5552 done_pipe(&ctx
, PIPE_SEQ
);
5554 /* If we got nothing... */
5555 /* (this makes bare "&" cmd a no-op.
5556 * bash says: "syntax error near unexpected token '&'") */
5557 if (pi
->num_cmds
== 0
5558 IF_HAS_KEYWORDS( && pi
->res_word
== RES_NONE
)
5564 debug_printf_parse("as_string '%s'\n", ctx
.as_string
.data
);
5566 *pstring
= ctx
.as_string
.data
;
5568 o_free_unsafe(&ctx
.as_string
);
5571 debug_printf_parse("parse_stream return %p\n", pi
);
5574 nommu_addchr(&ctx
.as_string
, ch
);
5575 is_ifs
= strchr(G
.ifs
, ch
);
5576 is_special
= strchr("<>;&|(){}#'" /* special outside of "str" */
5577 "\\$\"" USE_HUSH_TICK("`") /* always special */
5580 if (!is_special
&& !is_ifs
) { /* ordinary char */
5582 o_addQchr(&dest
, ch
);
5583 if ((dest
.o_assignment
== MAYBE_ASSIGNMENT
5584 || dest
.o_assignment
== WORD_IS_KEYWORD
)
5586 && is_well_formed_var_name(dest
.data
, '=')
5588 dest
.o_assignment
= DEFINITELY_ASSIGNMENT
;
5594 if (done_word(&dest
, &ctx
)) {
5598 #if ENABLE_HUSH_CASE
5599 /* "case ... in <newline> word) ..." -
5600 * newlines are ignored (but ';' wouldn't be) */
5601 if (ctx
.command
->argv
== NULL
5602 && ctx
.ctx_res_w
== RES_MATCH
5607 /* Treat newline as a command separator. */
5608 done_pipe(&ctx
, PIPE_SEQ
);
5609 debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt
);
5611 if (fetch_heredocs(heredoc_cnt
, &ctx
, input
)) {
5616 dest
.o_assignment
= MAYBE_ASSIGNMENT
;
5618 /* note: if (is_ifs) continue;
5619 * will still trigger for us */
5623 /* "cmd}" or "cmd }..." without semicolon or &:
5624 * } is an ordinary char in this case, even inside { cmd; }
5625 * Pathological example: { ""}; } should exec "}" cmd
5628 if (!IS_NULL_CMD(ctx
.command
) /* cmd } */
5629 || dest
.length
!= 0 /* word} */
5630 || dest
.o_quoted
/* ""} */
5634 if (!IS_NULL_PIPE(ctx
.pipe
)) /* cmd | } */
5635 goto skip_end_trigger
;
5636 /* else: } does terminate a group */
5639 if (end_trigger
&& end_trigger
== ch
5640 && (ch
!= ';' || heredoc_cnt
== 0)
5641 #if ENABLE_HUSH_CASE
5643 || ctx
.ctx_res_w
!= RES_MATCH
5644 || (!dest
.o_quoted
&& strcmp(dest
.data
, "esac") == 0)
5649 /* This is technically valid:
5650 * { cat <<HERE; }; echo Ok
5654 * but we don't support this.
5655 * We require heredoc to be in enclosing {}/(),
5658 syntax_error_unterm_str("here document");
5661 if (done_word(&dest
, &ctx
)) {
5664 done_pipe(&ctx
, PIPE_SEQ
);
5665 dest
.o_assignment
= MAYBE_ASSIGNMENT
;
5666 /* Do we sit outside of any if's, loops or case's? */
5668 IF_HAS_KEYWORDS(|| (ctx
.ctx_res_w
== RES_NONE
&& ctx
.old_flag
== 0))
5672 debug_printf_parse("as_string '%s'\n", ctx
.as_string
.data
);
5674 *pstring
= ctx
.as_string
.data
;
5676 o_free_unsafe(&ctx
.as_string
);
5679 debug_printf_parse("parse_stream return %p: "
5680 "end_trigger char found\n",
5682 return ctx
.list_head
;
5691 next
= i_peek(input
);
5694 /* Catch <, > before deciding whether this word is
5695 * an assignment. a=1 2>z b=2: b=2 is still assignment */
5698 redir_fd
= redirect_opt_num(&dest
);
5699 if (done_word(&dest
, &ctx
)) {
5702 redir_style
= REDIRECT_OVERWRITE
;
5704 redir_style
= REDIRECT_APPEND
;
5705 ch
= i_getch(input
);
5706 nommu_addchr(&ctx
.as_string
, ch
);
5709 else if (next
== '(') {
5710 syntax_error(">(process) not supported");
5714 if (parse_redirect(&ctx
, redir_fd
, redir_style
, input
))
5716 continue; /* back to top of while (1) */
5718 redir_fd
= redirect_opt_num(&dest
);
5719 if (done_word(&dest
, &ctx
)) {
5722 redir_style
= REDIRECT_INPUT
;
5724 redir_style
= REDIRECT_HEREDOC
;
5726 debug_printf_parse("++heredoc_cnt=%d\n", heredoc_cnt
);
5727 ch
= i_getch(input
);
5728 nommu_addchr(&ctx
.as_string
, ch
);
5729 } else if (next
== '>') {
5730 redir_style
= REDIRECT_IO
;
5731 ch
= i_getch(input
);
5732 nommu_addchr(&ctx
.as_string
, ch
);
5735 else if (next
== '(') {
5736 syntax_error("<(process) not supported");
5740 if (parse_redirect(&ctx
, redir_fd
, redir_style
, input
))
5742 continue; /* back to top of while (1) */
5745 if (dest
.o_assignment
== MAYBE_ASSIGNMENT
5746 /* check that we are not in word in "a=1 2>word b=1": */
5747 && !ctx
.pending_redirect
5749 /* ch is a special char and thus this word
5750 * cannot be an assignment */
5751 dest
.o_assignment
= NOT_ASSIGNMENT
;
5756 if (dest
.length
== 0) {
5759 if (ch
== EOF
|| ch
== '\n')
5762 /* note: we do not add it to &ctx.as_string */
5764 nommu_addchr(&ctx
.as_string
, '\n');
5766 o_addQchr(&dest
, ch
);
5771 syntax_error("\\<eof>");
5774 ch
= i_getch(input
);
5776 o_addchr(&dest
, '\\');
5777 nommu_addchr(&ctx
.as_string
, '\\');
5778 o_addchr(&dest
, ch
);
5779 nommu_addchr(&ctx
.as_string
, ch
);
5780 /* Example: echo Hello \2>file
5781 * we need to know that word 2 is quoted */
5786 if (handle_dollar(&ctx
.as_string
, &dest
, input
) != 0) {
5787 debug_printf_parse("parse_stream parse error: "
5788 "handle_dollar returned non-0\n");
5795 ch
= i_getch(input
);
5797 syntax_error_unterm_ch('\'');
5798 /*xfunc_die(); - redundant */
5800 nommu_addchr(&ctx
.as_string
, ch
);
5803 o_addqchr(&dest
, ch
);
5808 is_in_dquote
^= 1; /* invert */
5809 if (dest
.o_assignment
== NOT_ASSIGNMENT
)
5812 #if ENABLE_HUSH_TICK
5817 o_addchr(&dest
, SPECIAL_VAR_SYMBOL
);
5818 o_addchr(&dest
, '`');
5822 add_till_backquote(&dest
, input
);
5824 o_addstr(&ctx
.as_string
, dest
.data
+ pos
);
5825 o_addchr(&ctx
.as_string
, '`');
5827 o_addchr(&dest
, SPECIAL_VAR_SYMBOL
);
5828 //debug_printf_subst("SUBST RES3 '%s'\n", dest.data + pos);
5833 #if ENABLE_HUSH_CASE
5836 if (done_word(&dest
, &ctx
)) {
5839 done_pipe(&ctx
, PIPE_SEQ
);
5840 #if ENABLE_HUSH_CASE
5841 /* Eat multiple semicolons, detect
5842 * whether it means something special */
5847 ch
= i_getch(input
);
5848 nommu_addchr(&ctx
.as_string
, ch
);
5849 if (ctx
.ctx_res_w
== RES_CASE_BODY
) {
5850 ctx
.ctx_dsemicolon
= 1;
5851 ctx
.ctx_res_w
= RES_MATCH
;
5857 /* We just finished a cmd. New one may start
5858 * with an assignment */
5859 dest
.o_assignment
= MAYBE_ASSIGNMENT
;
5862 if (done_word(&dest
, &ctx
)) {
5866 ch
= i_getch(input
);
5867 nommu_addchr(&ctx
.as_string
, ch
);
5868 done_pipe(&ctx
, PIPE_AND
);
5870 done_pipe(&ctx
, PIPE_BG
);
5874 if (done_word(&dest
, &ctx
)) {
5877 #if ENABLE_HUSH_CASE
5878 if (ctx
.ctx_res_w
== RES_MATCH
)
5879 break; /* we are in case's "word | word)" */
5881 if (next
== '|') { /* || */
5882 ch
= i_getch(input
);
5883 nommu_addchr(&ctx
.as_string
, ch
);
5884 done_pipe(&ctx
, PIPE_OR
);
5886 /* we could pick up a file descriptor choice here
5887 * with redirect_opt_num(), but bash doesn't do it.
5888 * "echo foo 2| cat" yields "foo 2". */
5893 #if ENABLE_HUSH_CASE
5894 /* "case... in [(]word)..." - skip '(' */
5895 if (ctx
.ctx_res_w
== RES_MATCH
5896 && ctx
.command
->argv
== NULL
/* not (word|(... */
5897 && dest
.length
== 0 /* not word(... */
5898 && dest
.o_quoted
== 0 /* not ""(... */
5904 if (parse_group(&dest
, &ctx
, input
, ch
) != 0) {
5909 #if ENABLE_HUSH_CASE
5910 if (ctx
.ctx_res_w
== RES_MATCH
)
5914 /* proper use of this character is caught by end_trigger:
5915 * if we see {, we call parse_group(..., end_trigger='}')
5916 * and it will match } earlier (not here). */
5917 syntax_error_unexpected_ch(ch
);
5921 bb_error_msg_and_die("BUG: unexpected %c\n", ch
);
5927 struct parse_context
*pctx
;
5928 IF_HAS_KEYWORDS(struct parse_context
*p2
;)
5930 /* Clean up allocated tree.
5931 * Samples for finding leaks on syntax error recovery path.
5932 * Run them from interactive shell, watch pmap `pidof hush`.
5933 * while if false; then false; fi do break; done
5935 * while if false; then false; fi; do break; fi
5936 * Samples to catch leaks at execution:
5937 * while if (true | {true;}); then echo ok; fi; do break; done
5938 * while if (true | {true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done
5942 /* Update pipe/command counts,
5943 * otherwise freeing may miss some */
5944 done_pipe(pctx
, PIPE_SEQ
);
5945 debug_printf_clean("freeing list %p from ctx %p\n",
5946 pctx
->list_head
, pctx
);
5947 debug_print_tree(pctx
->list_head
, 0);
5948 free_pipe_list(pctx
->list_head
);
5949 debug_printf_clean("freed list %p\n", pctx
->list_head
);
5951 o_free_unsafe(&pctx
->as_string
);
5953 IF_HAS_KEYWORDS(p2
= pctx
->stack
;)
5957 IF_HAS_KEYWORDS(pctx
= p2
;)
5958 } while (HAS_KEYWORDS
&& pctx
);
5959 /* Free text, clear all dest fields */
5961 /* If we are not in top-level parse, we return,
5962 * our caller will propagate error.
5964 if (end_trigger
!= ';') {
5972 /* Discard cached input, force prompt */
5974 USE_HUSH_INTERACTIVE(input
->promptme
= 1;)
5979 /* Executing from string: eval, sh -c '...'
5980 * or from file: /etc/profile, . file, sh <script>, sh (intereactive)
5981 * end_trigger controls how often we stop parsing
5982 * NUL: parse all, execute, return
5983 * ';': parse till ';' or newline, execute, repeat till EOF
5985 static void parse_and_run_stream(struct in_str
*inp
, int end_trigger
)
5988 struct pipe
*pipe_list
;
5990 pipe_list
= parse_stream(NULL
, inp
, end_trigger
);
5991 if (!pipe_list
) /* EOF */
5993 debug_print_tree(pipe_list
, 0);
5994 debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
5995 run_and_free_list(pipe_list
);
5999 static void parse_and_run_string(const char *s
)
6001 struct in_str input
;
6002 setup_string_in_str(&input
, s
);
6003 parse_and_run_stream(&input
, '\0');
6006 static void parse_and_run_file(FILE *f
)
6008 struct in_str input
;
6009 setup_file_in_str(&input
, f
);
6010 parse_and_run_stream(&input
, ';');
6013 /* Called a few times only (or even once if "sh -c") */
6014 static void block_signals(int second_time
)
6019 mask
= (1 << SIGQUIT
);
6020 if (G_interactive_fd
) {
6021 mask
= (1 << SIGQUIT
) | SPECIAL_INTERACTIVE_SIGS
;
6022 if (G_saved_tty_pgrp
) /* we have ctty, job control sigs work */
6023 mask
|= SPECIAL_JOB_SIGS
;
6025 G
.non_DFL_mask
= mask
;
6028 sigprocmask(SIG_SETMASK
, NULL
, &G
.blocked_set
);
6032 sigaddset(&G
.blocked_set
, sig
);
6036 sigdelset(&G
.blocked_set
, SIGCHLD
);
6038 sigprocmask(SIG_SETMASK
, &G
.blocked_set
,
6039 second_time
? NULL
: &G
.inherited_set
);
6040 /* POSIX allows shell to re-enable SIGCHLD
6041 * even if it was SIG_IGN on entry */
6042 #if ENABLE_HUSH_FAST
6043 G
.count_SIGCHLD
++; /* ensure it is != G.handled_SIGCHLD */
6045 signal(SIGCHLD
, SIGCHLD_handler
);
6048 signal(SIGCHLD
, SIG_DFL
);
6054 static void maybe_set_to_sigexit(int sig
)
6056 void (*handler
)(int);
6057 /* non_DFL_mask'ed signals are, well, masked,
6058 * no need to set handler for them.
6060 if (!((G
.non_DFL_mask
>> sig
) & 1)) {
6061 handler
= signal(sig
, sigexit
);
6062 if (handler
== SIG_IGN
) /* oops... restore back to IGN! */
6063 signal(sig
, handler
);
6066 /* Set handlers to restore tty pgrp and exit */
6067 static void set_fatal_handlers(void)
6069 /* We _must_ restore tty pgrp on fatal signals */
6071 maybe_set_to_sigexit(SIGILL
);
6072 maybe_set_to_sigexit(SIGFPE
);
6073 maybe_set_to_sigexit(SIGBUS
);
6074 maybe_set_to_sigexit(SIGSEGV
);
6075 maybe_set_to_sigexit(SIGTRAP
);
6076 } /* else: hush is perfect. what SEGV? */
6077 maybe_set_to_sigexit(SIGABRT
);
6078 /* bash 3.2 seems to handle these just like 'fatal' ones */
6079 maybe_set_to_sigexit(SIGPIPE
);
6080 maybe_set_to_sigexit(SIGALRM
);
6081 /* if we are interactive, SIGHUP, SIGTERM and SIGINT are masked.
6082 * if we aren't interactive... but in this case
6083 * we never want to restore pgrp on exit, and this fn is not called */
6084 /*maybe_set_to_sigexit(SIGHUP );*/
6085 /*maybe_set_to_sigexit(SIGTERM);*/
6086 /*maybe_set_to_sigexit(SIGINT );*/
6090 static int set_mode(const char cstate
, const char mode
)
6092 int state
= (cstate
== '-' ? 1 : 0);
6094 case 'n': G
.fake_mode
= state
; break;
6095 case 'x': /*G.debug_mode = state;*/ break;
6096 default: return EXIT_FAILURE
;
6098 return EXIT_SUCCESS
;
6101 int hush_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
6102 int hush_main(int argc
, char **argv
)
6104 static const struct variable const_shell_ver
= {
6106 .varstr
= (char*)hush_version_str
,
6107 .max_len
= 1, /* 0 can provoke free(name) */
6111 int signal_mask_is_inited
= 0;
6114 struct variable
*cur_var
;
6117 if (EXIT_SUCCESS
) /* if EXIT_SUCCESS == 0, is already done */
6118 G
.last_exitcode
= EXIT_SUCCESS
;
6120 G
.argv0_for_re_execing
= argv
[0];
6122 /* Deal with HUSH_VERSION */
6123 G
.shell_ver
= const_shell_ver
; /* copying struct here */
6124 G
.top_var
= &G
.shell_ver
;
6125 debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
6126 unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
6127 /* Initialize our shell local variables with the values
6128 * currently living in the environment */
6129 cur_var
= G
.top_var
;
6132 char *value
= strchr(*e
, '=');
6133 if (value
) { /* paranoia */
6134 cur_var
->next
= xzalloc(sizeof(*cur_var
));
6135 cur_var
= cur_var
->next
;
6136 cur_var
->varstr
= *e
;
6137 cur_var
->max_len
= strlen(*e
);
6138 cur_var
->flg_export
= 1;
6142 debug_printf_env("putenv '%s'\n", hush_version_str
);
6143 putenv((char *)hush_version_str
); /* reinstate HUSH_VERSION */
6144 #if ENABLE_FEATURE_EDITING
6145 G
.line_input_state
= new_line_input_t(FOR_SHELL
);
6147 G
.global_argc
= argc
;
6148 G
.global_argv
= argv
;
6149 /* Initialize some more globals to non-zero values */
6151 cmdedit_update_prompt();
6153 if (setjmp(die_jmp
)) {
6154 /* xfunc has failed! die die die */
6155 /* no EXIT traps, this is an escape hatch! */
6157 hush_exit(xfunc_error_retval
);
6160 /* Shell is non-interactive at first. We need to call
6161 * block_signals(0) if we are going to execute "sh <script>",
6162 * "sh -c <cmds>" or login shell's /etc/profile and friends.
6163 * If we later decide that we are interactive, we run block_signals(0)
6164 * (or re-run block_signals(1) if we ran block_signals(0) before)
6165 * in order to intercept (more) signals.
6169 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
6171 opt
= getopt(argc
, argv
, "c:xins"
6174 # if ENABLE_HUSH_FUNCTIONS
6184 G
.root_pid
= getpid();
6185 G
.global_argv
= argv
+ optind
;
6186 if (!argv
[optind
]) {
6187 /* -c 'script' (no params): prevent empty $0 */
6188 *--G
.global_argv
= argv
[0];
6190 } /* else -c 'script' PAR0 PAR1: $0 is PAR0 */
6191 G
.global_argc
= argc
- optind
;
6192 block_signals(0); /* 0: called 1st time */
6193 parse_and_run_string(optarg
);
6196 /* Well, we cannot just declare interactiveness,
6197 * we have to have some stuff (ctty, etc) */
6198 /* G_interactive_fd++; */
6201 /* "-s" means "read from stdin", but this is how we always
6202 * operate, so simply do nothing here. */
6205 case '<': /* "big heredoc" support */
6206 full_write(STDOUT_FILENO
, optarg
, strlen(optarg
));
6209 G
.root_pid
= bb_strtou(optarg
, &optarg
, 16);
6211 G
.last_bg_pid
= bb_strtou(optarg
, &optarg
, 16);
6213 G
.last_exitcode
= bb_strtou(optarg
, &optarg
, 16);
6214 # if ENABLE_HUSH_LOOPS
6216 G
.depth_of_loop
= bb_strtou(optarg
, &optarg
, 16);
6221 set_local_var(xstrdup(optarg
), 0, opt
== 'R');
6223 # if ENABLE_HUSH_FUNCTIONS
6225 struct function
*funcp
= new_function(optarg
);
6226 /* funcp->name is already set to optarg */
6227 /* funcp->body is set to NULL. It's a special case. */
6228 funcp
->body_as_string
= argv
[optind
];
6236 if (!set_mode('-', opt
))
6240 fprintf(stderr
, "Usage: sh [FILE]...\n"
6241 " or: sh -c command [args]...\n\n");
6247 } /* option parsing loop */
6250 G
.root_pid
= getpid();
6252 /* If we are login shell... */
6253 if (argv
[0] && argv
[0][0] == '-') {
6255 debug_printf("sourcing /etc/profile\n");
6256 input
= fopen_for_read("/etc/profile");
6257 if (input
!= NULL
) {
6258 close_on_exec_on(fileno(input
));
6259 block_signals(0); /* 0: called 1st time */
6260 signal_mask_is_inited
= 1;
6261 parse_and_run_file(input
);
6264 /* bash: after sourcing /etc/profile,
6265 * tries to source (in the given order):
6266 * ~/.bash_profile, ~/.bash_login, ~/.profile,
6267 * stopping of first found. --noprofile turns this off.
6268 * bash also sources ~/.bash_logout on exit.
6269 * If called as sh, skips .bash_XXX files.
6276 * "bash <script>" (which is never interactive (unless -i?))
6277 * sources $BASH_ENV here (without scanning $PATH).
6278 * If called as sh, does the same but with $ENV.
6280 debug_printf("running script '%s'\n", argv
[optind
]);
6281 G
.global_argv
= argv
+ optind
;
6282 G
.global_argc
= argc
- optind
;
6283 input
= xfopen_for_read(argv
[optind
]);
6284 close_on_exec_on(fileno(input
));
6285 if (!signal_mask_is_inited
)
6286 block_signals(0); /* 0: called 1st time */
6287 parse_and_run_file(input
);
6288 #if ENABLE_FEATURE_CLEAN_UP
6294 /* Up to here, shell was non-interactive. Now it may become one.
6295 * NB: don't forget to (re)run block_signals(0/1) as needed.
6298 /* A shell is interactive if the '-i' flag was given, or if all of
6299 * the following conditions are met:
6301 * no arguments remaining or the -s flag given
6302 * standard input is a terminal
6303 * standard output is a terminal
6304 * Refer to Posix.2, the description of the 'sh' utility.
6307 if (isatty(STDIN_FILENO
) && isatty(STDOUT_FILENO
)) {
6308 G_saved_tty_pgrp
= tcgetpgrp(STDIN_FILENO
);
6309 debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp
);
6310 if (G_saved_tty_pgrp
< 0)
6311 G_saved_tty_pgrp
= 0;
6313 /* try to dup stdin to high fd#, >= 255 */
6314 G_interactive_fd
= fcntl(STDIN_FILENO
, F_DUPFD
, 255);
6315 if (G_interactive_fd
< 0) {
6316 /* try to dup to any fd */
6317 G_interactive_fd
= dup(STDIN_FILENO
);
6318 if (G_interactive_fd
< 0) {
6320 G_interactive_fd
= 0;
6321 G_saved_tty_pgrp
= 0;
6324 // TODO: track & disallow any attempts of user
6325 // to (inadvertently) close/redirect G_interactive_fd
6327 debug_printf("interactive_fd:%d\n", G_interactive_fd
);
6328 if (G_interactive_fd
) {
6329 close_on_exec_on(G_interactive_fd
);
6331 if (G_saved_tty_pgrp
) {
6332 /* If we were run as 'hush &', sleep until we are
6333 * in the foreground (tty pgrp == our pgrp).
6334 * If we get started under a job aware app (like bash),
6335 * make sure we are now in charge so we don't fight over
6336 * who gets the foreground */
6338 pid_t shell_pgrp
= getpgrp();
6339 G_saved_tty_pgrp
= tcgetpgrp(G_interactive_fd
);
6340 if (G_saved_tty_pgrp
== shell_pgrp
)
6342 /* send TTIN to ourself (should stop us) */
6343 kill(- shell_pgrp
, SIGTTIN
);
6347 /* Block some signals */
6348 block_signals(signal_mask_is_inited
);
6350 if (G_saved_tty_pgrp
) {
6351 /* Set other signals to restore saved_tty_pgrp */
6352 set_fatal_handlers();
6353 /* Put ourselves in our own process group
6354 * (bash, too, does this only if ctty is available) */
6355 bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
6356 /* Grab control of the terminal */
6357 tcsetpgrp(G_interactive_fd
, getpid());
6359 /* -1 is special - makes xfuncs longjmp, not exit
6360 * (we reset die_sleep = 0 whereever we [v]fork) */
6361 enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */
6362 } else if (!signal_mask_is_inited
) {
6363 block_signals(0); /* 0: called 1st time */
6364 } /* else: block_signals(0) was done before */
6365 #elif ENABLE_HUSH_INTERACTIVE
6366 /* No job control compiled in, only prompt/line editing */
6367 if (isatty(STDIN_FILENO
) && isatty(STDOUT_FILENO
)) {
6368 G_interactive_fd
= fcntl(STDIN_FILENO
, F_DUPFD
, 255);
6369 if (G_interactive_fd
< 0) {
6370 /* try to dup to any fd */
6371 G_interactive_fd
= dup(STDIN_FILENO
);
6372 if (G_interactive_fd
< 0)
6374 G_interactive_fd
= 0;
6377 if (G_interactive_fd
) {
6378 close_on_exec_on(G_interactive_fd
);
6379 block_signals(signal_mask_is_inited
);
6380 } else if (!signal_mask_is_inited
) {
6384 /* We have interactiveness code disabled */
6385 if (!signal_mask_is_inited
) {
6390 * if interactive but not a login shell, sources ~/.bashrc
6391 * (--norc turns this off, --rcfile <file> overrides)
6394 if (!ENABLE_FEATURE_SH_EXTRA_QUIET
&& G_interactive_fd
) {
6395 printf("\n\n%s hush - the humble shell\n", bb_banner
);
6396 if (ENABLE_HUSH_HELP
)
6397 puts("Enter 'help' for a list of built-in commands.");
6401 parse_and_run_file(stdin
);
6404 #if ENABLE_FEATURE_CLEAN_UP
6405 if (G
.cwd
!= bb_msg_unknown
)
6407 cur_var
= G
.top_var
->next
;
6409 struct variable
*tmp
= cur_var
;
6410 if (!cur_var
->max_len
)
6411 free(cur_var
->varstr
);
6412 cur_var
= cur_var
->next
;
6416 hush_exit(G
.last_exitcode
);
6421 int lash_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
6422 int lash_main(int argc
, char **argv
)
6424 //bb_error_msg("lash is deprecated, please use hush instead");
6425 return hush_main(argc
, argv
);
6433 static int builtin_true(char **argv UNUSED_PARAM
)
6438 static int builtin_test(char **argv
)
6445 return test_main(argc
, argv
- argc
);
6448 static int builtin_echo(char **argv
)
6455 return echo_main(argc
, argv
- argc
);
6458 static int builtin_eval(char **argv
)
6460 int rcode
= EXIT_SUCCESS
;
6463 char *str
= expand_strvec_to_string(argv
);
6465 * eval "echo Hi; done" ("done" is syntax error):
6466 * "echo Hi" will not execute too.
6468 parse_and_run_string(str
);
6470 rcode
= G
.last_exitcode
;
6475 static int builtin_cd(char **argv
)
6477 const char *newdir
= argv
[1];
6478 if (newdir
== NULL
) {
6479 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
6480 * bash says "bash: cd: HOME not set" and does nothing
6483 newdir
= get_local_var_value("HOME") ? : "/";
6485 if (chdir(newdir
)) {
6486 /* Mimic bash message exactly */
6487 bb_perror_msg("cd: %s", newdir
);
6488 return EXIT_FAILURE
;
6491 return EXIT_SUCCESS
;
6494 static int builtin_exec(char **argv
)
6496 if (*++argv
== NULL
)
6497 return EXIT_SUCCESS
; /* bash does this */
6502 /* TODO: if exec fails, bash does NOT exit! We do... */
6503 pseudo_exec_argv(&dummy
, argv
, 0, NULL
);
6508 static int builtin_exit(char **argv
)
6510 debug_printf_exec("%s()\n", __func__
);
6512 /* interactive bash:
6513 * # trap "echo EEE" EXIT
6516 * There are stopped jobs.
6517 * (if there are _stopped_ jobs, running ones don't count)
6520 # EEE (then bash exits)
6522 * we can use G.exiting = -1 as indicator "last cmd was exit"
6525 /* note: EXIT trap is run by hush_exit */
6526 if (*++argv
== NULL
)
6527 hush_exit(G
.last_exitcode
);
6528 /* mimic bash: exit 123abc == exit 255 + error msg */
6529 xfunc_error_retval
= 255;
6530 /* bash: exit -2 == exit 254, no error msg */
6531 hush_exit(xatoi(*argv
) & 0xff);
6534 static void print_escaped(const char *s
)
6540 p
= strchrnul(s
, '\'');
6541 /* print 'xxxx', possibly just '' */
6542 printf("'%.*s'", (int)(p
- s
), s
);
6547 /* s points to '; print "'''...'''" */
6549 do putchar('\''); while (*++s
== '\'');
6554 static int builtin_export(char **argv
)
6556 unsigned opt_unexport
;
6558 if (argv
[1] == NULL
) {
6565 /* ash emits: export VAR='VAL'
6566 * bash: declare -x VAR="VAL"
6567 * we follow ash example */
6568 const char *s
= *e
++;
6569 const char *p
= strchr(s
, '=');
6571 if (!p
) /* wtf? take next variable */
6574 printf("export %.*s", (int)(p
- s
) + 1, s
);
6575 print_escaped(p
+ 1);
6579 /*fflush(stdout); - done after each builtin anyway */
6581 return EXIT_SUCCESS
;
6584 #if ENABLE_HUSH_EXPORT_N
6585 /* "!": do not abort on errors */
6586 /* "+": stop at 1st non-option */
6587 opt_unexport
= getopt32(argv
, "!+n");
6588 if (opt_unexport
== (unsigned)-1)
6589 return EXIT_FAILURE
;
6599 /* So far we do not check that name is valid (TODO?) */
6601 if (strchr(name
, '=') == NULL
) {
6602 struct variable
*var
;
6604 var
= get_local_var(name
);
6606 /* export -n NAME (without =VALUE) */
6608 var
->flg_export
= 0;
6609 debug_printf_env("%s: unsetenv '%s'\n", __func__
, name
);
6611 } /* else: export -n NOT_EXISTING_VAR: no-op */
6614 /* export NAME (without =VALUE) */
6616 var
->flg_export
= 1;
6617 debug_printf_env("%s: putenv '%s'\n", __func__
, var
->varstr
);
6618 putenv(var
->varstr
);
6621 /* Exporting non-existing variable.
6622 * bash does not put it in environment,
6623 * but remembers that it is exported,
6624 * and does put it in env when it is set later.
6625 * We just set it to "" and export. */
6626 name
= xasprintf("%s=", name
);
6628 /* (Un)exporting NAME=VALUE */
6629 name
= xstrdup(name
);
6632 /*export:*/ (opt_unexport
? -1 : 1),
6637 return EXIT_SUCCESS
;
6640 static int builtin_trap(char **argv
)
6646 G
.traps
= xzalloc(sizeof(G
.traps
[0]) * NSIG
);
6651 /* No args: print all trapped */
6652 for (i
= 0; i
< NSIG
; ++i
) {
6655 print_escaped(G
.traps
[i
]);
6656 printf(" %s\n", get_signame(i
));
6659 /*fflush(stdout); - done after each builtin anyway */
6660 return EXIT_SUCCESS
;
6664 /* If first arg is a number: reset all specified signals */
6665 sig
= bb_strtou(*argv
, NULL
, 10);
6671 sig
= get_signum(*argv
++);
6672 if (sig
< 0 || sig
>= NSIG
) {
6674 /* Mimic bash message exactly */
6675 bb_perror_msg("trap: %s: invalid signal specification", argv
[-1]);
6680 G
.traps
[sig
] = xstrdup(new_cmd
);
6682 debug_printf("trap: setting SIG%s (%i) to '%s'",
6683 get_signame(sig
), sig
, G
.traps
[sig
]);
6685 /* There is no signal for 0 (EXIT) */
6690 sigaddset(&G
.blocked_set
, sig
);
6692 /* There was a trap handler, we are removing it
6693 * (if sig has non-DFL handling,
6694 * we don't need to do anything) */
6695 if (sig
< 32 && (G
.non_DFL_mask
& (1 << sig
)))
6697 sigdelset(&G
.blocked_set
, sig
);
6700 sigprocmask(SIG_SETMASK
, &G
.blocked_set
, NULL
);
6704 if (!argv
[1]) { /* no second arg */
6705 bb_error_msg("trap: invalid arguments");
6706 return EXIT_FAILURE
;
6709 /* First arg is "-": reset all specified to default */
6710 /* First arg is "--": skip it, the rest is "handler SIGs..." */
6711 /* Everything else: set arg as signal handler
6712 * (includes "" case, which ignores signal) */
6713 if (argv
[0][0] == '-') {
6714 if (argv
[0][1] == '\0') { /* "-" */
6715 /* new_cmd remains NULL: "reset these sigs" */
6718 if (argv
[0][1] == '-' && argv
[0][2] == '\0') { /* "--" */
6721 /* else: "-something", no special meaning */
6726 goto process_sig_list
;
6730 /* built-in 'fg' and 'bg' handler */
6731 static int builtin_fg_bg(char **argv
)
6736 if (!G_interactive_fd
)
6737 return EXIT_FAILURE
;
6739 /* If they gave us no args, assume they want the last backgrounded task */
6741 for (pi
= G
.job_list
; pi
; pi
= pi
->next
) {
6742 if (pi
->jobid
== G
.last_jobid
) {
6746 bb_error_msg("%s: no current job", argv
[0]);
6747 return EXIT_FAILURE
;
6749 if (sscanf(argv
[1], "%%%d", &jobnum
) != 1) {
6750 bb_error_msg("%s: bad argument '%s'", argv
[0], argv
[1]);
6751 return EXIT_FAILURE
;
6753 for (pi
= G
.job_list
; pi
; pi
= pi
->next
) {
6754 if (pi
->jobid
== jobnum
) {
6758 bb_error_msg("%s: %d: no such job", argv
[0], jobnum
);
6759 return EXIT_FAILURE
;
6761 /* TODO: bash prints a string representation
6762 * of job being foregrounded (like "sleep 1 | cat") */
6763 if (argv
[0][0] == 'f' && G_saved_tty_pgrp
) {
6764 /* Put the job into the foreground. */
6765 tcsetpgrp(G_interactive_fd
, pi
->pgrp
);
6768 /* Restart the processes in the job */
6769 debug_printf_jobs("reviving %d procs, pgrp %d\n", pi
->num_cmds
, pi
->pgrp
);
6770 for (i
= 0; i
< pi
->num_cmds
; i
++) {
6771 debug_printf_jobs("reviving pid %d\n", pi
->cmds
[i
].pid
);
6772 pi
->cmds
[i
].is_stopped
= 0;
6774 pi
->stopped_cmds
= 0;
6776 i
= kill(- pi
->pgrp
, SIGCONT
);
6778 if (errno
== ESRCH
) {
6779 delete_finished_bg_job(pi
);
6780 return EXIT_SUCCESS
;
6782 bb_perror_msg("kill (SIGCONT)");
6785 if (argv
[0][0] == 'f') {
6787 return checkjobs_and_fg_shell(pi
);
6789 return EXIT_SUCCESS
;
6793 #if ENABLE_HUSH_HELP
6794 static int builtin_help(char **argv UNUSED_PARAM
)
6796 const struct built_in_command
*x
;
6799 "Built-in commands:\n"
6800 "------------------\n");
6801 for (x
= bltins
; x
!= &bltins
[ARRAY_SIZE(bltins
)]; x
++) {
6802 printf("%s\t%s\n", x
->cmd
, x
->descr
);
6805 return EXIT_SUCCESS
;
6810 static int builtin_jobs(char **argv UNUSED_PARAM
)
6813 const char *status_string
;
6815 for (job
= G
.job_list
; job
; job
= job
->next
) {
6816 if (job
->alive_cmds
== job
->stopped_cmds
)
6817 status_string
= "Stopped";
6819 status_string
= "Running";
6821 printf(JOB_STATUS_FORMAT
, job
->jobid
, status_string
, job
->cmdtext
);
6823 return EXIT_SUCCESS
;
6828 static int builtin_memleak(char **argv UNUSED_PARAM
)
6833 /* Crude attempt to find where "free memory" starts,
6834 * sans fragmentation. */
6836 l
= (unsigned long)p
;
6839 if (l
< (unsigned long)p
) l
= (unsigned long)p
;
6842 if (!G
.memleak_value
)
6843 G
.memleak_value
= l
;
6845 l
-= G
.memleak_value
;
6852 /* Exitcode is "how many kilobytes we leaked since 1st call" */
6857 static int builtin_pwd(char **argv UNUSED_PARAM
)
6860 return EXIT_SUCCESS
;
6863 static int builtin_read(char **argv
)
6866 const char *name
= "REPLY";
6870 /* bash (3.2.33(1)) bug: "read 0abcd" will execute,
6871 * and _after_ that_ it will complain */
6872 if (!is_well_formed_var_name(name
, '\0')) {
6873 /* Mimic bash message */
6874 bb_error_msg("read: '%s': not a valid identifier", name
);
6879 //TODO: bash unbackslashes input, splits words and puts them in argv[i]
6881 string
= xmalloc_reads(STDIN_FILENO
, xasprintf("%s=", name
), NULL
);
6882 return set_local_var(string
, 0, 0);
6885 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
6886 * built-in 'set' handler
6888 * set [-abCefhmnuvx] [-o option] [argument...]
6889 * set [+abCefhmnuvx] [+o option] [argument...]
6890 * set -- [argument...]
6893 * Implementations shall support the options in both their hyphen and
6894 * plus-sign forms. These options can also be specified as options to sh.
6896 * Write out all variables and their values: set
6897 * Set $1, $2, and $3 and set "$#" to 3: set c a b
6898 * Turn on the -x and -v options: set -xv
6899 * Unset all positional parameters: set --
6900 * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
6901 * Set the positional parameters to the expansion of x, even if x expands
6902 * with a leading '-' or '+': set -- $x
6904 * So far, we only support "set -- [argument...]" and some of the short names.
6906 static int builtin_set(char **argv
)
6909 char **pp
, **g_argv
;
6910 char *arg
= *++argv
;
6914 for (e
= G
.top_var
; e
; e
= e
->next
)
6916 return EXIT_SUCCESS
;
6920 if (!strcmp(arg
, "--")) {
6924 if (arg
[0] != '+' && arg
[0] != '-')
6926 for (n
= 1; arg
[n
]; ++n
)
6927 if (set_mode(arg
[0], arg
[n
]))
6929 } while ((arg
= *++argv
) != NULL
);
6930 /* Now argv[0] is 1st argument */
6933 return EXIT_SUCCESS
;
6936 /* NB: G.global_argv[0] ($0) is never freed/changed */
6937 g_argv
= G
.global_argv
;
6938 if (G
.global_args_malloced
) {
6944 G
.global_args_malloced
= 1;
6945 pp
= xzalloc(sizeof(pp
[0]) * 2);
6946 pp
[0] = g_argv
[0]; /* retain $0 */
6949 /* This realloc's G.global_argv */
6950 G
.global_argv
= pp
= add_strings_to_strings(g_argv
, argv
, /*dup:*/ 1);
6957 return EXIT_SUCCESS
;
6959 /* Nothing known, so abort */
6961 bb_error_msg("set: %s: invalid option", arg
);
6962 return EXIT_FAILURE
;
6965 static int builtin_shift(char **argv
)
6971 if (n
>= 0 && n
< G
.global_argc
) {
6972 if (G
.global_args_malloced
) {
6975 free(G
.global_argv
[m
++]);
6978 memmove(&G
.global_argv
[1], &G
.global_argv
[n
+1],
6979 G
.global_argc
* sizeof(G
.global_argv
[0]));
6980 return EXIT_SUCCESS
;
6982 return EXIT_FAILURE
;
6985 static int builtin_source(char **argv
)
6990 #if ENABLE_HUSH_FUNCTIONS
6994 if (*++argv
== NULL
)
6995 return EXIT_FAILURE
;
6997 if (strchr(*argv
, '/') == NULL
6998 && (PATH
= get_local_var_value("PATH")) != NULL
7000 /* Search through $PATH */
7002 const char *end
= strchrnul(PATH
, ':');
7003 int sz
= end
- PATH
; /* must be int! */
7006 char *tmp
= xasprintf("%.*s/%s", sz
, PATH
, *argv
);
7007 input
= fopen_for_read(tmp
);
7010 /* We have xxx::yyyy in $PATH,
7011 * it means "use current dir" */
7012 input
= fopen_for_read(*argv
);
7021 input
= fopen_or_warn(*argv
, "r");
7023 /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
7024 return EXIT_FAILURE
;
7027 close_on_exec_on(fileno(input
));
7029 #if ENABLE_HUSH_FUNCTIONS
7030 sv_flg
= G
.flag_return_in_progress
;
7031 /* "we are inside sourced file, ok to use return" */
7032 G
.flag_return_in_progress
= -1;
7034 save_and_replace_G_args(&sv
, argv
);
7036 parse_and_run_file(input
);
7039 restore_G_args(&sv
, argv
);
7040 #if ENABLE_HUSH_FUNCTIONS
7041 G
.flag_return_in_progress
= sv_flg
;
7044 return G
.last_exitcode
;
7047 static int builtin_umask(char **argv
)
7054 mode_t old_mask
= mask
;
7057 rc
= bb_parse_mode(argv
[1], &mask
);
7062 * bash: umask: 'q': invalid symbolic mode operator
7063 * bash: umask: 999: octal number out of range
7065 bb_error_msg("%s: '%s' invalid mode", argv
[0], argv
[1]);
7070 printf("%04o\n", (unsigned) mask
);
7071 /* fall through and restore mask which we set to 0 */
7075 return !rc
; /* rc != 0 - success */
7078 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
7079 static int builtin_unset(char **argv
)
7084 /* "!": do not abort on errors */
7085 /* "+": stop at 1st non-option */
7086 opts
= getopt32(argv
, "!+vf");
7087 if (opts
== (unsigned)-1)
7088 return EXIT_FAILURE
;
7090 bb_error_msg("unset: -v and -f are exclusive");
7091 return EXIT_FAILURE
;
7097 if (!(opts
& 2)) { /* not -f */
7098 if (unset_local_var(*argv
)) {
7099 /* unset <nonexistent_var> doesn't fail.
7100 * Error is when one tries to unset RO var.
7101 * Message was printed by unset_local_var. */
7105 #if ENABLE_HUSH_FUNCTIONS
7115 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
7116 static int builtin_wait(char **argv
)
7118 int ret
= EXIT_SUCCESS
;
7121 if (*++argv
== NULL
) {
7122 /* Don't care about wait results */
7123 /* Note 1: must wait until there are no more children */
7124 /* Note 2: must be interruptible */
7126 * $ sleep 3 & sleep 6 & wait
7131 * $ sleep 3 & sleep 6 & wait
7135 * ^C <-- after ~4 sec from keyboard
7138 sigaddset(&G
.blocked_set
, SIGCHLD
);
7139 sigprocmask(SIG_SETMASK
, &G
.blocked_set
, NULL
);
7142 if (errno
== ECHILD
)
7144 /* Wait for SIGCHLD or any other signal of interest */
7145 /* sigtimedwait with infinite timeout: */
7146 sig
= sigwaitinfo(&G
.blocked_set
, NULL
);
7148 sig
= check_and_run_traps(sig
);
7149 if (sig
&& sig
!= SIGCHLD
) { /* see note 2 */
7155 sigdelset(&G
.blocked_set
, SIGCHLD
);
7156 sigprocmask(SIG_SETMASK
, &G
.blocked_set
, NULL
);
7160 /* This is probably buggy wrt interruptible-ness */
7162 pid_t pid
= bb_strtou(*argv
, NULL
, 10);
7164 /* mimic bash message */
7165 bb_error_msg("wait: '%s': not a pid or valid job spec", *argv
);
7166 return EXIT_FAILURE
;
7168 if (waitpid(pid
, &status
, 0) == pid
) {
7169 if (WIFSIGNALED(status
))
7170 ret
= 128 + WTERMSIG(status
);
7171 else if (WIFEXITED(status
))
7172 ret
= WEXITSTATUS(status
);
7176 bb_perror_msg("wait %s", *argv
);
7185 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS
7186 static unsigned parse_numeric_argv1(char **argv
, unsigned def
, unsigned def_min
)
7189 def
= bb_strtou(argv
[1], NULL
, 10);
7190 if (errno
|| def
< def_min
|| argv
[2]) {
7191 bb_error_msg("%s: bad arguments", argv
[0]);
7199 #if ENABLE_HUSH_LOOPS
7200 static int builtin_break(char **argv
)
7203 if (G
.depth_of_loop
== 0) {
7204 bb_error_msg("%s: only meaningful in a loop", argv
[0]);
7205 return EXIT_SUCCESS
; /* bash compat */
7207 G
.flag_break_continue
++; /* BC_BREAK = 1 */
7209 G
.depth_break_continue
= depth
= parse_numeric_argv1(argv
, 1, 1);
7210 if (depth
== UINT_MAX
)
7211 G
.flag_break_continue
= BC_BREAK
;
7212 if (G
.depth_of_loop
< depth
)
7213 G
.depth_break_continue
= G
.depth_of_loop
;
7215 return EXIT_SUCCESS
;
7218 static int builtin_continue(char **argv
)
7220 G
.flag_break_continue
= 1; /* BC_CONTINUE = 2 = 1+1 */
7221 return builtin_break(argv
);
7225 #if ENABLE_HUSH_FUNCTIONS
7226 static int builtin_return(char **argv
)
7230 if (G
.flag_return_in_progress
!= -1) {
7231 bb_error_msg("%s: not in a function or sourced script", argv
[0]);
7232 return EXIT_FAILURE
; /* bash compat */
7235 G
.flag_return_in_progress
= 1;
7238 * out of range: wraps around at 256, does not error out
7239 * non-numeric param:
7240 * f() { false; return qwe; }; f; echo $?
7241 * bash: return: qwe: numeric argument required <== we do this
7242 * 255 <== we also do this
7244 rc
= parse_numeric_argv1(argv
, G
.last_exitcode
, 0);