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