"Das U-Boot" Source Tree
at master 13048 lines 367 kB view raw
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 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 12 * 13 * Credits: 14 * The parser routines proper are all original material, first 15 * written Dec 2000 and Jan 2001 by Larry Doolittle. The 16 * execution engine, the builtins, and much of the underlying 17 * support has been adapted from busybox-0.49pre's lash, which is 18 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 19 * written by Erik Andersen <andersen@codepoet.org>. That, in turn, 20 * is based in part on ladsh.c, by Michael K. Johnson and Erik W. 21 * Troan, which they placed in the public domain. I don't know 22 * how much of the Johnson/Troan code has survived the repeated 23 * rewrites. 24 * 25 * Other credits: 26 * o_addchr derived from similar w_addchar function in glibc-2.2. 27 * parse_redirect, redirect_opt_num, and big chunks of main 28 * and many builtins derived from contributions by Erik Andersen. 29 * Miscellaneous bugfixes from Matt Kraai. 30 * 31 * There are two big (and related) architecture differences between 32 * this parser and the lash parser. One is that this version is 33 * actually designed from the ground up to understand nearly all 34 * of the Bourne grammar. The second, consequential change is that 35 * the parser and input reader have been turned inside out. Now, 36 * the parser is in control, and asks for input as needed. The old 37 * way had the input reader in control, and it asked for parsing to 38 * take place as needed. The new way makes it much easier to properly 39 * handle the recursion implicit in the various substitutions, especially 40 * across continuation lines. 41 * 42 * TODOs: 43 * grep for "TODO" and fix (some of them are easy) 44 * make complex ${var%...} constructs support optional 45 * make here documents optional 46 * special variables (done: PWD, PPID, RANDOM) 47 * follow IFS rules more precisely, including update semantics 48 * tilde expansion 49 * aliases 50 * "command" missing features: 51 * command -p CMD: run CMD using default $PATH 52 * (can use this to override standalone shell as well?) 53 * command BLTIN: disables special-ness (e.g. errors do not abort) 54 * command -V CMD1 CMD2 CMD3 (multiple args) (not in standard) 55 * builtins mandated by standards we don't support: 56 * [un]alias, fc: 57 * fc -l[nr] [BEG] [END]: list range of commands in history 58 * fc [-e EDITOR] [BEG] [END]: edit/rerun range of commands 59 * fc -s [PAT=REP] [CMD]: rerun CMD, replacing PAT with REP 60 * 61 * Bash compat TODO: 62 * redirection of stdout+stderr: &> and >& 63 * reserved words: function select 64 * advanced test: [[ ]] 65 * process substitution: <(list) and >(list) 66 * let EXPR [EXPR...] 67 * Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION) 68 * If the last arg evaluates to 0, let returns 1; 0 otherwise. 69 * NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used) 70 * ((EXPR)) 71 * The EXPR is evaluated according to ARITHMETIC EVALUATION. 72 * This is exactly equivalent to let "EXPR". 73 * $[EXPR]: synonym for $((EXPR)) 74 * indirect expansion: ${!VAR} 75 * substring op on @: ${@:n:m} 76 * 77 * Won't do: 78 * Some builtins mandated by standards: 79 * newgrp [GRP]: not a builtin in bash but a suid binary 80 * which spawns a new shell with new group ID 81 * 82 * Status of [[ support: 83 * [[ args ]] are CMD_SINGLEWORD_NOGLOB: 84 * v='a b'; [[ $v = 'a b' ]]; echo 0:$? 85 * [[ /bin/n* ]]; echo 0:$? 86 * = is glob match operator, not equality operator: STR = GLOB 87 * == same as = 88 * =~ is regex match operator: STR =~ REGEX 89 * TODO: 90 * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc) 91 * in word = GLOB, quoting should be significant on char-by-char basis: a*cd"*" 92 */ 93//config:config HUSH 94//config: bool "hush (70 kb)" 95//config: default y 96//config: select SHELL_HUSH 97//config: help 98//config: hush is a small shell. It handles the normal flow control 99//config: constructs such as if/then/elif/else/fi, for/in/do/done, while loops, 100//config: case/esac. Redirections, here documents, $((arithmetic)) 101//config: and functions are supported. 102//config: 103//config: It will compile and work on no-mmu systems. 104//config: 105//config: It does not handle select, aliases, tilde expansion, 106//config: &>file and >&file redirection of stdout+stderr. 107//config: 108// This option is visible (has a description) to make it possible to select 109// a "scripted" applet (such as NOLOGIN) but avoid selecting any shells: 110//config:config SHELL_HUSH 111//config: bool "Internal shell for embedded script support" 112//config: default n 113//config: 114//config:# hush options 115//config:# It's only needed to get "nice" menuconfig indenting. 116//config:if SHELL_HUSH || HUSH || SH_IS_HUSH || BASH_IS_HUSH 117//config: 118//config:config HUSH_BASH_COMPAT 119//config: bool "bash-compatible extensions" 120//config: default y 121//config: depends on SHELL_HUSH 122//config: 123//config:config HUSH_BRACE_EXPANSION 124//config: bool "Brace expansion" 125//config: default y 126//config: depends on HUSH_BASH_COMPAT 127//config: help 128//config: Enable {abc,def} extension. 129//config: 130//config:config HUSH_BASH_SOURCE_CURDIR 131//config: bool "'source' and '.' builtins search current directory after $PATH" 132//config: default n # do not encourage non-standard behavior 133//config: depends on HUSH_BASH_COMPAT 134//config: help 135//config: This is not compliant with standards. Avoid if possible. 136//config: 137//config:config HUSH_LINENO_VAR 138//config: bool "$LINENO variable (bashism)" 139//config: default y 140//config: depends on SHELL_HUSH 141//config: 142//config:config HUSH_INTERACTIVE 143//config: bool "Interactive mode" 144//config: default y 145//config: depends on SHELL_HUSH 146//config: help 147//config: Enable interactive mode (prompt and command editing). 148//config: Without this, hush simply reads and executes commands 149//config: from stdin just like a shell script from a file. 150//config: No prompt, no PS1/PS2 magic shell variables. 151//config: 152//config:config HUSH_SAVEHISTORY 153//config: bool "Save command history to .hush_history" 154//config: default y 155//config: depends on HUSH_INTERACTIVE && FEATURE_EDITING_SAVEHISTORY 156//config: 157//config:config HUSH_JOB 158//config: bool "Job control" 159//config: default y 160//config: depends on HUSH_INTERACTIVE 161//config: help 162//config: Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current 163//config: command (not entire shell), fg/bg builtins work. Without this option, 164//config: "cmd &" still works by simply spawning a process and immediately 165//config: prompting for next command (or executing next command in a script), 166//config: but no separate process group is formed. 167//config: 168//config:config HUSH_TICK 169//config: bool "Support command substitution" 170//config: default y 171//config: depends on SHELL_HUSH 172//config: help 173//config: Enable `command` and $(command). 174//config: 175//config:config HUSH_IF 176//config: bool "Support if/then/elif/else/fi" 177//config: default y 178//config: depends on SHELL_HUSH 179//config: 180//config:config HUSH_LOOPS 181//config: bool "Support for, while and until loops" 182//config: default y 183//config: depends on SHELL_HUSH 184//config: 185//config:config HUSH_CASE 186//config: bool "Support case ... esac statement" 187//config: default y 188//config: depends on SHELL_HUSH 189//config: help 190//config: Enable case ... esac statement. +400 bytes. 191//config: 192//config:config HUSH_FUNCTIONS 193//config: bool "Support funcname() { commands; } syntax" 194//config: default y 195//config: depends on SHELL_HUSH 196//config: help 197//config: Enable support for shell functions. +800 bytes. 198//config: 199//config:config HUSH_LOCAL 200//config: bool "local builtin" 201//config: default y 202//config: depends on HUSH_FUNCTIONS 203//config: help 204//config: Enable support for local variables in functions. 205//config: 206//config:config HUSH_RANDOM_SUPPORT 207//config: bool "Pseudorandom generator and $RANDOM variable" 208//config: default y 209//config: depends on SHELL_HUSH 210//config: help 211//config: Enable pseudorandom generator and dynamic variable "$RANDOM". 212//config: Each read of "$RANDOM" will generate a new pseudorandom value. 213//config: 214//config:config HUSH_MODE_X 215//config: bool "Support 'hush -x' option and 'set -x' command" 216//config: default y 217//config: depends on SHELL_HUSH 218//config: help 219//config: This instructs hush to print commands before execution. 220//config: Adds ~300 bytes. 221//config: 222//config:config HUSH_ECHO 223//config: bool "echo builtin" 224//config: default y 225//config: depends on SHELL_HUSH 226//config: 227//config:config HUSH_PRINTF 228//config: bool "printf builtin" 229//config: default y 230//config: depends on SHELL_HUSH 231//config: 232//config:config HUSH_TEST 233//config: bool "test builtin" 234//config: default y 235//config: depends on SHELL_HUSH 236//config: 237//config:config HUSH_HELP 238//config: bool "help builtin" 239//config: default y 240//config: depends on SHELL_HUSH 241//config: 242//config:config HUSH_EXPORT 243//config: bool "export builtin" 244//config: default y 245//config: depends on SHELL_HUSH 246//config: 247//config:config HUSH_EXPORT_N 248//config: bool "Support 'export -n' option" 249//config: default y 250//config: depends on HUSH_EXPORT 251//config: help 252//config: export -n unexports variables. It is a bash extension. 253//config: 254//config:config HUSH_READONLY 255//config: bool "readonly builtin" 256//config: default y 257//config: depends on SHELL_HUSH 258//config: help 259//config: Enable support for read-only variables. 260//config: 261//config:config HUSH_KILL 262//config: bool "kill builtin (supports kill %jobspec)" 263//config: default y 264//config: depends on SHELL_HUSH 265//config: 266//config:config HUSH_WAIT 267//config: bool "wait builtin" 268//config: default y 269//config: depends on SHELL_HUSH 270//config: 271//config:config HUSH_COMMAND 272//config: bool "command builtin" 273//config: default y 274//config: depends on SHELL_HUSH 275//config: 276//config:config HUSH_TRAP 277//config: bool "trap builtin" 278//config: default y 279//config: depends on SHELL_HUSH 280//config: 281//config:config HUSH_TYPE 282//config: bool "type builtin" 283//config: default y 284//config: depends on SHELL_HUSH 285//config: 286//config:config HUSH_TIMES 287//config: bool "times builtin" 288//config: default y 289//config: depends on SHELL_HUSH 290//config: 291//config:config HUSH_READ 292//config: bool "read builtin" 293//config: default y 294//config: depends on SHELL_HUSH 295//config: 296//config:config HUSH_SET 297//config: bool "set builtin" 298//config: default y 299//config: depends on SHELL_HUSH 300//config: 301//config:config HUSH_UNSET 302//config: bool "unset builtin" 303//config: default y 304//config: depends on SHELL_HUSH 305//config: 306//config:config HUSH_ULIMIT 307//config: bool "ulimit builtin" 308//config: default y 309//config: depends on SHELL_HUSH 310//config: 311//config:config HUSH_UMASK 312//config: bool "umask builtin" 313//config: default y 314//config: depends on SHELL_HUSH 315//config: 316//config:config HUSH_GETOPTS 317//config: bool "getopts builtin" 318//config: default y 319//config: depends on SHELL_HUSH 320//config: 321//config:config HUSH_MEMLEAK 322//config: bool "memleak builtin (debugging)" 323//config: default n 324//config: depends on SHELL_HUSH 325//config: 326//config:endif # hush options 327 328//applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP)) 329// APPLET_ODDNAME:name main location suid_type help 330//applet:IF_SH_IS_HUSH( APPLET_ODDNAME(sh, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) 331//applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) 332 333//kbuild:lib-$(CONFIG_SHELL_HUSH) += hush.o match.o shell_common.o 334//kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o 335 336/* -i (interactive) is also accepted, 337 * but does nothing, therefore not shown in help. 338 * NOMMU-specific options are not meant to be used by users, 339 * therefore we don't show them either. 340 */ 341//usage:#define hush_trivial_usage 342//usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]" 343//usage:#define hush_full_usage "\n\n" 344//usage: "Unix shell interpreter" 345 346#ifndef __U_BOOT__ 347#if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ 348 || defined(__APPLE__) \ 349 ) 350# include <malloc.h> /* for malloc_trim */ 351#endif 352#include <glob.h> 353/* #include <dmalloc.h> */ 354#if ENABLE_HUSH_CASE 355# include <fnmatch.h> 356#endif 357#include <sys/times.h> 358#include <sys/utsname.h> /* for setting $HOSTNAME */ 359 360#include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */ 361#include "unicode.h" 362#include "shell_common.h" 363#include "math.h" 364#include "match.h" 365#if ENABLE_HUSH_RANDOM_SUPPORT 366# include "random.h" 367#else 368# define CLEAR_RANDOM_T(rnd) ((void)0) 369#endif 370#ifndef O_CLOEXEC 371# define O_CLOEXEC 0 372#endif 373#ifndef F_DUPFD_CLOEXEC 374# define F_DUPFD_CLOEXEC F_DUPFD 375#endif 376 377#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !ENABLE_SHELL_ASH 378# include "embedded_scripts.h" 379#else 380# define NUM_SCRIPTS 0 381#endif 382#endif /* !__U_BOOT__ */ 383 384/* So far, all bash compat is controlled by one config option */ 385/* Separate defines document which part of code implements what */ 386#define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT 387#define BASH_SUBSTR ENABLE_HUSH_BASH_COMPAT 388#define BASH_SOURCE ENABLE_HUSH_BASH_COMPAT 389#define BASH_DOLLAR_SQUOTE ENABLE_HUSH_BASH_COMPAT 390#define BASH_HOSTNAME_VAR ENABLE_HUSH_BASH_COMPAT 391#define BASH_EPOCH_VARS ENABLE_HUSH_BASH_COMPAT 392#define BASH_TEST2 (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST) 393#define BASH_READ_D ENABLE_HUSH_BASH_COMPAT 394 395/* Build knobs */ 396#define LEAK_HUNTING 0 397#define BUILD_AS_NOMMU 0 398/* Enable/disable sanity checks. Ok to enable in production, 399 * only adds a bit of bloat. Set to >1 to get non-production level verbosity. 400 * Keeping 1 for now even in released versions. 401 */ 402#define HUSH_DEBUG 1 403/* Slightly bigger (+200 bytes), but faster hush. 404 * So far it only enables a trick with counting SIGCHLDs and forks, 405 * which allows us to do fewer waitpid's. 406 * (we can detect a case where neither forks were done nor SIGCHLDs happened 407 * and therefore waitpid will return the same result as last time) 408 */ 409#define ENABLE_HUSH_FAST 0 410/* TODO: implement simplified code for users which do not need ${var%...} ops 411 * So far ${var%...} ops are always enabled: 412 */ 413#define ENABLE_HUSH_DOLLAR_OPS 1 414 415#if BUILD_AS_NOMMU 416# undef BB_MMU 417# undef USE_FOR_NOMMU 418# undef USE_FOR_MMU 419# define BB_MMU 0 420# define USE_FOR_NOMMU(...) __VA_ARGS__ 421# define USE_FOR_MMU(...) 422#endif 423 424#ifndef __U_BOOT__ 425#include "NUM_APPLETS.h" 426#if NUM_APPLETS == 1 427/* STANDALONE does not make sense, and won't compile */ 428# undef ENABLE_FEATURE_SH_STANDALONE 429# undef IF_FEATURE_SH_STANDALONE 430# undef IF_NOT_FEATURE_SH_STANDALONE 431# define ENABLE_FEATURE_SH_STANDALONE 0 432# define IF_FEATURE_SH_STANDALONE(...) 433# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ 434#endif 435#endif /* __U_BOOT__ */ 436 437#if !ENABLE_HUSH_INTERACTIVE 438# undef ENABLE_FEATURE_EDITING 439# define ENABLE_FEATURE_EDITING 0 440# undef ENABLE_FEATURE_EDITING_FANCY_PROMPT 441# define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0 442# undef ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 443# define ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 0 444#endif 445 446/* Do we support ANY keywords? */ 447#if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE 448# define HAS_KEYWORDS 1 449# define IF_HAS_KEYWORDS(...) __VA_ARGS__ 450# define IF_HAS_NO_KEYWORDS(...) 451#else 452# define HAS_KEYWORDS 0 453# define IF_HAS_KEYWORDS(...) 454# define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__ 455#endif 456 457/* If you comment out one of these below, it will be #defined later 458 * to perform debug printfs to stderr: */ 459#define debug_printf(...) do {} while (0) 460/* Finer-grained debug switches */ 461#define debug_printf_parse(...) do {} while (0) 462#define debug_printf_heredoc(...) do {} while (0) 463#define debug_print_tree(a, b) do {} while (0) 464#define debug_printf_exec(...) do {} while (0) 465#define debug_printf_env(...) do {} while (0) 466#define debug_printf_jobs(...) do {} while (0) 467#define debug_printf_expand(...) do {} while (0) 468#define debug_printf_varexp(...) do {} while (0) 469#define debug_printf_glob(...) do {} while (0) 470#define debug_printf_redir(...) do {} while (0) 471#define debug_printf_list(...) do {} while (0) 472#define debug_printf_subst(...) do {} while (0) 473#define debug_printf_prompt(...) do {} while (0) 474#define debug_printf_clean(...) do {} while (0) 475 476#define ERR_PTR ((void*)(long)1) 477 478#define JOB_STATUS_FORMAT "[%u] %-22s %.40s\n" 479 480#define _SPECIAL_VARS_STR "_*@$!?#-" 481#ifndef __U_BOOT__ 482#define SPECIAL_VARS_STR ("_*@$!?#-" + 1) 483#define NUMERIC_SPECVARS_STR ("_*@$!?#-" + 3) 484#else /* __U_BOOT__ */ 485#define SPECIAL_VARS_STR "*@$!?#-" 486#define NUMERIC_SPECVARS_STR "$!?#-" 487#endif /* __U_BOOT__ */ 488#if BASH_PATTERN_SUBST 489/* Support / and // replace ops */ 490/* Note that // is stored as \ in "encoded" string representation */ 491# define VAR_ENCODED_SUBST_OPS "\\/%#:-=+?" 492# define VAR_SUBST_OPS ("\\/%#:-=+?" + 1) 493# define MINUS_PLUS_EQUAL_QUESTION ("\\/%#:-=+?" + 5) 494#else 495# define VAR_ENCODED_SUBST_OPS "%#:-=+?" 496# define VAR_SUBST_OPS "%#:-=+?" 497# define MINUS_PLUS_EQUAL_QUESTION ("%#:-=+?" + 3) 498#endif 499 500#define SPECIAL_VAR_SYMBOL_STR "\3" 501#define SPECIAL_VAR_SYMBOL 3 502/* The "variable" with name "\1" emits string "\3". Testcase: "echo ^C" */ 503#define SPECIAL_VAR_QUOTED_SVS 1 504 505struct variable; 506 507static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER; 508 509/* This supports saving pointers malloced in vfork child, 510 * to be freed in the parent. 511 */ 512#if !BB_MMU 513typedef struct nommu_save_t { 514 struct variable *old_vars; 515 char **argv; 516 char **argv_from_re_execing; 517} nommu_save_t; 518#endif 519 520enum { 521 RES_NONE = 0, 522#if ENABLE_HUSH_IF 523 RES_IF , 524 RES_THEN , 525 RES_ELIF , 526 RES_ELSE , 527 RES_FI , 528#endif 529#if ENABLE_HUSH_LOOPS 530 RES_FOR , 531 RES_WHILE , 532 RES_UNTIL , 533 RES_DO , 534 RES_DONE , 535#endif 536#if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE 537 RES_IN , 538#endif 539#if ENABLE_HUSH_CASE 540 RES_CASE , 541 /* three pseudo-keywords support contrived "case" syntax: */ 542 RES_CASE_IN, /* "case ... IN", turns into RES_MATCH when IN is observed */ 543 RES_MATCH , /* "word)" */ 544 RES_CASE_BODY, /* "this command is inside CASE" */ 545 RES_ESAC , 546#endif 547 RES_XXXX , 548 RES_SNTX 549}; 550 551typedef struct o_string { 552 char *data; 553 int length; /* position where data is appended */ 554 int maxlen; 555 int o_expflags; 556 /* At least some part of the string was inside '' or "", 557 * possibly empty one: word"", wo''rd etc. */ 558 smallint has_quoted_part; 559 smallint has_empty_slot; 560 smallint ended_in_ifs; 561} o_string; 562enum { 563 EXP_FLAG_SINGLEWORD = 0x80, /* must be 0x80 */ 564 EXP_FLAG_GLOB = 0x2, 565 /* Protect newly added chars against globbing 566 * by prepending \ to *, ?, [, \ */ 567 EXP_FLAG_ESC_GLOB_CHARS = 0x1, 568}; 569/* Used for initialization: o_string foo = NULL_O_STRING; */ 570#define NULL_O_STRING { NULL } 571 572#ifndef debug_printf_parse 573static const char *const assignment_flag[] ALIGN_PTR = { 574 "MAYBE_ASSIGNMENT", 575 "DEFINITELY_ASSIGNMENT", 576 "NOT_ASSIGNMENT", 577 "WORD_IS_KEYWORD", 578}; 579#endif 580 581/* We almost can use standard FILE api, but we need an ability to move 582 * its fd when redirects coincide with it. No api exists for that 583 * (RFE for it at https://sourceware.org/bugzilla/show_bug.cgi?id=21902). 584 * HFILE is our internal alternative. Only supports reading. 585 * Since we now can, we incorporate linked list of all opened HFILEs 586 * into the struct (used to be a separate mini-list). 587 */ 588typedef struct HFILE { 589 char *cur; 590 char *end; 591 struct HFILE *next_hfile; 592 int fd; 593 char buf[1024]; 594} HFILE; 595 596typedef struct in_str { 597 const char *p; 598 int peek_buf[2]; 599 int last_char; 600 HFILE *file; 601} in_str; 602 603#ifndef __U_BOOT__ 604/* The descrip member of this structure is only used to make 605 * debugging output pretty */ 606static const struct { 607 int32_t mode; 608 signed char default_fd; 609 char descrip[3]; 610} redir_table[] ALIGN4 = { 611 { O_RDONLY, 0, "<" }, 612 { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" }, 613 { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" }, 614 { O_CREAT|O_RDWR, 1, "<>" }, 615 { O_RDONLY, 0, "<<" }, 616/* Should not be needed. Bogus default_fd helps in debugging */ 617/* { O_RDONLY, 77, "<<" }, */ 618}; 619 620struct redir_struct { 621 struct redir_struct *next; 622 char *rd_filename; /* filename */ 623 int rd_fd; /* fd to redirect */ 624 /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */ 625 int rd_dup; 626 smallint rd_type; /* (enum redir_type) */ 627 /* note: for heredocs, rd_filename contains heredoc delimiter, 628 * and subsequently heredoc itself; and rd_dup is a bitmask: 629 * bit 0: do we need to trim leading tabs? 630 * bit 1: is heredoc quoted (<<'delim' syntax) ? 631 */ 632}; 633typedef enum redir_type { 634 REDIRECT_INPUT = 0, 635 REDIRECT_OVERWRITE = 1, 636 REDIRECT_APPEND = 2, 637 REDIRECT_IO = 3, 638 REDIRECT_HEREDOC = 4, 639 REDIRECT_HEREDOC2 = 5, /* REDIRECT_HEREDOC after heredoc is loaded */ 640 641 REDIRFD_CLOSE = -3, 642 REDIRFD_SYNTAX_ERR = -2, 643 REDIRFD_TO_FILE = -1, 644 /* otherwise, rd_fd is redirected to rd_dup */ 645 646 HEREDOC_SKIPTABS = 1, 647 HEREDOC_QUOTED = 2, 648} redir_type; 649 650#endif /* !__U_BOOT__ */ 651 652struct command { 653#ifndef __U_BOOT__ 654 pid_t pid; /* 0 if exited */ 655#endif /* !__U_BOOT__ */ 656 unsigned assignment_cnt; /* how many argv[i] are assignments? */ 657#if ENABLE_HUSH_LINENO_VAR 658 unsigned lineno; 659#endif 660 smallint cmd_type; /* CMD_xxx */ 661#define CMD_NORMAL 0 662#define CMD_SUBSHELL 1 663#if BASH_TEST2 664/* used for "[[ EXPR ]]" */ 665# define CMD_TEST2_SINGLEWORD_NOGLOB 2 666#endif 667#if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY 668/* used to prevent word splitting and globbing in "export v=t*" */ 669# define CMD_SINGLEWORD_NOGLOB 3 670#endif 671#if ENABLE_HUSH_FUNCTIONS 672# define CMD_FUNCDEF 4 673#endif 674 675 smalluint cmd_exitcode; 676 /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */ 677 struct pipe *group; 678#if !BB_MMU 679 char *group_as_string; 680#endif 681#if ENABLE_HUSH_FUNCTIONS 682 struct function *child_func; 683/* This field is used to prevent a bug here: 684 * while...do f1() {a;}; f1; f1() {b;}; f1; done 685 * When we execute "f1() {a;}" cmd, we create new function and clear 686 * cmd->group, cmd->group_as_string, cmd->argv[0]. 687 * When we execute "f1() {b;}", we notice that f1 exists, 688 * and that its "parent cmd" struct is still "alive", 689 * we put those fields back into cmd->xxx 690 * (struct function has ->parent_cmd ptr to facilitate that). 691 * When we loop back, we can execute "f1() {a;}" again and set f1 correctly. 692 * Without this trick, loop would execute a;b;b;b;... 693 * instead of correct sequence a;b;a;b;... 694 * When command is freed, it severs the link 695 * (sets ->child_func->parent_cmd to NULL). 696 */ 697#endif 698#ifdef __U_BOOT__ 699 int argc; /* number of program arguments */ 700#endif 701 char **argv; /* command name and arguments */ 702/* argv vector may contain variable references (^Cvar^C, ^C0^C etc) 703 * and on execution these are substituted with their values. 704 * Substitution can make _several_ words out of one argv[n]! 705 * Example: argv[0]=='.^C*^C.' here: echo .$*. 706 * References of the form ^C`cmd arg^C are `cmd arg` substitutions. 707 */ 708#ifndef __U_BOOT__ 709 struct redir_struct *redirects; /* I/O redirections */ 710#endif /* !__U_BOOT__ */ 711}; 712/* Is there anything in this command at all? */ 713#ifndef __U_BOOT__ 714#define IS_NULL_CMD(cmd) \ 715 (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects) 716 717#else /* __U_BOOT__ */ 718#define IS_NULL_CMD(cmd) \ 719 (!(cmd)->group && !(cmd)->argv) 720#endif /* __U_BOOT__ */ 721struct pipe { 722 struct pipe *next; 723 int num_cmds; /* total number of commands in pipe */ 724#ifndef __U_BOOT__ 725 int alive_cmds; /* number of commands running (not exited) */ 726 int stopped_cmds; /* number of commands alive, but stopped */ 727#if ENABLE_HUSH_JOB 728 unsigned jobid; /* job number */ 729 pid_t pgrp; /* process group ID for the job */ 730 char *cmdtext; /* name of job */ 731#endif 732#endif /* !__U_BOOT__ */ 733 struct command *cmds; /* array of commands in pipe */ 734 smallint followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */ 735 IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */ 736 IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */ 737}; 738typedef enum pipe_style { 739 PIPE_SEQ = 0, 740 PIPE_AND = 1, 741 PIPE_OR = 2, 742 PIPE_BG = 3, 743} pipe_style; 744/* Is there anything in this pipe at all? */ 745#define IS_NULL_PIPE(pi) \ 746 ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE)) 747 748/* This holds pointers to the various results of parsing */ 749struct parse_context { 750 /* linked list of pipes */ 751 struct pipe *list_head; 752 /* last pipe (being constructed right now) */ 753 struct pipe *pipe; 754 /* last command in pipe (being constructed right now) */ 755 struct command *command; 756#ifndef __U_BOOT__ 757 /* last redirect in command->redirects list */ 758 struct redir_struct *pending_redirect; 759#endif /* !__U_BOOT__ */ 760 o_string word; 761#if !BB_MMU 762 o_string as_string; 763#endif 764 smallint is_assignment; /* 0:maybe, 1:yes, 2:no, 3:keyword */ 765#if HAS_KEYWORDS 766 smallint ctx_res_w; 767 smallint ctx_inverted; /* "! cmd | cmd" */ 768#if ENABLE_HUSH_CASE 769 smallint ctx_dsemicolon; /* ";;" seen */ 770#endif 771 /* bitmask of FLAG_xxx, for figuring out valid reserved words */ 772 int old_flag; 773 /* group we are enclosed in: 774 * example: "if pipe1; pipe2; then pipe3; fi" 775 * when we see "if" or "then", we malloc and copy current context, 776 * and make ->stack point to it. then we parse pipeN. 777 * when closing "then" / fi" / whatever is found, 778 * we move list_head into ->stack->command->group, 779 * copy ->stack into current context, and delete ->stack. 780 * (parsing of { list } and ( list ) doesn't use this method) 781 */ 782 struct parse_context *stack; 783#endif 784}; 785enum { 786 MAYBE_ASSIGNMENT = 0, 787 DEFINITELY_ASSIGNMENT = 1, 788 NOT_ASSIGNMENT = 2, 789 /* Not an assignment, but next word may be: "if v=xyz cmd;" */ 790 WORD_IS_KEYWORD = 3, 791}; 792 793#ifndef __U_BOOT__ 794/* On program start, environ points to initial environment. 795 * putenv adds new pointers into it, unsetenv removes them. 796 * Neither of these (de)allocates the strings. 797 * setenv allocates new strings in malloc space and does putenv, 798 * and thus setenv is unusable (leaky) for shell's purposes */ 799#define setenv(...) setenv_is_leaky_dont_use() 800#endif /* !__U_BOOT__ */ 801struct variable { 802 struct variable *next; 803 char *varstr; /* points to "name=" portion */ 804 int max_len; /* if > 0, name is part of initial env; else name is malloced */ 805#ifndef __U_BOOT__ 806 uint16_t var_nest_level; 807 smallint flg_export; /* putenv should be done on this var */ 808 smallint flg_read_only; 809#endif /* !__U_BOOT__ */ 810}; 811 812enum { 813 BC_BREAK = 1, 814 BC_CONTINUE = 2, 815}; 816 817#if ENABLE_HUSH_FUNCTIONS 818struct function { 819 struct function *next; 820 char *name; 821 struct command *parent_cmd; 822 struct pipe *body; 823# if !BB_MMU 824 char *body_as_string; 825# endif 826}; 827#endif 828 829/* set -/+o OPT support. (TODO: make it optional) 830 * bash supports the following opts: 831 * allexport off 832 * braceexpand on 833 * emacs on 834 * errexit off 835 * errtrace off 836 * functrace off 837 * hashall on 838 * histexpand off 839 * history on 840 * ignoreeof off 841 * interactive-comments on 842 * keyword off 843 * monitor on 844 * noclobber off 845 * noexec off 846 * noglob off 847 * nolog off 848 * notify off 849 * nounset off 850 * onecmd off 851 * physical off 852 * pipefail off 853 * posix off 854 * privileged off 855 * verbose off 856 * vi off 857 * xtrace off 858 */ 859static const char o_opt_strings[] ALIGN1 = 860 "pipefail\0" 861 "noexec\0" 862 "errexit\0" 863#if ENABLE_HUSH_MODE_X 864 "xtrace\0" 865#endif 866 ; 867enum { 868 OPT_O_PIPEFAIL, 869 OPT_O_NOEXEC, 870 OPT_O_ERREXIT, 871#if ENABLE_HUSH_MODE_X 872 OPT_O_XTRACE, 873#endif 874 NUM_OPT_O 875}; 876 877/* "Globals" within this file */ 878/* Sorted roughly by size (smaller offsets == smaller code) */ 879struct globals { 880#ifndef __U_BOOT__ 881 /* interactive_fd != 0 means we are an interactive shell. 882 * If we are, then saved_tty_pgrp can also be != 0, meaning 883 * that controlling tty is available. With saved_tty_pgrp == 0, 884 * job control still works, but terminal signals 885 * (^C, ^Z, ^Y, ^\) won't work at all, and background 886 * process groups can only be created with "cmd &". 887 * With saved_tty_pgrp != 0, hush will use tcsetpgrp() 888 * to give tty to the foreground process group, 889 * and will take it back when the group is stopped (^Z) 890 * or killed (^C). 891 */ 892#if ENABLE_HUSH_INTERACTIVE 893 /* 'interactive_fd' is a fd# open to ctty, if we have one 894 * _AND_ if we decided to act interactively */ 895 int interactive_fd; 896 IF_NOT_FEATURE_EDITING_FANCY_PROMPT(char *PS1;) 897# define G_interactive_fd (G.interactive_fd) 898#else 899# define G_interactive_fd 0 900#endif 901#else /* __U_BOOT__ */ 902# define G_interactive_fd 0 903#endif /* __U_BOOT__ */ 904#ifndef __U_BOOT__ 905#if ENABLE_FEATURE_EDITING 906 line_input_t *line_input_state; 907#endif 908 pid_t root_pid; 909 pid_t root_ppid; 910 pid_t last_bg_pid; 911#if ENABLE_HUSH_RANDOM_SUPPORT 912 random_t random_gen; 913#endif 914#if ENABLE_HUSH_JOB 915 int run_list_level; 916 unsigned last_jobid; 917 pid_t saved_tty_pgrp; 918 struct pipe *job_list; 919# define G_saved_tty_pgrp (G.saved_tty_pgrp) 920#else 921# define G_saved_tty_pgrp 0 922#endif 923#endif /* !__U_BOOT__ */ 924 /* How deeply are we in context where "set -e" is ignored */ 925 int errexit_depth; 926#ifndef __U_BOOT__ 927 /* "set -e" rules (do we follow them correctly?): 928 * Exit if pipe, list, or compound command exits with a non-zero status. 929 * Shell does not exit if failed command is part of condition in 930 * if/while, part of && or || list except the last command, any command 931 * in a pipe but the last, or if the command's return value is being 932 * inverted with !. If a compound command other than a subshell returns a 933 * non-zero status because a command failed while -e was being ignored, the 934 * shell does not exit. A trap on ERR, if set, is executed before the shell 935 * exits [ERR is a bashism]. 936 * 937 * If a compound command or function executes in a context where -e is 938 * ignored, none of the commands executed within are affected by the -e 939 * setting. If a compound command or function sets -e while executing in a 940 * context where -e is ignored, that setting does not have any effect until 941 * the compound command or the command containing the function call completes. 942 */ 943 944 char o_opt[NUM_OPT_O]; 945#if ENABLE_HUSH_MODE_X 946# define G_x_mode (G.o_opt[OPT_O_XTRACE]) 947#else 948# define G_x_mode 0 949#endif 950 char opt_s; 951 char opt_c; 952#endif /* !__U_BOOT__ */ 953#if ENABLE_HUSH_INTERACTIVE 954 smallint promptmode; /* 0: PS1, 1: PS2 */ 955#endif 956 /* set by signal handler if SIGINT is received _and_ its trap is not set */ 957 smallint flag_SIGINT; 958#ifndef __U_BOOT__ 959#if ENABLE_HUSH_LOOPS 960 smallint flag_break_continue; 961#endif 962#endif /* !__U_BOOT__ */ 963#if ENABLE_HUSH_FUNCTIONS 964 /* 0: outside of a function (or sourced file) 965 * -1: inside of a function, ok to use return builtin 966 * 1: return is invoked, skip all till end of func 967 */ 968 smallint flag_return_in_progress; 969# define G_flag_return_in_progress (G.flag_return_in_progress) 970#else 971# define G_flag_return_in_progress 0 972#endif 973 smallint exiting; /* used to prevent EXIT trap recursion */ 974 /* These support $? */ 975 smalluint last_exitcode; 976 smalluint expand_exitcode; 977 smalluint last_bg_pid_exitcode; 978#ifndef __U_BOOT__ 979#if ENABLE_HUSH_SET 980 /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ 981 smalluint global_args_malloced; 982# define G_global_args_malloced (G.global_args_malloced) 983#else 984# define G_global_args_malloced 0 985#endif 986#if ENABLE_HUSH_BASH_COMPAT 987 int dead_job_exitcode; /* for "wait -n" */ 988#endif 989#endif /* !__U_BOOT__ */ 990 /* how many non-NULL argv's we have. NB: $# + 1 */ 991 int global_argc; 992 char **global_argv; 993#if !BB_MMU 994 char *argv0_for_re_execing; 995#endif 996#if ENABLE_HUSH_LOOPS 997#ifndef __U_BOOT__ 998 unsigned depth_break_continue; 999#endif /* !__U_BOOT__ */ 1000 unsigned depth_of_loop; 1001#endif 1002#ifndef __U_BOOT__ 1003#if ENABLE_HUSH_GETOPTS 1004 unsigned getopt_count; 1005#endif 1006#endif /* !__U_BOOT__ */ 1007 const char *ifs; 1008#ifdef __U_BOOT__ 1009 int flag_repeat; 1010 int do_repeat; 1011 int run_command_flags; 1012#endif /* __U_BOOT__ */ 1013 char *ifs_whitespace; /* = G.ifs or malloced */ 1014#ifndef __U_BOOT__ 1015 const char *cwd; 1016#endif /* !__U_BOOT__ */ 1017 struct variable *top_var; 1018 char **expanded_assignments; 1019 struct variable **shadowed_vars_pp; 1020 unsigned var_nest_level; 1021#ifndef __U_BOOT__ 1022#if ENABLE_HUSH_FUNCTIONS 1023# if ENABLE_HUSH_LOCAL 1024 unsigned func_nest_level; /* solely to prevent "local v" in non-functions */ 1025# endif 1026 struct function *top_func; 1027#endif 1028 /* Signal and trap handling */ 1029#if ENABLE_HUSH_FAST 1030 unsigned count_SIGCHLD; 1031 unsigned handled_SIGCHLD; 1032 smallint we_have_children; 1033#endif 1034#if ENABLE_HUSH_LINENO_VAR 1035 unsigned parse_lineno; 1036 unsigned execute_lineno; 1037#endif 1038 HFILE *HFILE_list; 1039 HFILE *HFILE_stdin; 1040 /* Which signals have non-DFL handler (even with no traps set)? 1041 * Set at the start to: 1042 * (SIGQUIT + maybe SPECIAL_INTERACTIVE_SIGS + maybe SPECIAL_JOBSTOP_SIGS) 1043 * SPECIAL_INTERACTIVE_SIGS are cleared after fork. 1044 * The rest is cleared right before execv syscalls. 1045 * Other than these two times, never modified. 1046 */ 1047 unsigned special_sig_mask; 1048#if ENABLE_HUSH_JOB 1049 unsigned fatal_sig_mask; 1050# define G_fatal_sig_mask (G.fatal_sig_mask) 1051#else 1052# define G_fatal_sig_mask 0 1053#endif 1054#if ENABLE_HUSH_TRAP 1055 int pre_trap_exitcode; 1056# if ENABLE_HUSH_FUNCTIONS 1057 int return_exitcode; 1058# endif 1059 char **traps; /* char *traps[NSIG] */ 1060# define G_traps G.traps 1061#else 1062# define G_traps ((char**)NULL) 1063#endif 1064 sigset_t pending_set; 1065#if ENABLE_HUSH_MEMLEAK 1066 unsigned long memleak_value; 1067#endif 1068#if ENABLE_HUSH_MODE_X 1069 unsigned x_mode_depth; 1070 /* "set -x" output should not be redirectable with subsequent 2>FILE. 1071 * We dup fd#2 to x_mode_fd when "set -x" is executed, and use it 1072 * for all subsequent output. 1073 */ 1074 int x_mode_fd; 1075 o_string x_mode_buf; 1076#endif 1077#endif /* !__U_BOOT__ */ 1078#if HUSH_DEBUG >= 2 1079 int debug_indent; 1080#endif 1081#ifndef __U_BOOT__ 1082 struct sigaction sa; 1083 char optstring_buf[sizeof("eixcs")]; 1084#if BASH_EPOCH_VARS 1085 char epoch_buf[sizeof("%llu.nnnnnn") + sizeof(long long)*3]; 1086#endif 1087#if ENABLE_FEATURE_EDITING 1088 char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN]; 1089#endif 1090#endif /* !__U_BOOT__ */ 1091}; 1092#ifdef __U_BOOT__ 1093struct globals *ptr_to_globals; 1094#endif /* __U_BOOT__ */ 1095#define G (*ptr_to_globals) 1096/* Not #defining name to G.name - this quickly gets unwieldy 1097 * (too many defines). Also, I actually prefer to see when a variable 1098 * is global, thus "G." prefix is a useful hint */ 1099#ifdef __U_BOOT__ 1100#define SET_PTR_TO_GLOBALS(x) do { \ 1101 (*(struct globals**)&ptr_to_globals) = (void*)(x); \ 1102 barrier(); \ 1103} while (0) 1104#define INIT_G() do { \ 1105 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 1106 G.promptmode = 1; \ 1107} while (0) 1108#else /* !__U_BOOT__ */ 1109#define INIT_G() do { \ 1110 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 1111 /* memset(&G.sa, 0, sizeof(G.sa)); */ \ 1112 sigfillset(&G.sa.sa_mask); \ 1113 G.sa.sa_flags = SA_RESTART; \ 1114} while (0) 1115#endif /* !__U_BOOT__ */ 1116 1117#ifndef __U_BOOT__ 1118/* Function prototypes for builtins */ 1119static int builtin_cd(char **argv) FAST_FUNC; 1120#if ENABLE_HUSH_ECHO 1121static int builtin_echo(char **argv) FAST_FUNC; 1122#endif 1123static int builtin_eval(char **argv) FAST_FUNC; 1124static int builtin_exec(char **argv) FAST_FUNC; 1125static int builtin_exit(char **argv) FAST_FUNC; 1126#if ENABLE_HUSH_EXPORT 1127static int builtin_export(char **argv) FAST_FUNC; 1128#endif 1129#if ENABLE_HUSH_READONLY 1130static int builtin_readonly(char **argv) FAST_FUNC; 1131#endif 1132static int builtin_false(char **argv) FAST_FUNC; 1133#if ENABLE_HUSH_JOB 1134static int builtin_fg_bg(char **argv) FAST_FUNC; 1135static int builtin_jobs(char **argv) FAST_FUNC; 1136#endif 1137#if ENABLE_HUSH_GETOPTS 1138static int builtin_getopts(char **argv) FAST_FUNC; 1139#endif 1140#if ENABLE_HUSH_HELP 1141static int builtin_help(char **argv) FAST_FUNC; 1142#endif 1143#if MAX_HISTORY && ENABLE_FEATURE_EDITING 1144static int builtin_history(char **argv) FAST_FUNC; 1145#endif 1146#if ENABLE_HUSH_LOCAL 1147static int builtin_local(char **argv) FAST_FUNC; 1148#endif 1149#if ENABLE_HUSH_MEMLEAK 1150static int builtin_memleak(char **argv) FAST_FUNC; 1151#endif 1152#if ENABLE_HUSH_PRINTF 1153static int builtin_printf(char **argv) FAST_FUNC; 1154#endif 1155static int builtin_pwd(char **argv) FAST_FUNC; 1156#if ENABLE_HUSH_READ 1157static int builtin_read(char **argv) FAST_FUNC; 1158#endif 1159#if ENABLE_HUSH_SET 1160static int builtin_set(char **argv) FAST_FUNC; 1161#endif 1162static int builtin_shift(char **argv) FAST_FUNC; 1163static int builtin_source(char **argv) FAST_FUNC; 1164#if ENABLE_HUSH_TEST || BASH_TEST2 1165static int builtin_test(char **argv) FAST_FUNC; 1166#endif 1167#if ENABLE_HUSH_TRAP 1168static int builtin_trap(char **argv) FAST_FUNC; 1169#endif 1170#if ENABLE_HUSH_TYPE 1171static int builtin_type(char **argv) FAST_FUNC; 1172#endif 1173#if ENABLE_HUSH_TIMES 1174static int builtin_times(char **argv) FAST_FUNC; 1175#endif 1176static int builtin_true(char **argv) FAST_FUNC; 1177#if ENABLE_HUSH_UMASK 1178static int builtin_umask(char **argv) FAST_FUNC; 1179#endif 1180#if ENABLE_HUSH_UNSET 1181static int builtin_unset(char **argv) FAST_FUNC; 1182#endif 1183#if ENABLE_HUSH_KILL 1184static int builtin_kill(char **argv) FAST_FUNC; 1185#endif 1186#if ENABLE_HUSH_WAIT 1187static int builtin_wait(char **argv) FAST_FUNC; 1188#endif 1189#if ENABLE_HUSH_LOOPS 1190static int builtin_break(char **argv) FAST_FUNC; 1191static int builtin_continue(char **argv) FAST_FUNC; 1192#endif 1193#if ENABLE_HUSH_FUNCTIONS 1194static int builtin_return(char **argv) FAST_FUNC; 1195#endif 1196 1197/* Table of built-in functions. They can be forked or not, depending on 1198 * context: within pipes, they fork. As simple commands, they do not. 1199 * When used in non-forking context, they can change global variables 1200 * in the parent shell process. If forked, of course they cannot. 1201 * For example, 'unset foo | whatever' will parse and run, but foo will 1202 * still be set at the end. */ 1203struct built_in_command { 1204 const char *b_cmd; 1205 int (*b_function)(char **argv) FAST_FUNC; 1206#if ENABLE_HUSH_HELP 1207 const char *b_descr; 1208# define BLTIN(cmd, func, help) { cmd, func, help } 1209#else 1210# define BLTIN(cmd, func, help) { cmd, func } 1211#endif 1212}; 1213 1214static const struct built_in_command bltins1[] ALIGN_PTR = { 1215 BLTIN("." , builtin_source , "Run commands in file"), 1216 BLTIN(":" , builtin_true , NULL), 1217#if ENABLE_HUSH_JOB 1218 BLTIN("bg" , builtin_fg_bg , "Resume job in background"), 1219#endif 1220#if ENABLE_HUSH_LOOPS 1221 BLTIN("break" , builtin_break , "Exit loop"), 1222#endif 1223 BLTIN("cd" , builtin_cd , "Change directory"), 1224#if ENABLE_HUSH_LOOPS 1225 BLTIN("continue" , builtin_continue, "Start new loop iteration"), 1226#endif 1227 BLTIN("eval" , builtin_eval , "Construct and run shell command"), 1228 BLTIN("exec" , builtin_exec , "Execute command, don't return to shell"), 1229 BLTIN("exit" , builtin_exit , NULL), 1230#if ENABLE_HUSH_EXPORT 1231 BLTIN("export" , builtin_export , "Set environment variables"), 1232#endif 1233 BLTIN("false" , builtin_false , NULL), 1234#if ENABLE_HUSH_JOB 1235 BLTIN("fg" , builtin_fg_bg , "Bring job to foreground"), 1236#endif 1237#if ENABLE_HUSH_GETOPTS 1238 BLTIN("getopts" , builtin_getopts , NULL), 1239#endif 1240#if ENABLE_HUSH_HELP 1241 BLTIN("help" , builtin_help , NULL), 1242#endif 1243#if MAX_HISTORY && ENABLE_FEATURE_EDITING 1244 BLTIN("history" , builtin_history , "Show history"), 1245#endif 1246#if ENABLE_HUSH_JOB 1247 BLTIN("jobs" , builtin_jobs , "List jobs"), 1248#endif 1249#if ENABLE_HUSH_KILL 1250 BLTIN("kill" , builtin_kill , "Send signals to processes"), 1251#endif 1252#if ENABLE_HUSH_LOCAL 1253 BLTIN("local" , builtin_local , "Set local variables"), 1254#endif 1255#if ENABLE_HUSH_MEMLEAK 1256 BLTIN("memleak" , builtin_memleak , NULL), 1257#endif 1258#if ENABLE_HUSH_READ 1259 BLTIN("read" , builtin_read , "Input into variable"), 1260#endif 1261#if ENABLE_HUSH_READONLY 1262 BLTIN("readonly" , builtin_readonly, "Make variables read-only"), 1263#endif 1264#if ENABLE_HUSH_FUNCTIONS 1265 BLTIN("return" , builtin_return , "Return from function"), 1266#endif 1267#if ENABLE_HUSH_SET 1268 BLTIN("set" , builtin_set , "Set positional parameters"), 1269#endif 1270 BLTIN("shift" , builtin_shift , "Shift positional parameters"), 1271#if BASH_SOURCE 1272 BLTIN("source" , builtin_source , NULL), 1273#endif 1274#if ENABLE_HUSH_TIMES 1275 BLTIN("times" , builtin_times , NULL), 1276#endif 1277#if ENABLE_HUSH_TRAP 1278 BLTIN("trap" , builtin_trap , "Trap signals"), 1279#endif 1280 BLTIN("true" , builtin_true , NULL), 1281#if ENABLE_HUSH_TYPE 1282 BLTIN("type" , builtin_type , "Show command type"), 1283#endif 1284#if ENABLE_HUSH_ULIMIT 1285 BLTIN("ulimit" , shell_builtin_ulimit, "Control resource limits"), 1286#endif 1287#if ENABLE_HUSH_UMASK 1288 BLTIN("umask" , builtin_umask , "Set file creation mask"), 1289#endif 1290#if ENABLE_HUSH_UNSET 1291 BLTIN("unset" , builtin_unset , "Unset variables"), 1292#endif 1293#if ENABLE_HUSH_WAIT 1294 BLTIN("wait" , builtin_wait , "Wait for process to finish"), 1295#endif 1296}; 1297/* These builtins won't be used if we are on NOMMU and need to re-exec 1298 * (it's cheaper to run an external program in this case): 1299 */ 1300static const struct built_in_command bltins2[] ALIGN_PTR = { 1301#if ENABLE_HUSH_TEST 1302 BLTIN("[" , builtin_test , NULL), 1303#endif 1304#if BASH_TEST2 1305 BLTIN("[[" , builtin_test , NULL), 1306#endif 1307#if ENABLE_HUSH_ECHO 1308 BLTIN("echo" , builtin_echo , NULL), 1309#endif 1310#if ENABLE_HUSH_PRINTF 1311 BLTIN("printf" , builtin_printf , NULL), 1312#endif 1313 BLTIN("pwd" , builtin_pwd , NULL), 1314#if ENABLE_HUSH_TEST 1315 BLTIN("test" , builtin_test , NULL), 1316#endif 1317}; 1318 1319#endif /* !__U_BOOT__ */ 1320 1321/* Debug printouts. 1322 */ 1323#if HUSH_DEBUG >= 2 1324/* prevent disasters with G.debug_indent < 0 */ 1325# define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "") 1326# define debug_enter() (G.debug_indent++) 1327# define debug_leave() (G.debug_indent--) 1328#else 1329# define indent() ((void)0) 1330# define debug_enter() ((void)0) 1331# define debug_leave() ((void)0) 1332#endif 1333 1334#ifndef debug_printf 1335# define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__)) 1336#endif 1337 1338#ifndef debug_printf_parse 1339# define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__)) 1340#endif 1341 1342#ifndef debug_printf_heredoc 1343# define debug_printf_heredoc(...) (indent(), fdprintf(2, __VA_ARGS__)) 1344#endif 1345 1346#ifndef debug_printf_exec 1347#define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__)) 1348#endif 1349 1350#ifndef debug_printf_env 1351# define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__)) 1352#endif 1353 1354#ifndef debug_printf_jobs 1355# define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__)) 1356# define DEBUG_JOBS 1 1357#else 1358# define DEBUG_JOBS 0 1359#endif 1360 1361#ifndef debug_printf_expand 1362# define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__)) 1363# define DEBUG_EXPAND 1 1364#else 1365# define DEBUG_EXPAND 0 1366#endif 1367 1368#ifndef debug_printf_varexp 1369# define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__)) 1370#endif 1371 1372#ifndef debug_printf_glob 1373# define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__)) 1374# define DEBUG_GLOB 1 1375#else 1376# define DEBUG_GLOB 0 1377#endif 1378 1379#ifndef debug_printf_redir 1380# define debug_printf_redir(...) (indent(), fdprintf(2, __VA_ARGS__)) 1381#endif 1382 1383#ifndef debug_printf_list 1384# define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__)) 1385#endif 1386 1387#ifndef debug_printf_subst 1388# define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__)) 1389#endif 1390 1391#ifndef debug_printf_prompt 1392# define debug_printf_prompt(...) (indent(), fdprintf(2, __VA_ARGS__)) 1393#endif 1394 1395#ifndef debug_printf_clean 1396# define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__)) 1397# define DEBUG_CLEAN 1 1398#else 1399# define DEBUG_CLEAN 0 1400#endif 1401 1402#if DEBUG_EXPAND 1403static void debug_print_strings(const char *prefix, char **vv) 1404{ 1405 indent(); 1406 fdprintf(2, "%s:\n", prefix); 1407 while (*vv) 1408 fdprintf(2, " '%s'\n", *vv++); 1409} 1410#else 1411# define debug_print_strings(prefix, vv) ((void)0) 1412#endif 1413 1414/* Leak hunting. Use hush_leaktool.sh for post-processing. 1415 */ 1416#if LEAK_HUNTING 1417static void *xxmalloc(int lineno, size_t size) 1418{ 1419 void *ptr = xmalloc((size + 0xff) & ~0xff); 1420 fdprintf(2, "line %d: malloc %p\n", lineno, ptr); 1421 return ptr; 1422} 1423static void *xxrealloc(int lineno, void *ptr, size_t size) 1424{ 1425 ptr = xrealloc(ptr, (size + 0xff) & ~0xff); 1426 fdprintf(2, "line %d: realloc %p\n", lineno, ptr); 1427 return ptr; 1428} 1429static char *xxstrdup(int lineno, const char *str) 1430{ 1431 char *ptr = xstrdup(str); 1432 fdprintf(2, "line %d: strdup %p\n", lineno, ptr); 1433 return ptr; 1434} 1435static void xxfree(void *ptr) 1436{ 1437 fdprintf(2, "free %p\n", ptr); 1438 free(ptr); 1439} 1440# define xmalloc(s) xxmalloc(__LINE__, s) 1441# define xrealloc(p, s) xxrealloc(__LINE__, p, s) 1442# define xstrdup(s) xxstrdup(__LINE__, s) 1443# define free(p) xxfree(p) 1444#endif 1445 1446/* Syntax and runtime errors. They always abort scripts. 1447 * In interactive use they usually discard unparsed and/or unexecuted commands 1448 * and return to the prompt. 1449 * HUSH_DEBUG >= 2 prints line number in this file where it was detected. 1450 */ 1451#if HUSH_DEBUG < 2 1452# define msg_and_die_if_script(lineno, ...) msg_and_die_if_script(__VA_ARGS__) 1453# define syntax_error(lineno, msg) syntax_error(msg) 1454# define syntax_error_at(lineno, msg) syntax_error_at(msg) 1455# define syntax_error_unterm_ch(lineno, ch) syntax_error_unterm_ch(ch) 1456# define syntax_error_unterm_str(lineno, s) syntax_error_unterm_str(s) 1457# define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch) 1458#endif 1459 1460static void die_if_script(void) 1461{ 1462 if (!G_interactive_fd) { 1463 if (G.last_exitcode) /* sometines it's 2, not 1 (bash compat) */ 1464 xfunc_error_retval = G.last_exitcode; 1465 xfunc_die(); 1466 } 1467} 1468 1469#ifdef __U_BOOT__ 1470static void __maybe_unused msg_and_die_if_script(unsigned lineno, const char *fmt, ...) 1471#else /* !__U_BOOT__ */ 1472static void msg_and_die_if_script(unsigned lineno, const char *fmt, ...) 1473#endif /* !__U_BOOT__ */ 1474{ 1475 va_list p; 1476 1477#if HUSH_DEBUG >= 2 1478 bb_error_msg("hush.c:%u", lineno); 1479#endif 1480 va_start(p, fmt); 1481 bb_verror_msg(fmt, p, NULL); 1482 va_end(p); 1483 die_if_script(); 1484} 1485 1486static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg) 1487{ 1488 if (msg) 1489 bb_error_msg("syntax error: %s", msg); 1490 else 1491 bb_simple_error_msg("syntax error"); 1492 die_if_script(); 1493} 1494 1495static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg) 1496{ 1497 bb_error_msg("syntax error at '%s'", msg); 1498 die_if_script(); 1499} 1500 1501static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s) 1502{ 1503 bb_error_msg("syntax error: unterminated %s", s); 1504//? source4.tests fails: in bash, echo ${^} in script does not terminate the script 1505// (but bash --posix, or if bash is run as "sh", does terminate in script, so maybe uncomment this?) 1506// die_if_script(); 1507} 1508 1509static void syntax_error_unterm_ch(unsigned lineno, char ch) 1510{ 1511 char msg[2] = { ch, '\0' }; 1512 syntax_error_unterm_str(lineno, msg); 1513} 1514 1515static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch) 1516{ 1517 char msg[2]; 1518 msg[0] = ch; 1519 msg[1] = '\0'; 1520#if HUSH_DEBUG >= 2 1521 bb_error_msg("hush.c:%u", lineno); 1522#endif 1523 bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg); 1524 die_if_script(); 1525} 1526 1527#if HUSH_DEBUG < 2 1528# undef msg_and_die_if_script 1529# undef syntax_error 1530# undef syntax_error_at 1531# undef syntax_error_unterm_ch 1532# undef syntax_error_unterm_str 1533# undef syntax_error_unexpected_ch 1534#else 1535# define msg_and_die_if_script(...) msg_and_die_if_script(__LINE__, __VA_ARGS__) 1536# define syntax_error(msg) syntax_error(__LINE__, msg) 1537# define syntax_error_at(msg) syntax_error_at(__LINE__, msg) 1538# define syntax_error_unterm_ch(ch) syntax_error_unterm_ch(__LINE__, ch) 1539# define syntax_error_unterm_str(s) syntax_error_unterm_str(__LINE__, s) 1540# define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch) 1541#endif 1542 1543/* Utility functions 1544 */ 1545/* Replace each \x with x in place, return ptr past NUL. */ 1546static char *unbackslash(char *src) 1547{ 1548#ifdef __U_BOOT__ 1549 char *dst = src = (char *)strchrnul(src, '\\'); 1550#else /* !__U_BOOT__ */ 1551 char *dst = src = strchrnul(src, '\\'); 1552#endif /* !__U_BOOT__ */ 1553 while (1) { 1554 if (*src == '\\') { 1555 src++; 1556 if (*src != '\0') { 1557 /* \x -> x */ 1558 *dst++ = *src++; 1559 continue; 1560 } 1561 /* else: "\<nul>". Do not delete this backslash. 1562 * Testcase: eval 'echo ok\' 1563 */ 1564 *dst++ = '\\'; 1565 /* fallthrough */ 1566 } 1567 if ((*dst++ = *src++) == '\0') 1568 break; 1569 } 1570 return dst; 1571} 1572 1573static char **add_strings_to_strings(char **strings, char **add, int need_to_dup) 1574{ 1575 int i; 1576 unsigned count1; 1577 unsigned count2; 1578 char **v; 1579 1580 v = strings; 1581 count1 = 0; 1582 if (v) { 1583 while (*v) { 1584 count1++; 1585 v++; 1586 } 1587 } 1588 count2 = 0; 1589 v = add; 1590 while (*v) { 1591 count2++; 1592 v++; 1593 } 1594 v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*)); 1595 v[count1 + count2] = NULL; 1596 i = count2; 1597 while (--i >= 0) 1598 v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]); 1599 return v; 1600} 1601#if LEAK_HUNTING 1602static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup) 1603{ 1604 char **ptr = add_strings_to_strings(strings, add, need_to_dup); 1605 fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr); 1606 return ptr; 1607} 1608#define add_strings_to_strings(strings, add, need_to_dup) \ 1609 xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup) 1610#endif 1611 1612/* Note: takes ownership of "add" ptr (it is not strdup'ed) */ 1613static char **add_string_to_strings(char **strings, char *add) 1614{ 1615 char *v[2]; 1616 v[0] = add; 1617 v[1] = NULL; 1618 return add_strings_to_strings(strings, v, /*dup:*/ 0); 1619} 1620 1621#if LEAK_HUNTING 1622static char **xx_add_string_to_strings(int lineno, char **strings, char *add) 1623{ 1624 char **ptr = add_string_to_strings(strings, add); 1625 fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr); 1626 return ptr; 1627} 1628#define add_string_to_strings(strings, add) \ 1629 xx_add_string_to_strings(__LINE__, strings, add) 1630#endif 1631 1632static void free_strings(char **strings) 1633{ 1634 char **v; 1635 1636 if (!strings) 1637 return; 1638 v = strings; 1639 while (*v) { 1640 free(*v); 1641 v++; 1642 } 1643 free(strings); 1644} 1645 1646#ifndef __U_BOOT__ 1647static int dup_CLOEXEC(int fd, int avoid_fd) 1648{ 1649 int newfd; 1650 repeat: 1651 newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1); 1652 if (newfd >= 0) { 1653 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */ 1654 close_on_exec_on(newfd); 1655 } else { /* newfd < 0 */ 1656 if (errno == EBUSY) 1657 goto repeat; 1658 if (errno == EINTR) 1659 goto repeat; 1660 if (errno != EBADF) { 1661 /* "echo >&9999" gets EINVAL trying to save fd 1 to above 9999. 1662 * We could try saving it _below_ 9999 instead (how?), but 1663 * this probably means that dup2(9999,1) to effectuate >&9999 1664 * would also not work: fd 9999 can't exist. 1665 * (This differs from "echo >&99" where saving works, but 1666 * subsequent dup2(99,1) fails if fd 99 is not open). 1667 */ 1668 bb_perror_msg("fcntl(%d,F_DUPFD,%d)", fd, avoid_fd + 1); 1669 } 1670 } 1671 return newfd; 1672} 1673 1674static int xdup_CLOEXEC_and_close(int fd, int avoid_fd) 1675{ 1676 int newfd; 1677 repeat: 1678 newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1); 1679 if (newfd < 0) { 1680 if (errno == EBUSY) 1681 goto repeat; 1682 if (errno == EINTR) 1683 goto repeat; 1684 /* fd was not open? */ 1685 if (errno == EBADF) 1686 return fd; 1687 xfunc_die(); 1688 } 1689 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */ 1690 close_on_exec_on(newfd); 1691 close(fd); 1692 return newfd; 1693} 1694 1695/* Manipulating HFILEs */ 1696static HFILE *hfopen(const char *name) 1697{ 1698 HFILE *fp; 1699 int fd; 1700 1701 fd = STDIN_FILENO; 1702 if (name) { 1703 fd = open(name, O_RDONLY | O_CLOEXEC); 1704 if (fd < 0) 1705 return NULL; 1706 if (O_CLOEXEC == 0) /* ancient libc */ 1707 close_on_exec_on(fd); 1708 } 1709 1710 fp = xmalloc(sizeof(*fp)); 1711 if (name == NULL) 1712 G.HFILE_stdin = fp; 1713 fp->fd = fd; 1714 fp->cur = fp->end = fp->buf; 1715 fp->next_hfile = G.HFILE_list; 1716 G.HFILE_list = fp; 1717 return fp; 1718} 1719static void hfclose(HFILE *fp) 1720{ 1721 HFILE **pp = &G.HFILE_list; 1722 while (*pp) { 1723 HFILE *cur = *pp; 1724 if (cur == fp) { 1725 *pp = cur->next_hfile; 1726 break; 1727 } 1728 pp = &cur->next_hfile; 1729 } 1730 if (fp->fd >= 0) 1731 close(fp->fd); 1732 free(fp); 1733} 1734static int refill_HFILE_and_getc(HFILE *fp) 1735{ 1736 int n; 1737 1738 if (fp->fd < 0) { 1739 /* Already saw EOF */ 1740 return EOF; 1741 } 1742#if ENABLE_HUSH_INTERACTIVE && !ENABLE_FEATURE_EDITING 1743 /* If user presses ^C, read() restarts after SIGINT (we use SA_RESTART). 1744 * IOW: ^C will not immediately stop line input. 1745 * But poll() is different: it does NOT restart after signals. 1746 */ 1747 if (fp == G.HFILE_stdin) { 1748 struct pollfd pfd[1]; 1749 pfd[0].fd = fp->fd; 1750 pfd[0].events = POLLIN; 1751 n = poll(pfd, 1, -1); 1752 if (n < 0 1753 /*&& errno == EINTR - assumed true */ 1754 && sigismember(&G.pending_set, SIGINT) 1755 ) { 1756 return '\0'; 1757 } 1758 } 1759#else 1760/* if FEATURE_EDITING=y, we do not use this routine for interactive input */ 1761#endif 1762 /* Try to buffer more input */ 1763 n = safe_read(fp->fd, fp->buf, sizeof(fp->buf)); 1764 if (n < 0) { 1765 bb_simple_perror_msg("read error"); 1766 n = 0; 1767 } 1768 fp->cur = fp->buf; 1769 fp->end = fp->buf + n; 1770 if (n == 0) { 1771 /* EOF/error */ 1772 close(fp->fd); 1773 fp->fd = -1; 1774 return EOF; 1775 } 1776 return (unsigned char)(*fp->cur++); 1777} 1778/* Inlined for common case of non-empty buffer. 1779 */ 1780static ALWAYS_INLINE int hfgetc(HFILE *fp) 1781{ 1782 if (fp->cur < fp->end) 1783 return (unsigned char)(*fp->cur++); 1784 /* Buffer empty */ 1785 return refill_HFILE_and_getc(fp); 1786} 1787static int move_HFILEs_on_redirect(int fd, int avoid_fd) 1788{ 1789 HFILE *fl = G.HFILE_list; 1790 while (fl) { 1791 if (fd == fl->fd) { 1792 /* We use it only on script files, they are all CLOEXEC */ 1793 fl->fd = xdup_CLOEXEC_and_close(fd, avoid_fd); 1794 debug_printf_redir("redirect_fd %d: matches a script fd, moving it to %d\n", fd, fl->fd); 1795 return 1; /* "found and moved" */ 1796 } 1797 fl = fl->next_hfile; 1798 } 1799#if ENABLE_HUSH_MODE_X 1800 if (G.x_mode_fd > 0 && fd == G.x_mode_fd) { 1801 G.x_mode_fd = xdup_CLOEXEC_and_close(fd, avoid_fd); 1802 return 1; /* "found and moved" */ 1803 } 1804#endif 1805 return 0; /* "not in the list" */ 1806} 1807#if ENABLE_FEATURE_SH_STANDALONE && BB_MMU 1808static void close_all_HFILE_list(void) 1809{ 1810 HFILE *fl = G.HFILE_list; 1811 while (fl) { 1812 /* hfclose would also free HFILE object. 1813 * It is disastrous if we share memory with a vforked parent. 1814 * I'm not sure we never come here after vfork. 1815 * Therefore just close fd, nothing more. 1816 * 1817 * ">" instead of ">=": we don't close fd#0, 1818 * interactive shell uses hfopen(NULL) as stdin input 1819 * which has fl->fd == 0, but fd#0 gets redirected in pipes. 1820 * If we'd close it here, then e.g. interactive "set | sort" 1821 * with NOFORKed sort, would have sort's input fd closed. 1822 */ 1823 if (fl->fd > 0) 1824 /*hfclose(fl); - unsafe */ 1825 close(fl->fd); 1826 fl = fl->next_hfile; 1827 } 1828} 1829#endif 1830static int fd_in_HFILEs(int fd) 1831{ 1832 HFILE *fl = G.HFILE_list; 1833 while (fl) { 1834 if (fl->fd == fd) 1835 return 1; 1836 fl = fl->next_hfile; 1837 } 1838 return 0; 1839} 1840 1841#endif /* !__U_BOOT__ */ 1842 1843/* Helpers for setting new $n and restoring them back 1844 */ 1845typedef struct save_arg_t { 1846 char *sv_argv0; 1847 char **sv_g_argv; 1848 int sv_g_argc; 1849#ifndef __U_BOOT__ 1850 IF_HUSH_SET(smallint sv_g_malloced;) 1851#endif /* !__U_BOOT__ */ 1852} save_arg_t; 1853 1854#ifndef __U_BOOT__ 1855static void save_and_replace_G_args(save_arg_t *sv, char **argv) 1856{ 1857 sv->sv_argv0 = argv[0]; 1858 sv->sv_g_argv = G.global_argv; 1859 sv->sv_g_argc = G.global_argc; 1860 IF_HUSH_SET(sv->sv_g_malloced = G.global_args_malloced;) 1861 1862 argv[0] = G.global_argv[0]; /* retain $0 */ 1863 G.global_argv = argv; 1864 IF_HUSH_SET(G.global_args_malloced = 0;) 1865 1866 G.global_argc = 1 + string_array_len(argv + 1); 1867} 1868 1869static void restore_G_args(save_arg_t *sv, char **argv) 1870{ 1871#if ENABLE_HUSH_SET 1872 if (G.global_args_malloced) { 1873 /* someone ran "set -- arg1 arg2 ...", undo */ 1874 char **pp = G.global_argv; 1875 while (*++pp) /* note: does not free $0 */ 1876 free(*pp); 1877 free(G.global_argv); 1878 } 1879#endif 1880 argv[0] = sv->sv_argv0; 1881 G.global_argv = sv->sv_g_argv; 1882 G.global_argc = sv->sv_g_argc; 1883 IF_HUSH_SET(G.global_args_malloced = sv->sv_g_malloced;) 1884} 1885#endif /* !__U_BOOT__ */ 1886 1887#ifndef __U_BOOT__ 1888/* Basic theory of signal handling in shell 1889 * ======================================== 1890 * This does not describe what hush does, rather, it is current understanding 1891 * what it _should_ do. If it doesn't, it's a bug. 1892 * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap 1893 * 1894 * Signals are handled only after each pipe ("cmd | cmd | cmd" thing) 1895 * is finished or backgrounded. It is the same in interactive and 1896 * non-interactive shells, and is the same regardless of whether 1897 * a user trap handler is installed or a shell special one is in effect. 1898 * ^C or ^Z from keyboard seems to execute "at once" because it usually 1899 * backgrounds (i.e. stops) or kills all members of currently running 1900 * pipe. 1901 * 1902 * Wait builtin is interruptible by signals for which user trap is set 1903 * or by SIGINT in interactive shell. 1904 * 1905 * Trap handlers will execute even within trap handlers. (right?) 1906 * 1907 * User trap handlers are forgotten when subshell ("(cmd)") is entered, 1908 * except for handlers set to '' (empty string). 1909 * 1910 * If job control is off, backgrounded commands ("cmd &") 1911 * have SIGINT, SIGQUIT set to SIG_IGN. 1912 * 1913 * Commands which are run in command substitution ("`cmd`") 1914 * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN. 1915 * 1916 * Ordinary commands have signals set to SIG_IGN/DFL as inherited 1917 * by the shell from its parent. 1918 * 1919 * Signals which differ from SIG_DFL action 1920 * (note: child (i.e., [v]forked) shell is not an interactive shell): 1921 * 1922 * SIGQUIT: ignore 1923 * SIGTERM (interactive): ignore 1924 * SIGHUP (interactive): 1925 * Send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit. 1926 * Kernel would do this for us ("orphaned process group" handling 1927 * according to POSIX) if we are a session leader and thus our death 1928 * frees the controlling tty, but to be bash-compatible, we also do it 1929 * for every interactive shell's death by SIGHUP. 1930 * (Also, we need to restore tty pgrp, otherwise e.g. Midnight Commander 1931 * backgrounds when hush started from it gets killed by SIGHUP). 1932 * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore 1933 * Note that ^Z is handled not by trapping SIGTSTP, but by seeing 1934 * that all pipe members are stopped. Try this in bash: 1935 * while :; do :; done - ^Z does not background it 1936 * (while :; do :; done) - ^Z backgrounds it 1937 * SIGINT (interactive): wait for last pipe, ignore the rest 1938 * of the command line, show prompt. NB: ^C does not send SIGINT 1939 * to interactive shell while shell is waiting for a pipe, 1940 * since shell is bg'ed (is not in foreground process group). 1941 * Example 1: this waits 5 sec, but does not execute ls: 1942 * "echo $$; sleep 5; ls -l" + "kill -INT <pid>" 1943 * Example 2: this does not wait and does not execute ls: 1944 * "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>" 1945 * Example 3: this does not wait 5 sec, but executes ls: 1946 * "sleep 5; ls -l" + press ^C 1947 * Example 4: this does not wait and does not execute ls: 1948 * "sleep 5 & wait; ls -l" + press ^C 1949 * 1950 * (What happens to signals which are IGN on shell start?) 1951 * (What happens with signal mask on shell start?) 1952 * 1953 * Old implementation 1954 * ================== 1955 * We use in-kernel pending signal mask to determine which signals were sent. 1956 * We block all signals which we don't want to take action immediately, 1957 * i.e. we block all signals which need to have special handling as described 1958 * above, and all signals which have traps set. 1959 * After each pipe execution, we extract any pending signals via sigtimedwait() 1960 * and act on them. 1961 * 1962 * unsigned special_sig_mask: a mask of such "special" signals 1963 * sigset_t blocked_set: current blocked signal set 1964 * 1965 * "trap - SIGxxx": 1966 * clear bit in blocked_set unless it is also in special_sig_mask 1967 * "trap 'cmd' SIGxxx": 1968 * set bit in blocked_set (even if 'cmd' is '') 1969 * after [v]fork, if we plan to be a shell: 1970 * unblock signals with special interactive handling 1971 * (child shell is not interactive), 1972 * unset all traps except '' (note: regardless of child shell's type - {}, (), etc) 1973 * after [v]fork, if we plan to exec: 1974 * POSIX says fork clears pending signal mask in child - no need to clear it. 1975 * Restore blocked signal set to one inherited by shell just prior to exec. 1976 * 1977 * Note: as a result, we do not use signal handlers much. The only uses 1978 * are to count SIGCHLDs 1979 * and to restore tty pgrp on signal-induced exit. 1980 * 1981 * Note 2 (compat): 1982 * Standard says "When a subshell is entered, traps that are not being ignored 1983 * are set to the default actions". bash interprets it so that traps which 1984 * are set to '' (ignore) are NOT reset to defaults. We do the same. 1985 * 1986 * Problem: the above approach makes it unwieldy to catch signals while 1987 * we are in read builtin, or while we read commands from stdin: 1988 * masked signals are not visible! 1989 * 1990 * New implementation 1991 * ================== 1992 * We record each signal we are interested in by installing signal handler 1993 * for them - a bit like emulating kernel pending signal mask in userspace. 1994 * We are interested in: signals which need to have special handling 1995 * as described above, and all signals which have traps set. 1996 * Signals are recorded in pending_set. 1997 * After each pipe execution, we extract any pending signals 1998 * and act on them. 1999 * 2000 * unsigned special_sig_mask: a mask of shell-special signals. 2001 * unsigned fatal_sig_mask: a mask of signals on which we restore tty pgrp. 2002 * char *traps[sig] if trap for sig is set (even if it's ''). 2003 * sigset_t pending_set: set of sigs we received. 2004 * 2005 * "trap - SIGxxx": 2006 * if sig is in special_sig_mask, set handler back to: 2007 * record_pending_signo, or to IGN if it's a tty stop signal 2008 * if sig is in fatal_sig_mask, set handler back to sigexit. 2009 * else: set handler back to SIG_DFL 2010 * "trap 'cmd' SIGxxx": 2011 * set handler to record_pending_signo. 2012 * "trap '' SIGxxx": 2013 * set handler to SIG_IGN. 2014 * after [v]fork, if we plan to be a shell: 2015 * set signals with special interactive handling to SIG_DFL 2016 * (because child shell is not interactive), 2017 * unset all traps except '' (note: regardless of child shell's type - {}, (), etc) 2018 * after [v]fork, if we plan to exec: 2019 * POSIX says fork clears pending signal mask in child - no need to clear it. 2020 * 2021 * To make wait builtin interruptible, we handle SIGCHLD as special signal, 2022 * otherwise (if we leave it SIG_DFL) sigsuspend in wait builtin will not wake up on it. 2023 * 2024 * Note (compat): 2025 * Standard says "When a subshell is entered, traps that are not being ignored 2026 * are set to the default actions". bash interprets it so that traps which 2027 * are set to '' (ignore) are NOT reset to defaults. We do the same. 2028 */ 2029enum { 2030 SPECIAL_INTERACTIVE_SIGS = 0 2031 | (1 << SIGTERM) 2032 | (1 << SIGINT) 2033 | (1 << SIGHUP) 2034 , 2035 SPECIAL_JOBSTOP_SIGS = 0 2036#if ENABLE_HUSH_JOB 2037 | (1 << SIGTTIN) 2038 | (1 << SIGTTOU) 2039 | (1 << SIGTSTP) 2040#endif 2041 , 2042}; 2043 2044static void record_pending_signo(int sig) 2045{ 2046 sigaddset(&G.pending_set, sig); 2047#if ENABLE_FEATURE_EDITING 2048 if (sig != SIGCHLD 2049 || (G_traps && G_traps[SIGCHLD] && G_traps[SIGCHLD][0]) 2050 /* ^^^ if SIGCHLD, interrupt line reading only if it has a trap */ 2051 ) { 2052 bb_got_signal = sig; /* for read_line_input: "we got a signal" */ 2053 } 2054#endif 2055#if ENABLE_HUSH_FAST 2056 if (sig == SIGCHLD) { 2057 G.count_SIGCHLD++; 2058//bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); 2059 } 2060#endif 2061} 2062 2063static sighandler_t install_sighandler(int sig, sighandler_t handler) 2064{ 2065 struct sigaction old_sa; 2066 2067 /* We could use signal() to install handlers... almost: 2068 * except that we need to mask ALL signals while handlers run. 2069 * I saw signal nesting in strace, race window isn't small. 2070 * SA_RESTART is also needed, but in Linux, signal() 2071 * sets SA_RESTART too. 2072 */ 2073 /* memset(&G.sa, 0, sizeof(G.sa)); - already done */ 2074 /* sigfillset(&G.sa.sa_mask); - already done */ 2075 /* G.sa.sa_flags = SA_RESTART; - already done */ 2076 G.sa.sa_handler = handler; 2077 sigaction(sig, &G.sa, &old_sa); 2078 return old_sa.sa_handler; 2079} 2080#endif /* !__U_BOOT__ */ 2081 2082#ifndef __U_BOOT__ 2083static void hush_exit(int exitcode) NORETURN; 2084 2085static void restore_ttypgrp_and__exit(void) NORETURN; 2086static void restore_ttypgrp_and__exit(void) 2087{ 2088 /* xfunc has failed! die die die */ 2089 /* no EXIT traps, this is an escape hatch! */ 2090 G.exiting = 1; 2091 hush_exit(xfunc_error_retval); 2092} 2093 2094#if ENABLE_HUSH_JOB 2095 2096/* Needed only on some libc: 2097 * It was observed that on exit(), fgetc'ed buffered data 2098 * gets "unwound" via lseek(fd, -NUM, SEEK_CUR). 2099 * With the net effect that even after fork(), not vfork(), 2100 * exit() in NOEXECed applet in "sh SCRIPT": 2101 * noexec_applet_here 2102 * echo END_OF_SCRIPT 2103 * lseeks fd in input FILE object from EOF to "e" in "echo END_OF_SCRIPT". 2104 * This makes "echo END_OF_SCRIPT" executed twice. 2105 * Similar problems can be seen with msg_and_die_if_script() -> xfunc_die() 2106 * and in `cmd` handling. 2107 * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit(): 2108 */ 2109static void fflush_and__exit(void) NORETURN; 2110static void fflush_and__exit(void) 2111{ 2112 fflush_all(); 2113 _exit(xfunc_error_retval); 2114} 2115 2116/* After [v]fork, in child: do not restore tty pgrp on xfunc death */ 2117# define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit) 2118/* After [v]fork, in parent: restore tty pgrp on xfunc death */ 2119# define enable_restore_tty_pgrp_on_exit() (die_func = restore_ttypgrp_and__exit) 2120 2121/* Restores tty foreground process group, and exits. 2122 * May be called as signal handler for fatal signal 2123 * (will resend signal to itself, producing correct exit state) 2124 * or called directly with -EXITCODE. 2125 * We also call it if xfunc is exiting. 2126 */ 2127static void sigexit(int sig) NORETURN; 2128static void sigexit(int sig) 2129{ 2130 /* Careful: we can end up here after [v]fork. Do not restore 2131 * tty pgrp then, only top-level shell process does that */ 2132 if (G_saved_tty_pgrp && getpid() == G.root_pid) { 2133 /* Disable all signals: job control, SIGPIPE, etc. 2134 * Mostly paranoid measure, to prevent infinite SIGTTOU. 2135 */ 2136 sigprocmask_allsigs(SIG_BLOCK); 2137 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp); 2138 } 2139 2140 /* Not a signal, just exit */ 2141 if (sig <= 0) 2142 _exit(- sig); 2143 2144 kill_myself_with_sig(sig); /* does not return */ 2145} 2146#else 2147 2148# define disable_restore_tty_pgrp_on_exit() ((void)0) 2149# define enable_restore_tty_pgrp_on_exit() ((void)0) 2150 2151#endif 2152#endif /* !__U_BOOT__ */ 2153 2154#ifndef __U_BOOT__ 2155static sighandler_t pick_sighandler(unsigned sig) 2156{ 2157 sighandler_t handler = SIG_DFL; 2158 if (sig < sizeof(unsigned)*8) { 2159 unsigned sigmask = (1 << sig); 2160 2161#if ENABLE_HUSH_JOB 2162 /* is sig fatal? */ 2163 if (G_fatal_sig_mask & sigmask) 2164 handler = sigexit; 2165 else 2166#endif 2167 /* sig has special handling? */ 2168 if (G.special_sig_mask & sigmask) { 2169 handler = record_pending_signo; 2170 /* TTIN/TTOU/TSTP can't be set to record_pending_signo 2171 * in order to ignore them: they will be raised 2172 * in an endless loop when we try to do some 2173 * terminal ioctls! We do have to _ignore_ these. 2174 */ 2175 if (SPECIAL_JOBSTOP_SIGS & sigmask) 2176 handler = SIG_IGN; 2177 } 2178 } 2179 return handler; 2180} 2181#endif /* !__U_BOOT__ */ 2182 2183#ifndef __U_BOOT__ 2184/* Restores tty foreground process group, and exits. */ 2185static void hush_exit(int exitcode) 2186{ 2187#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 2188 save_history(G.line_input_state); /* may be NULL */ 2189#endif 2190 2191 fflush_all(); 2192 if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) { 2193 char *argv[3]; 2194 /* argv[0] is unused */ 2195 argv[1] = xstrdup(G_traps[0]); /* copy, since EXIT trap handler may modify G_traps[0] */ 2196 argv[2] = NULL; 2197 G.exiting = 1; /* prevent EXIT trap recursion */ 2198 /* Note: G_traps[0] is not cleared! 2199 * "trap" will still show it, if executed 2200 * in the handler */ 2201 builtin_eval(argv); 2202 } 2203 2204#if ENABLE_FEATURE_CLEAN_UP 2205 { 2206 struct variable *cur_var; 2207 if (G.cwd != bb_msg_unknown) 2208 free((char*)G.cwd); 2209 cur_var = G.top_var; 2210 while (cur_var) { 2211 struct variable *tmp = cur_var; 2212 if (!cur_var->max_len) 2213 free(cur_var->varstr); 2214 cur_var = cur_var->next; 2215 free(tmp); 2216 } 2217 } 2218#endif 2219 2220 fflush_all(); 2221#if ENABLE_HUSH_JOB 2222 sigexit(- (exitcode & 0xff)); 2223#else 2224 _exit(exitcode); 2225#endif 2226} 2227 2228//TODO: return a mask of ALL handled sigs? 2229static int check_and_run_traps(void) 2230{ 2231 int last_sig = 0; 2232 2233 while (1) { 2234 int sig; 2235 2236 if (sigisemptyset(&G.pending_set)) 2237 break; 2238 sig = 0; 2239 do { 2240 sig++; 2241 if (sigismember(&G.pending_set, sig)) { 2242 sigdelset(&G.pending_set, sig); 2243 goto got_sig; 2244 } 2245 } while (sig < NSIG); 2246 break; 2247 got_sig: 2248#if ENABLE_HUSH_TRAP 2249 if (G_traps && G_traps[sig]) { 2250 debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]); 2251 if (G_traps[sig][0]) { 2252 /* We have user-defined handler */ 2253 smalluint save_rcode; 2254 int save_pre; 2255 char *argv[3]; 2256 /* argv[0] is unused */ 2257 argv[1] = xstrdup(G_traps[sig]); 2258 /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */ 2259 argv[2] = NULL; 2260 save_pre = G.pre_trap_exitcode; 2261 G.pre_trap_exitcode = save_rcode = G.last_exitcode; 2262 builtin_eval(argv); 2263 free(argv[1]); 2264 G.pre_trap_exitcode = save_pre; 2265 G.last_exitcode = save_rcode; 2266# if ENABLE_HUSH_FUNCTIONS 2267 if (G.return_exitcode >= 0) { 2268 debug_printf_exec("trap exitcode:%d\n", G.return_exitcode); 2269 G.last_exitcode = G.return_exitcode; 2270 } 2271# endif 2272 last_sig = sig; 2273 } /* else: "" trap, ignoring signal */ 2274 continue; 2275 } 2276#endif 2277 /* not a trap: special action */ 2278 switch (sig) { 2279 case SIGINT: 2280 debug_printf_exec("%s: sig:%d default SIGINT handler\n", __func__, sig); 2281 G.flag_SIGINT = 1; 2282 last_sig = sig; 2283 break; 2284#if ENABLE_HUSH_JOB 2285 case SIGHUP: { 2286 /* if (G_interactive_fd) - no need to check, the handler 2287 * is only installed if we *are* interactive */ 2288 { 2289 /* bash compat: "Before exiting, an interactive 2290 * shell resends the SIGHUP to all jobs, running 2291 * or stopped. Stopped jobs are sent SIGCONT 2292 * to ensure that they receive the SIGHUP." 2293 */ 2294 struct pipe *job; 2295 debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig); 2296 /* bash is observed to signal whole process groups, 2297 * not individual processes */ 2298 for (job = G.job_list; job; job = job->next) { 2299 if (job->pgrp <= 0) 2300 continue; 2301 debug_printf_exec("HUPing pgrp %d\n", job->pgrp); 2302 if (kill(- job->pgrp, SIGHUP) == 0) 2303 kill(- job->pgrp, SIGCONT); 2304 } 2305 } 2306 /* this restores tty pgrp, then kills us with SIGHUP */ 2307 sigexit(SIGHUP); 2308 } 2309#endif 2310#if ENABLE_HUSH_FAST 2311 case SIGCHLD: 2312 debug_printf_exec("%s: sig:%d default SIGCHLD handler\n", __func__, sig); 2313 G.count_SIGCHLD++; 2314//bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); 2315 /* Note: 2316 * We don't do 'last_sig = sig' here -> NOT returning this sig. 2317 * This simplifies wait builtin a bit. 2318 */ 2319 break; 2320#endif 2321 default: /* ignored: */ 2322 debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig); 2323 /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */ 2324 /* Note: 2325 * We don't do 'last_sig = sig' here -> NOT returning this sig. 2326 * Example: wait is not interrupted by TERM 2327 * in interactive shell, because TERM is ignored. 2328 */ 2329 break; 2330 } 2331 } 2332 return last_sig; 2333} 2334 2335static const char *get_cwd(int force) 2336{ 2337 if (force || G.cwd == NULL) { 2338 /* xrealloc_getcwd_or_warn(arg) calls free(arg), 2339 * we must not try to free(bb_msg_unknown) */ 2340 if (G.cwd == bb_msg_unknown) 2341 G.cwd = NULL; 2342 G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd); 2343 if (!G.cwd) 2344 G.cwd = bb_msg_unknown; 2345 } 2346 return G.cwd; 2347} 2348 2349#endif /* !__U_BOOT__ */ 2350 2351/* 2352 * Shell and environment variable support 2353 */ 2354static struct variable **get_ptr_to_local_var(const char *name) 2355{ 2356 struct variable **pp; 2357 struct variable *cur; 2358 2359 pp = &G.top_var; 2360 while ((cur = *pp) != NULL) { 2361 if (varcmp(cur->varstr, name) == 0) 2362 return pp; 2363 pp = &cur->next; 2364 } 2365 return NULL; 2366} 2367 2368static const char* FAST_FUNC get_local_var_value(const char *name) 2369{ 2370 struct variable **vpp; 2371 2372 if (G.expanded_assignments) { 2373 char **cpp = G.expanded_assignments; 2374 while (*cpp) { 2375 char *cp = *cpp; 2376 if (varcmp(cp, name) == 0) 2377 return strchr(cp, '=') + 1; 2378 cpp++; 2379 } 2380 } 2381 2382 vpp = get_ptr_to_local_var(name); 2383 if (vpp) 2384 return strchr((*vpp)->varstr, '=') + 1; 2385 2386#ifndef __U_BOOT__ 2387 if (strcmp(name, "PPID") == 0) 2388 return utoa(G.root_ppid); 2389#endif /* !__U_BOOT__ */ 2390 // bash compat: UID? EUID? 2391#if ENABLE_HUSH_RANDOM_SUPPORT 2392 if (strcmp(name, "RANDOM") == 0) 2393 return utoa(next_random(&G.random_gen)); 2394#endif 2395#if ENABLE_HUSH_LINENO_VAR 2396 if (strcmp(name, "LINENO") == 0) 2397 return utoa(G.execute_lineno); 2398#endif 2399#if BASH_EPOCH_VARS 2400 { 2401 const char *fmt = NULL; 2402 if (strcmp(name, "EPOCHSECONDS") == 0) 2403 fmt = "%llu"; 2404 else if (strcmp(name, "EPOCHREALTIME") == 0) 2405 fmt = "%llu.%06u"; 2406 if (fmt) { 2407 struct timeval tv; 2408 xgettimeofday(&tv); 2409 sprintf(G.epoch_buf, fmt, (unsigned long long)tv.tv_sec, 2410 (unsigned)tv.tv_usec); 2411 return G.epoch_buf; 2412 } 2413 } 2414#endif 2415 return NULL; 2416} 2417 2418#ifndef __U_BOOT__ 2419#if ENABLE_HUSH_GETOPTS 2420static void handle_changed_special_names(const char *name) 2421{ 2422 if (varcmp(name, "OPTIND") == 0) { 2423 G.getopt_count = 0; 2424 return; 2425 } 2426} 2427#else 2428/* Do not even bother evaluating arguments */ 2429# define handle_changed_special_names(...) ((void)0) 2430#endif 2431#else /* __U_BOOT__ */ 2432/* Do not even bother evaluating arguments */ 2433# define handle_changed_special_names(...) ((void)0) 2434#endif /* __U_BOOT__ */ 2435 2436/* str holds "NAME=VAL" and is expected to be malloced. 2437 * We take ownership of it. 2438 */ 2439#ifndef __U_BOOT__ 2440#define SETFLAG_EXPORT (1 << 0) 2441#define SETFLAG_UNEXPORT (1 << 1) 2442#define SETFLAG_MAKE_RO (1 << 2) 2443#endif /* !__U_BOOT__ */ 2444#define SETFLAG_VARLVL_SHIFT 3 2445#ifndef __U_BOOT__ 2446static int set_local_var(char *str, unsigned flags) 2447#else /* __U_BOOT__ */ 2448int set_local_var_modern(char *str, int flags) 2449#endif /* __U_BOOT__ */ 2450{ 2451 struct variable **cur_pp; 2452 struct variable *cur; 2453 char *free_me = NULL; 2454 char *eq_sign; 2455 int name_len; 2456 int retval; 2457#ifndef __U_BOOT__ 2458 unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT); 2459#endif /* !__U_BOOT__ */ 2460 2461 eq_sign = strchr(str, '='); 2462 if (HUSH_DEBUG && !eq_sign) 2463 bb_simple_error_msg_and_die("BUG in setvar"); 2464 2465 name_len = eq_sign - str + 1; /* including '=' */ 2466 cur_pp = &G.top_var; 2467 while ((cur = *cur_pp) != NULL) { 2468 if (strncmp(cur->varstr, str, name_len) != 0) { 2469 cur_pp = &cur->next; 2470 continue; 2471 } 2472 2473#ifndef __U_BOOT__ 2474 /* We found an existing var with this name */ 2475 if (cur->flg_read_only) { 2476 bb_error_msg("%s: readonly variable", str); 2477 free(str); 2478//NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1, 2479//but export per se succeeds (does put the var in env). We don't mimic that. 2480 return -1; 2481 } 2482 if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ? 2483 debug_printf_env("%s: unsetenv '%s'\n", __func__, str); 2484 *eq_sign = '\0'; 2485 unsetenv(str); 2486 *eq_sign = '='; 2487 } 2488 if (cur->var_nest_level < local_lvl) { 2489 /* bash 3.2.33(1) and exported vars: 2490 * # export z=z 2491 * # f() { local z=a; env | grep ^z; } 2492 * # f 2493 * z=a 2494 * # env | grep ^z 2495 * z=z 2496 */ 2497 if (cur->flg_export) 2498 flags |= SETFLAG_EXPORT; 2499 /* New variable is local ("local VAR=VAL" or 2500 * "VAR=VAL cmd") 2501 * and existing one is global, or local 2502 * on a lower level that new one. 2503 * Remove it from global variable list: 2504 */ 2505 *cur_pp = cur->next; 2506 if (G.shadowed_vars_pp) { 2507 /* Save in "shadowed" list */ 2508 debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n", 2509 cur->flg_export ? "exported " : "", 2510 cur->varstr, cur->var_nest_level, str, local_lvl 2511 ); 2512 cur->next = *G.shadowed_vars_pp; 2513 *G.shadowed_vars_pp = cur; 2514 } else { 2515 /* Came from pseudo_exec_argv(), no need to save: delete it */ 2516 debug_printf_env("shadow-deleting %s'%s'/%u by '%s'/%u\n", 2517 cur->flg_export ? "exported " : "", 2518 cur->varstr, cur->var_nest_level, str, local_lvl 2519 ); 2520 if (cur->max_len == 0) /* allocated "VAR=VAL"? */ 2521 free_me = cur->varstr; /* then free it later */ 2522 free(cur); 2523 } 2524 break; 2525 } 2526#endif /* !__U_BOOT__ */ 2527 2528 if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) { 2529 debug_printf_env("assignement '%s' does not change anything\n", str); 2530 free_and_exp: 2531 free(str); 2532 goto exp; 2533 } 2534 2535 /* Replace the value in the found "struct variable" */ 2536 if (cur->max_len != 0) { 2537 if (cur->max_len >= strnlen(str, cur->max_len + 1)) { 2538 /* This one is from startup env, reuse space */ 2539 debug_printf_env("reusing startup env for '%s'\n", str); 2540 strcpy(cur->varstr, str); 2541 goto free_and_exp; 2542 } 2543 /* Can't reuse */ 2544 cur->max_len = 0; 2545 goto set_str_and_exp; 2546 } 2547 /* max_len == 0 signifies "malloced" var, which we can 2548 * (and have to) free. But we can't free(cur->varstr) here: 2549 * if cur->flg_export is 1, it is in the environment. 2550 * We should either unsetenv+free, or wait until putenv, 2551 * then putenv(new)+free(old). 2552 */ 2553 free_me = cur->varstr; 2554 goto set_str_and_exp; 2555 } 2556 2557 /* Not found or shadowed - create new variable struct */ 2558#ifndef __U_BOOT__ 2559 debug_printf_env("%s: alloc new var '%s'/%u\n", __func__, str, local_lvl); 2560#else /* __U_BOOT__ */ 2561 debug_printf_env("%s: alloc new var '%s'\n", __func__, str); 2562#endif /* __U_BOOT__ */ 2563 cur = xzalloc(sizeof(*cur)); 2564#ifndef __U_BOOT__ 2565 cur->var_nest_level = local_lvl; 2566#endif /* !__U_BOOT__ */ 2567 cur->next = *cur_pp; 2568 *cur_pp = cur; 2569 2570 set_str_and_exp: 2571 cur->varstr = str; 2572 exp: 2573#ifndef __U_BOOT__ 2574#if !BB_MMU || ENABLE_HUSH_READONLY 2575 if (flags & SETFLAG_MAKE_RO) { 2576 cur->flg_read_only = 1; 2577 } 2578#endif 2579 if (flags & SETFLAG_EXPORT) 2580 cur->flg_export = 1; 2581#endif /* !__U_BOOT__ */ 2582 retval = 0; 2583#ifndef __U_BOOT__ 2584 if (cur->flg_export) { 2585 if (flags & SETFLAG_UNEXPORT) { 2586 cur->flg_export = 0; 2587 /* unsetenv was already done */ 2588 } else { 2589 debug_printf_env("%s: putenv '%s'/%u\n", __func__, cur->varstr, cur->var_nest_level); 2590 retval = putenv(cur->varstr); 2591 /* fall through to "free(free_me)" - 2592 * only now we can free old exported malloced string 2593 */ 2594 } 2595 } 2596#endif /* !__U_BOOT__ */ 2597 free(free_me); 2598 2599 handle_changed_special_names(cur->varstr); 2600 2601 return retval; 2602} 2603 2604#ifndef __U_BOOT__ 2605static int set_local_var0(char *str) 2606{ 2607 return set_local_var(str, 0); 2608} 2609 2610static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val) 2611{ 2612 char *var = xasprintf("%s=%s", name, val); 2613 set_local_var0(var); 2614} 2615 2616/* Used at startup and after each cd */ 2617static void set_pwd_var(unsigned flag) 2618{ 2619 set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)), flag); 2620} 2621#endif /* !__U_BOOT__ */ 2622 2623#if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS 2624static int unset_local_var(const char *name) 2625{ 2626 struct variable *cur; 2627 struct variable **cur_pp; 2628 2629 cur_pp = &G.top_var; 2630 while ((cur = *cur_pp) != NULL) { 2631 if (varcmp(cur->varstr, name) == 0) { 2632 if (cur->flg_read_only) { 2633 bb_error_msg("%s: readonly variable", name); 2634 return EXIT_FAILURE; 2635 } 2636 2637 *cur_pp = cur->next; 2638 debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr); 2639 bb_unsetenv(cur->varstr); 2640 if (!cur->max_len) 2641 free(cur->varstr); 2642 free(cur); 2643 2644 break; 2645 } 2646 cur_pp = &cur->next; 2647 } 2648 2649 /* Handle "unset LINENO" et al even if did not find the variable to unset */ 2650 handle_changed_special_names(name); 2651 2652 return EXIT_SUCCESS; 2653} 2654#endif 2655 2656#ifndef __U_BOOT__ 2657/* 2658 * Helpers for "var1=val1 var2=val2 cmd" feature 2659 */ 2660static void add_vars(struct variable *var) 2661{ 2662 struct variable *next; 2663 2664 while (var) { 2665 next = var->next; 2666 var->next = G.top_var; 2667 G.top_var = var; 2668 if (var->flg_export) { 2669 debug_printf_env("%s: restoring exported '%s'/%u\n", __func__, var->varstr, var->var_nest_level); 2670 putenv(var->varstr); 2671 } else { 2672 debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level); 2673 } 2674 var = next; 2675 } 2676} 2677 2678/* We put strings[i] into variable table and possibly putenv them. 2679 * If variable is read only, we can free the strings[i] 2680 * which attempts to overwrite it. 2681 * The strings[] vector itself is freed. 2682 */ 2683static void set_vars_and_save_old(char **strings) 2684{ 2685 char **s; 2686 2687 if (!strings) 2688 return; 2689 2690 s = strings; 2691 while (*s) { 2692 struct variable *var_p; 2693 struct variable **var_pp; 2694 char *eq; 2695 2696 eq = strchr(*s, '='); 2697 if (HUSH_DEBUG && !eq) 2698 bb_simple_error_msg_and_die("BUG in varexp4"); 2699 var_pp = get_ptr_to_local_var(*s); 2700 if (var_pp) { 2701 var_p = *var_pp; 2702 if (var_p->flg_read_only) { 2703 char **p; 2704 bb_error_msg("%s: readonly variable", *s); 2705 /* 2706 * "VAR=V BLTIN" unsets VARs after BLTIN completes. 2707 * If VAR is readonly, leaving it in the list 2708 * after asssignment error (msg above) 2709 * causes doubled error message later, on unset. 2710 */ 2711 debug_printf_env("removing/freeing '%s' element\n", *s); 2712 free(*s); 2713 p = s; 2714 do { *p = p[1]; p++; } while (*p); 2715 goto next; 2716 } 2717 /* below, set_local_var() with nest level will 2718 * "shadow" (remove) this variable from 2719 * global linked list. 2720 */ 2721 } 2722 debug_printf_env("%s: env override '%s'/%u\n", __func__, *s, G.var_nest_level); 2723 set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT); 2724 s++; 2725 next: ; 2726 } 2727 free(strings); 2728} 2729 2730/* 2731 * Unicode helper 2732 */ 2733static void reinit_unicode_for_hush(void) 2734{ 2735 /* Unicode support should be activated even if LANG is set 2736 * _during_ shell execution, not only if it was set when 2737 * shell was started. Therefore, re-check LANG every time: 2738 */ 2739 if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV 2740 || ENABLE_UNICODE_USING_LOCALE 2741 ) { 2742 const char *s = get_local_var_value("LC_ALL"); 2743 if (!s) s = get_local_var_value("LC_CTYPE"); 2744 if (!s) s = get_local_var_value("LANG"); 2745 reinit_unicode(s); 2746 } 2747} 2748 2749#endif /* !__U_BOOT__ */ 2750/* 2751 * in_str support (strings, and "strings" read from files). 2752 */ 2753 2754#if ENABLE_HUSH_INTERACTIVE 2755#ifndef __U_BOOT__ 2756/* To test correct lineedit/interactive behavior, type from command line: 2757 * echo $P\ 2758 * \ 2759 * AT\ 2760 * H\ 2761 * \ 2762 * It exercises a lot of corner cases. 2763 */ 2764static const char *setup_prompt_string(void) 2765{ 2766 const char *prompt_str; 2767 2768 debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode); 2769 2770# if ENABLE_FEATURE_EDITING_FANCY_PROMPT 2771 prompt_str = get_local_var_value(G.promptmode == 0 ? "PS1" : "PS2"); 2772 if (!prompt_str) 2773 prompt_str = ""; 2774# else 2775 prompt_str = "> "; /* if PS2, else... */ 2776 if (G.promptmode == 0) { /* PS1 */ 2777 /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */ 2778 free(G.PS1); 2779 /* bash uses $PWD value, even if it is set by user. 2780 * It uses current dir only if PWD is unset. 2781 * We always use current dir. */ 2782 prompt_str = G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#'); 2783 } 2784# endif 2785 debug_printf("prompt_str '%s'\n", prompt_str); 2786 return prompt_str; 2787} 2788#endif /* !__U_BOOT__ */ 2789 2790#ifndef __U_BOOT__ 2791static int get_user_input(struct in_str *i) 2792#else /* __U_BOOT__ */ 2793static void get_user_input(struct in_str *i) 2794#endif /* __U_BOOT__ */ 2795{ 2796#ifndef __U_BOOT__ 2797# if ENABLE_FEATURE_EDITING 2798 /* In EDITING case, this function reads next input line, 2799 * saves it in i->p, then returns 1st char of it. 2800 */ 2801 int r; 2802 const char *prompt_str; 2803 2804 prompt_str = setup_prompt_string(); 2805 for (;;) { 2806 reinit_unicode_for_hush(); 2807 G.flag_SIGINT = 0; 2808 2809 bb_got_signal = 0; 2810 if (!sigisemptyset(&G.pending_set)) { 2811 /* Whoops, already got a signal, do not call read_line_input */ 2812 bb_got_signal = r = -1; 2813 } else { 2814 /* For shell, LI_INTERRUPTIBLE is set: 2815 * read_line_input will abort on either 2816 * getting EINTR in poll() and bb_got_signal became != 0, 2817 * or if it sees bb_got_signal != 0 2818 * (IOW: if signal arrives before poll() is reached). 2819 * Interactive testcases: 2820 * (while kill -INT $$; do sleep 1; done) & 2821 * #^^^ prints ^C, prints prompt, repeats 2822 * trap 'echo I' int; (while kill -INT $$; do sleep 1; done) & 2823 * #^^^ prints ^C, prints "I", prints prompt, repeats 2824 * trap 'echo T' term; (while kill $$; do sleep 1; done) & 2825 * #^^^ prints "T", prints prompt, repeats 2826 * #(bash 5.0.17 exits after first "T", looks like a bug) 2827 */ 2828 r = read_line_input(G.line_input_state, prompt_str, 2829 G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1 2830 ); 2831 /* read_line_input intercepts ^C, "convert" it to SIGINT */ 2832 if (r == 0) 2833 raise(SIGINT); 2834 } 2835 /* bash prints ^C (before running a trap, if any) 2836 * both on keyboard ^C and on real SIGINT (non-kbd generated). 2837 */ 2838 if (sigismember(&G.pending_set, SIGINT)) { 2839 write(STDOUT_FILENO, "^C\n", 3); 2840 G.last_exitcode = 128 | SIGINT; 2841 } 2842 check_and_run_traps(); 2843 if (r == 0) /* keyboard ^C? */ 2844 continue; /* go back, read another input line */ 2845 if (r > 0) /* normal input? (no ^C, no ^D, no signals) */ 2846 break; 2847 if (!bb_got_signal) { 2848 /* r < 0: ^D/EOF/error detected (but not signal) */ 2849 /* ^D on interactive input goes to next line before exiting: */ 2850 write(STDOUT_FILENO, "\n", 1); 2851 i->p = NULL; 2852 i->peek_buf[0] = r = EOF; 2853 return r; 2854 } 2855 /* it was a signal: go back, read another input line */ 2856 } 2857 i->p = G.user_input_buf; 2858 return (unsigned char)*i->p++; 2859# else 2860 /* In !EDITING case, this function gets called for every char. 2861 * Buffering happens deeper in the call chain, in hfgetc(i->file). 2862 */ 2863 int r; 2864 2865 for (;;) { 2866 G.flag_SIGINT = 0; 2867 if (i->last_char == '\0' || i->last_char == '\n') { 2868 const char *prompt_str = setup_prompt_string(); 2869 /* Why check_and_run_traps here? Try this interactively: 2870 * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) & 2871 * $ <[enter], repeatedly...> 2872 * Without check_and_run_traps, handler never runs. 2873 */ 2874 check_and_run_traps(); 2875 fputs_stdout(prompt_str); 2876 fflush_all(); 2877 } 2878 r = hfgetc(i->file); 2879 /* In !ENABLE_FEATURE_EDITING we don't use read_line_input, 2880 * no ^C masking happens during fgetc, no special code for ^C: 2881 * it generates SIGINT as usual. 2882 */ 2883 check_and_run_traps(); 2884 if (r != '\0' && !G.flag_SIGINT) 2885 break; 2886 if (G.flag_SIGINT) { 2887 /* ^C or SIGINT: repeat */ 2888 /* bash prints ^C even on real SIGINT (non-kbd generated) */ 2889 /* kernel prints "^C" itself, just print newline: */ 2890 write(STDOUT_FILENO, "\n", 1); 2891 G.last_exitcode = 128 | SIGINT; 2892 } 2893 } 2894 return r; 2895# endif 2896#else /* __U_BOOT__ */ 2897 int n; 2898 int promptme; 2899 static char the_command[CONFIG_SYS_CBSIZE + 1]; 2900 2901 bootretry_reset_cmd_timeout(); 2902 promptme = 1; 2903 n = u_boot_cli_readline(i); 2904 2905# ifdef CONFIG_BOOT_RETRY_TIME 2906 if (n == -2) { 2907 puts("\nTimeout waiting for command\n"); 2908# ifdef CONFIG_RESET_TO_RETRY 2909 do_reset(NULL, 0, 0, NULL); 2910# else 2911# error "This currently only works with CONFIG_RESET_TO_RETRY enabled" 2912# endif 2913 } 2914# endif 2915 if (n == -1 ) { 2916 G.flag_repeat = 0; 2917 promptme = 0; 2918 } 2919 n = strlen(console_buffer); 2920 console_buffer[n] = '\n'; 2921 console_buffer[n+1]= '\0'; 2922 if (had_ctrlc()) 2923 G.flag_repeat = 0; 2924 clear_ctrlc(); 2925 G.do_repeat = 0; 2926#ifndef __U_BOOT__ 2927 if (G.promptmode == 1) { 2928#else /* __U_BOOT__ */ 2929 if (!G.promptmode) { 2930#endif /* __U_BOOT__ */ 2931 if (console_buffer[0] == '\n'&& G.flag_repeat == 0) { 2932 strcpy(the_command, console_buffer); 2933 } 2934 else { 2935 if (console_buffer[0] != '\n') { 2936 strcpy(the_command, console_buffer); 2937 G.flag_repeat = 1; 2938 } 2939 else { 2940 G.do_repeat = 1; 2941 } 2942 } 2943 i->p = the_command; 2944 } 2945 else { 2946 if (console_buffer[0] != '\n') { 2947 if (strlen(the_command) + strlen(console_buffer) 2948 < CONFIG_SYS_CBSIZE) { 2949 n = strlen(the_command); 2950#ifdef __U_BOOT__ 2951 /* 2952 * To avoid writing to bad places, we check if 2953 * n is greater than 0. 2954 * This bug was found by Harald Seiler. 2955 */ 2956 if (n > 0) 2957 the_command[n-1] = ' '; 2958 strcpy(&the_command[n], console_buffer); 2959#else /* !__U_BOOT__ */ 2960 the_command[n-1] = ' '; 2961 strcpy(&the_command[n], console_buffer); 2962#endif /* !__U_BOOT__ */ 2963 } 2964 else { 2965 the_command[0] = '\n'; 2966 the_command[1] = '\0'; 2967 G.flag_repeat = 0; 2968 } 2969 } 2970 if (promptme == 0) { 2971 the_command[0] = '\n'; 2972 the_command[1] = '\0'; 2973 } 2974 i->p = console_buffer; 2975 } 2976#endif /* __U_BOOT__ */ 2977} 2978/* This is the magic location that prints prompts 2979 * and gets data back from the user */ 2980static int fgetc_interactive(struct in_str *i) 2981{ 2982 int ch; 2983#ifndef __U_BOOT__ 2984 /* If it's interactive stdin, get new line. */ 2985 if (G_interactive_fd && i->file == G.HFILE_stdin) { 2986#endif /* !__U_BOOT__ */ 2987#ifndef __U_BOOT__ 2988 /* Returns first char (or EOF), the rest is in i->p[] */ 2989 ch = get_user_input(i); 2990#else /* __U_BOOT__ */ 2991 /* Avoid garbage value and make clang happy. */ 2992 ch = 0; 2993 /* 2994 * get_user_input() does not return anything when used in 2995 * U-Boot. 2996 * So, we need to take the read character from i->p[]. 2997 */ 2998 get_user_input(i); 2999 if (i->p && *i->p) { 3000 ch = *i->p++; 3001 } 3002#endif /* __U_BOOT__ */ 3003 G.promptmode = 1; /* PS2 */ 3004 debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode); 3005#ifndef __U_BOOT__ 3006 } else { 3007 /* Not stdin: script file, sourced file, etc */ 3008 do ch = hfgetc(i->file); while (ch == '\0'); 3009 } 3010#endif /* !__U_BOOT__ */ 3011 return ch; 3012} 3013#else /* !INTERACTIVE */ 3014#ifndef __U_BOOT__ 3015static ALWAYS_INLINE int fgetc_interactive(struct in_str *i) 3016{ 3017 int ch; 3018 do ch = hfgetc(i->file); while (ch == '\0'); 3019 return ch; 3020} 3021#endif /* !__U_BOOT__ */ 3022#endif /* !INTERACTIVE */ 3023 3024static int i_getch(struct in_str *i) 3025{ 3026 int ch; 3027 3028#ifndef __U_BOOT__ 3029 if (!i->file) { 3030 /* string-based in_str */ 3031 ch = (unsigned char)*i->p; 3032 if (ch != '\0') { 3033 i->p++; 3034 i->last_char = ch; 3035#if ENABLE_HUSH_LINENO_VAR 3036 if (ch == '\n') { 3037 G.parse_lineno++; 3038 debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno); 3039 } 3040#endif 3041 return ch; 3042 } 3043 return EOF; 3044 } 3045 3046#endif /* !__U_BOOT__ */ 3047 /* FILE-based in_str */ 3048 3049#if ENABLE_FEATURE_EDITING 3050 /* This can be stdin, check line editing char[] buffer */ 3051 if (i->p && *i->p != '\0') { 3052 ch = (unsigned char)*i->p++; 3053 goto out; 3054#ifndef __U_BOOT__ 3055 } 3056#else /* __U_BOOT__ */ 3057 /* 3058 * There are two ways for command to be called: 3059 * 1. The first one is when they are typed by the user. 3060 * 2. The second one is through run_command() (NOTE command run 3061 * internally calls run_command()). 3062 * 3063 * In the second case, we do not get input from the user, so once we 3064 * get a '\0', it means we need to stop. 3065 * NOTE G.run_command_flags is only set on run_command call stack, so 3066 * we use this to know if we come from user input or run_command(). 3067 */ 3068 } else if (i->p && *i->p == '\0' && G.run_command_flags){ 3069 return EOF; 3070 } 3071#endif /* __U_BOOT__ */ 3072#endif 3073#ifndef __U_BOOT__ 3074 /* peek_buf[] is an int array, not char. Can contain EOF. */ 3075 ch = i->peek_buf[0]; 3076 if (ch != 0) { 3077 int ch2 = i->peek_buf[1]; 3078 i->peek_buf[0] = ch2; 3079 if (ch2 == 0) /* very likely, avoid redundant write */ 3080 goto out; 3081 i->peek_buf[1] = 0; 3082 goto out; 3083 } 3084 3085#endif /* !__U_BOOT__ */ 3086 ch = fgetc_interactive(i); 3087 out: 3088 debug_printf("file_get: got '%c' %d\n", ch, ch); 3089 i->last_char = ch; 3090#if ENABLE_HUSH_LINENO_VAR 3091 if (ch == '\n') { 3092 G.parse_lineno++; 3093 debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno); 3094 } 3095#endif 3096 return ch; 3097} 3098 3099static int i_peek(struct in_str *i) 3100{ 3101#ifndef __U_BOOT__ 3102 int ch; 3103 3104 if (!i->file) { 3105 /* string-based in_str */ 3106 /* Doesn't report EOF on NUL. None of the callers care. */ 3107 return (unsigned char)*i->p; 3108 } 3109 3110 /* FILE-based in_str */ 3111 3112#if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE 3113 /* This can be stdin, check line editing char[] buffer */ 3114 if (i->p && *i->p != '\0') 3115 return (unsigned char)*i->p; 3116#endif 3117 /* peek_buf[] is an int array, not char. Can contain EOF. */ 3118 ch = i->peek_buf[0]; 3119 if (ch != 0) 3120 return ch; 3121 3122 /* Need to get a new char */ 3123 ch = fgetc_interactive(i); 3124 debug_printf("file_peek: got '%c' %d\n", ch, ch); 3125 3126 /* Save it by either rolling back line editing buffer, or in i->peek_buf[0] */ 3127#if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE 3128 if (i->p) { 3129 i->p -= 1; 3130 return ch; 3131 } 3132#endif 3133 i->peek_buf[0] = ch; 3134 /*i->peek_buf[1] = 0; - already is */ 3135 return ch; 3136#else /* __U_BOOT__ */ 3137 /* string-based in_str */ 3138 /* Doesn't report EOF on NUL. None of the callers care. */ 3139 return (unsigned char)*i->p; 3140#endif /* __U_BOOT__ */ 3141} 3142 3143/* Only ever called if i_peek() was called, and did not return EOF. 3144 * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL, 3145 * not end-of-line. Therefore we never need to read a new editing line here. 3146 */ 3147static int i_peek2(struct in_str *i) 3148{ 3149#ifndef __U_BOOT__ 3150 int ch; 3151#endif /* !__U_BOOT__ */ 3152 3153 /* There are two cases when i->p[] buffer exists. 3154 * (1) it's a string in_str. 3155 * (2) It's a file, and we have a saved line editing buffer. 3156 * In both cases, we know that i->p[0] exists and not NUL, and 3157 * the peek2 result is in i->p[1]. 3158 */ 3159 if (i->p) 3160 return (unsigned char)i->p[1]; 3161 3162#ifndef __U_BOOT__ 3163 /* Now we know it is a file-based in_str. */ 3164 3165 /* peek_buf[] is an int array, not char. Can contain EOF. */ 3166 /* Is there 2nd char? */ 3167 ch = i->peek_buf[1]; 3168 if (ch == 0) { 3169 /* We did not read it yet, get it now */ 3170 do ch = hfgetc(i->file); while (ch == '\0'); 3171 i->peek_buf[1] = ch; 3172 } 3173 3174 debug_printf("file_peek2: got '%c' %d\n", ch, ch); 3175 return ch; 3176#else 3177 return 0; 3178#endif /* __U_BOOT__ */ 3179} 3180 3181static int i_getch_and_eat_bkslash_nl(struct in_str *input) 3182{ 3183 for (;;) { 3184 int ch, ch2; 3185 3186 ch = i_getch(input); 3187 if (ch != '\\') 3188 return ch; 3189 ch2 = i_peek(input); 3190 if (ch2 != '\n') 3191 return ch; 3192 /* backslash+newline, skip it */ 3193 i_getch(input); 3194 } 3195} 3196 3197/* Note: this function _eats_ \<newline> pairs, safe to use plain 3198 * i_getch() after it instead of i_getch_and_eat_bkslash_nl(). 3199 */ 3200static int i_peek_and_eat_bkslash_nl(struct in_str *input) 3201{ 3202 for (;;) { 3203 int ch, ch2; 3204 3205 ch = i_peek(input); 3206 if (ch != '\\') 3207 return ch; 3208 ch2 = i_peek2(input); 3209 if (ch2 != '\n') 3210 return ch; 3211 /* backslash+newline, skip it */ 3212 i_getch(input); 3213 i_getch(input); 3214 } 3215} 3216 3217#ifndef __U_BOOT__ 3218static void setup_file_in_str(struct in_str *i, HFILE *fp) 3219#else /* __U_BOOT__ */ 3220static void setup_file_in_str(struct in_str *i) 3221#endif /* __U_BOOT__ */ 3222{ 3223 memset(i, 0, sizeof(*i)); 3224#ifndef __U_BOOT__ 3225 i->file = fp; 3226 /* i->p = NULL; */ 3227#endif /* !__U_BOOT__ */ 3228} 3229 3230static void setup_string_in_str(struct in_str *i, const char *s) 3231{ 3232 memset(i, 0, sizeof(*i)); 3233 /*i->file = NULL */; 3234 i->p = s; 3235} 3236 3237/* 3238 * o_string support 3239 */ 3240#define B_CHUNK (32 * sizeof(char*)) 3241 3242static void o_reset_to_empty_unquoted(o_string *o) 3243{ 3244 o->length = 0; 3245 o->has_quoted_part = 0; 3246 if (o->data) 3247 o->data[0] = '\0'; 3248} 3249 3250static void o_free_and_set_NULL(o_string *o) 3251{ 3252 free(o->data); 3253 memset(o, 0, sizeof(*o)); 3254} 3255 3256static ALWAYS_INLINE void o_free(o_string *o) 3257{ 3258 free(o->data); 3259} 3260 3261static void o_grow_by(o_string *o, int len) 3262{ 3263 if (o->length + len > o->maxlen) { 3264 o->maxlen += (2 * len) | (B_CHUNK-1); 3265 o->data = xrealloc(o->data, 1 + o->maxlen); 3266 } 3267} 3268 3269static void o_addchr(o_string *o, int ch) 3270{ 3271 debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o); 3272 if (o->length < o->maxlen) { 3273 /* likely. avoid o_grow_by() call */ 3274 add: 3275 o->data[o->length] = ch; 3276 o->length++; 3277 o->data[o->length] = '\0'; 3278 return; 3279 } 3280 o_grow_by(o, 1); 3281 goto add; 3282} 3283 3284#if 0 3285/* Valid only if we know o_string is not empty */ 3286static void o_delchr(o_string *o) 3287{ 3288 o->length--; 3289 o->data[o->length] = '\0'; 3290} 3291#endif 3292 3293static void o_addblock(o_string *o, const char *str, int len) 3294{ 3295 o_grow_by(o, len); 3296 ((char*)mempcpy(&o->data[o->length], str, len))[0] = '\0'; 3297 o->length += len; 3298} 3299 3300static void o_addstr(o_string *o, const char *str) 3301{ 3302 o_addblock(o, str, strlen(str)); 3303} 3304 3305#ifndef __U_BOOT__ 3306static void o_addstr_with_NUL(o_string *o, const char *str) 3307{ 3308 o_addblock(o, str, strlen(str) + 1); 3309} 3310#endif /* !__U_BOOT__ */ 3311 3312#if !BB_MMU 3313static void nommu_addchr(o_string *o, int ch) 3314{ 3315 if (o) 3316 o_addchr(o, ch); 3317} 3318#else 3319# define nommu_addchr(o, str) ((void)0) 3320#endif 3321 3322#ifndef __U_BOOT__ 3323#if ENABLE_HUSH_MODE_X 3324static void x_mode_addchr(int ch) 3325{ 3326 o_addchr(&G.x_mode_buf, ch); 3327} 3328static void x_mode_addstr(const char *str) 3329{ 3330 o_addstr(&G.x_mode_buf, str); 3331} 3332static void x_mode_addblock(const char *str, int len) 3333{ 3334 o_addblock(&G.x_mode_buf, str, len); 3335} 3336static void x_mode_prefix(void) 3337{ 3338 int n = G.x_mode_depth; 3339 do x_mode_addchr('+'); while (--n >= 0); 3340} 3341static void x_mode_flush(void) 3342{ 3343 int len = G.x_mode_buf.length; 3344 if (len <= 0) 3345 return; 3346 if (G.x_mode_fd > 0) { 3347 G.x_mode_buf.data[len] = '\n'; 3348 full_write(G.x_mode_fd, G.x_mode_buf.data, len + 1); 3349 } 3350 G.x_mode_buf.length = 0; 3351} 3352#endif 3353#endif /* !__U_BOOT__ */ 3354 3355/* 3356 * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side. 3357 * Currently, "v='{q,w}'; echo $v" erroneously expands braces in $v. 3358 * Apparently, on unquoted $v bash still does globbing 3359 * ("v='*.txt'; echo $v" prints all .txt files), 3360 * but NOT brace expansion! Thus, there should be TWO independent 3361 * quoting mechanisms on $v expansion side: one protects 3362 * $v from brace expansion, and other additionally protects "$v" against globbing. 3363 * We have only second one. 3364 */ 3365 3366#if ENABLE_HUSH_BRACE_EXPANSION 3367# define MAYBE_BRACES "{}" 3368#else 3369# define MAYBE_BRACES "" 3370#endif 3371 3372/* My analysis of quoting semantics tells me that state information 3373 * is associated with a destination, not a source. 3374 */ 3375static void o_addqchr(o_string *o, int ch) 3376{ 3377 int sz = 1; 3378 /* '-' is included because of this case: 3379 * >filename0 >filename1 >filename9; v='-'; echo filename[0"$v"9] 3380 */ 3381 char *found = strchr("*?[-\\" MAYBE_BRACES, ch); 3382 if (found) 3383 sz++; 3384 o_grow_by(o, sz); 3385 if (found) { 3386 o->data[o->length] = '\\'; 3387 o->length++; 3388 } 3389 o->data[o->length] = ch; 3390 o->length++; 3391 o->data[o->length] = '\0'; 3392} 3393 3394static void o_addQchr(o_string *o, int ch) 3395{ 3396 int sz = 1; 3397 if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS) 3398 && strchr("*?[-\\" MAYBE_BRACES, ch) 3399 ) { 3400 sz++; 3401 o->data[o->length] = '\\'; 3402 o->length++; 3403 } 3404 o_grow_by(o, sz); 3405 o->data[o->length] = ch; 3406 o->length++; 3407 o->data[o->length] = '\0'; 3408} 3409 3410static void o_addqblock(o_string *o, const char *str, int len) 3411{ 3412 while (len) { 3413 char ch; 3414 int sz; 3415 int ordinary_cnt = strcspn(str, "*?[-\\" MAYBE_BRACES); 3416 if (ordinary_cnt > len) /* paranoia */ 3417 ordinary_cnt = len; 3418 o_addblock(o, str, ordinary_cnt); 3419 if (ordinary_cnt == len) 3420 return; /* NUL is already added by o_addblock */ 3421 str += ordinary_cnt; 3422 len -= ordinary_cnt + 1; /* we are processing + 1 char below */ 3423 3424 ch = *str++; 3425 sz = 1; 3426 if (ch) { /* it is necessarily one of "*?[-\\" MAYBE_BRACES */ 3427 sz++; 3428 o->data[o->length] = '\\'; 3429 o->length++; 3430 } 3431 o_grow_by(o, sz); 3432 o->data[o->length] = ch; 3433 o->length++; 3434 } 3435 o->data[o->length] = '\0'; 3436} 3437 3438static void o_addQblock(o_string *o, const char *str, int len) 3439{ 3440 if (!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)) { 3441 o_addblock(o, str, len); 3442 return; 3443 } 3444 o_addqblock(o, str, len); 3445} 3446 3447static void o_addQstr(o_string *o, const char *str) 3448{ 3449 o_addQblock(o, str, strlen(str)); 3450} 3451 3452/* A special kind of o_string for $VAR and `cmd` expansion. 3453 * It contains char* list[] at the beginning, which is grown in 16 element 3454 * increments. Actual string data starts at the next multiple of 16 * (char*). 3455 * list[i] contains an INDEX (int!) into this string data. 3456 * It means that if list[] needs to grow, data needs to be moved higher up 3457 * but list[i]'s need not be modified. 3458 * NB: remembering how many list[i]'s you have there is crucial. 3459 * o_finalize_list() operation post-processes this structure - calculates 3460 * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well. 3461 */ 3462#if DEBUG_EXPAND || DEBUG_GLOB 3463static void debug_print_list(const char *prefix, o_string *o, int n) 3464{ 3465 char **list = (char**)o->data; 3466 int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]); 3467 int i = 0; 3468 3469 indent(); 3470 fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n", 3471 prefix, list, n, string_start, o->length, o->maxlen, 3472 !!(o->o_expflags & EXP_FLAG_GLOB), 3473 o->has_quoted_part, 3474 !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); 3475 while (i < n) { 3476 indent(); 3477 fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i], 3478 o->data + (int)(uintptr_t)list[i] + string_start, 3479 o->data + (int)(uintptr_t)list[i] + string_start); 3480 i++; 3481 } 3482 if (n) { 3483 const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start; 3484 indent(); 3485#ifndef __U_BOOT__ 3486 fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data)); 3487#else /* __U_BOOT__ */ 3488 printf(" total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data)); 3489#endif /* __U_BOOT__ */ 3490 } 3491} 3492#else 3493# define debug_print_list(prefix, o, n) ((void)0) 3494#endif 3495 3496/* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value 3497 * in list[n] so that it points past last stored byte so far. 3498 * It returns n+1. */ 3499static int o_save_ptr_helper(o_string *o, int n) 3500{ 3501 char **list = (char**)o->data; 3502 int string_start; 3503 int string_len; 3504 3505 if (!o->has_empty_slot) { 3506 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]); 3507 string_len = o->length - string_start; 3508 if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */ 3509 debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start); 3510 /* list[n] points to string_start, make space for 16 more pointers */ 3511 o->maxlen += 0x10 * sizeof(list[0]); 3512 o->data = xrealloc(o->data, o->maxlen + 1); 3513 list = (char**)o->data; 3514 memmove(list + n + 0x10, list + n, string_len); 3515 /* 3516 * expand_on_ifs() has a "previous argv[] ends in IFS?" 3517 * check. (grep for -prev-ifs-check-). 3518 * Ensure that argv[-1][last] is not garbage 3519 * but zero bytes, to save index check there. 3520 */ 3521 list[n + 0x10 - 1] = 0; 3522 o->length += 0x10 * sizeof(list[0]); 3523 } else { 3524 debug_printf_list("list[%d]=%d string_start=%d\n", 3525 n, string_len, string_start); 3526 } 3527 } else { 3528 /* We have empty slot at list[n], reuse without growth */ 3529 string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */ 3530 string_len = o->length - string_start; 3531 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n", 3532 n, string_len, string_start); 3533 o->has_empty_slot = 0; 3534 } 3535 o->has_quoted_part = 0; 3536 list[n] = (char*)(uintptr_t)string_len; 3537 return n + 1; 3538} 3539 3540/* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */ 3541static int o_get_last_ptr(o_string *o, int n) 3542{ 3543 char **list = (char**)o->data; 3544 int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]); 3545 3546 return ((int)(uintptr_t)list[n-1]) + string_start; 3547} 3548 3549/* 3550 * Globbing routines. 3551 * 3552 * Most words in commands need to be globbed, even ones which are 3553 * (single or double) quoted. This stems from the possiblity of 3554 * constructs like "abc"* and 'abc'* - these should be globbed. 3555 * Having a different code path for fully-quoted strings ("abc", 3556 * 'abc') would only help performance-wise, but we still need 3557 * code for partially-quoted strings. 3558 * 3559 * Unfortunately, if we want to match bash and ash behavior in all cases, 3560 * the logic can't be "shell-syntax argument is first transformed 3561 * to a string, then globbed, and if globbing does not match anything, 3562 * it is used verbatim". Here are two examples where it fails: 3563 * 3564 * echo 'b\*'? 3565 * 3566 * The globbing can't be avoided (because of '?' at the end). 3567 * The glob pattern is: b\\\*? - IOW, both \ and * are literals 3568 * and are glob-escaped. If this does not match, bash/ash print b\*? 3569 * - IOW: they "unbackslash" the glob pattern. 3570 * Now, look at this: 3571 * 3572 * v='\\\*'; echo b$v? 3573 * 3574 * The glob pattern is the same here: b\\\*? - the unquoted $v expansion 3575 * should be used as glob pattern with no changes. However, if glob 3576 * does not match, bash/ash print b\\\*? - NOT THE SAME as first example! 3577 * 3578 * ash implements this by having an encoded representation of the word 3579 * to glob, which IS NOT THE SAME as the glob pattern - it has more data. 3580 * Glob pattern is derived from it. If glob fails, the decision what result 3581 * should be is made using that encoded representation. Not glob pattern. 3582 */ 3583 3584#if ENABLE_HUSH_BRACE_EXPANSION 3585/* There in a GNU extension, GLOB_BRACE, but it is not usable: 3586 * first, it processes even {a} (no commas), second, 3587 * I didn't manage to make it return strings when they don't match 3588 * existing files. Need to re-implement it. 3589 */ 3590 3591/* Helper */ 3592static int glob_needed(const char *s) 3593{ 3594 while (*s) { 3595 if (*s == '\\') { 3596 if (!s[1]) 3597 return 0; 3598 s += 2; 3599 continue; 3600 } 3601 if (*s == '*' || *s == '[' || *s == '?' || *s == '{') 3602 return 1; 3603 s++; 3604 } 3605 return 0; 3606} 3607/* Return pointer to next closing brace or to comma */ 3608static const char *next_brace_sub(const char *cp) 3609{ 3610 unsigned depth = 0; 3611 cp++; 3612 while (*cp != '\0') { 3613 if (*cp == '\\') { 3614 if (*++cp == '\0') 3615 break; 3616 cp++; 3617 continue; 3618 } 3619 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0)) 3620 break; 3621 if (*cp++ == '{') 3622 depth++; 3623 } 3624 3625 return *cp != '\0' ? cp : NULL; 3626} 3627/* Recursive brace globber. Note: may garble pattern[]. */ 3628static int glob_brace(char *pattern, o_string *o, int n) 3629{ 3630 char *new_pattern_buf; 3631 const char *begin; 3632 const char *next; 3633 const char *rest; 3634 const char *p; 3635 size_t rest_len; 3636 3637 debug_printf_glob("glob_brace('%s')\n", pattern); 3638 3639 begin = pattern; 3640 while (1) { 3641 if (*begin == '\0') 3642 goto simple_glob; 3643 if (*begin == '{') { 3644 /* Find the first sub-pattern and at the same time 3645 * find the rest after the closing brace */ 3646 next = next_brace_sub(begin); 3647 if (next == NULL) { 3648 /* An illegal expression */ 3649 goto simple_glob; 3650 } 3651 if (*next == '}') { 3652 /* "{abc}" with no commas - illegal 3653 * brace expr, disregard and skip it */ 3654 begin = next + 1; 3655 continue; 3656 } 3657 break; 3658 } 3659 if (*begin == '\\' && begin[1] != '\0') 3660 begin++; 3661 begin++; 3662 } 3663 debug_printf_glob("begin:%s\n", begin); 3664 debug_printf_glob("next:%s\n", next); 3665 3666 /* Now find the end of the whole brace expression */ 3667 rest = next; 3668 while (*rest != '}') { 3669 rest = next_brace_sub(rest); 3670 if (rest == NULL) { 3671 /* An illegal expression */ 3672 goto simple_glob; 3673 } 3674 debug_printf_glob("rest:%s\n", rest); 3675 } 3676 rest_len = strlen(++rest) + 1; 3677 3678 /* We are sure the brace expression is well-formed */ 3679 3680 /* Allocate working buffer large enough for our work */ 3681 new_pattern_buf = xmalloc(strlen(pattern)); 3682 3683 /* We have a brace expression. BEGIN points to the opening {, 3684 * NEXT points past the terminator of the first element, and REST 3685 * points past the final }. We will accumulate result names from 3686 * recursive runs for each brace alternative in the buffer using 3687 * GLOB_APPEND. */ 3688 3689 p = begin + 1; 3690 while (1) { 3691 /* Construct the new glob expression */ 3692 memcpy( 3693 mempcpy( 3694 mempcpy(new_pattern_buf, 3695 /* We know the prefix for all sub-patterns */ 3696 pattern, begin - pattern), 3697 p, next - p), 3698 rest, rest_len); 3699 3700 /* Note: glob_brace() may garble new_pattern_buf[]. 3701 * That's why we re-copy prefix every time (1st memcpy above). 3702 */ 3703 n = glob_brace(new_pattern_buf, o, n); 3704 if (*next == '}') { 3705 /* We saw the last entry */ 3706 break; 3707 } 3708 p = next + 1; 3709 next = next_brace_sub(next); 3710 } 3711 free(new_pattern_buf); 3712 return n; 3713 3714 simple_glob: 3715 { 3716 int gr; 3717 glob_t globdata; 3718 3719 memset(&globdata, 0, sizeof(globdata)); 3720 gr = glob(pattern, 0, NULL, &globdata); 3721 debug_printf_glob("glob('%s'):%d\n", pattern, gr); 3722 if (gr != 0) { 3723 if (gr == GLOB_NOMATCH) { 3724 globfree(&globdata); 3725 /* NB: garbles parameter */ 3726 unbackslash(pattern); 3727 o_addstr_with_NUL(o, pattern); 3728 debug_printf_glob("glob pattern '%s' is literal\n", pattern); 3729 return o_save_ptr_helper(o, n); 3730 } 3731 if (gr == GLOB_NOSPACE) 3732 bb_die_memory_exhausted(); 3733 /* GLOB_ABORTED? Only happens with GLOB_ERR flag, 3734 * but we didn't specify it. Paranoia again. */ 3735 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern); 3736 } 3737 if (globdata.gl_pathv && globdata.gl_pathv[0]) { 3738 char **argv = globdata.gl_pathv; 3739 while (1) { 3740 o_addstr_with_NUL(o, *argv); 3741 n = o_save_ptr_helper(o, n); 3742 argv++; 3743 if (!*argv) 3744 break; 3745 } 3746 } 3747 globfree(&globdata); 3748 } 3749 return n; 3750} 3751/* Performs globbing on last list[], 3752 * saving each result as a new list[]. 3753 */ 3754static int perform_glob(o_string *o, int n) 3755{ 3756 char *pattern, *copy; 3757 3758 debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data); 3759 if (!o->data) 3760 return o_save_ptr_helper(o, n); 3761 pattern = o->data + o_get_last_ptr(o, n); 3762 debug_printf_glob("glob pattern '%s'\n", pattern); 3763 if (!glob_needed(pattern)) { 3764 /* unbackslash last string in o in place, fix length */ 3765 o->length = unbackslash(pattern) - o->data; 3766 debug_printf_glob("glob pattern '%s' is literal\n", pattern); 3767 return o_save_ptr_helper(o, n); 3768 } 3769 3770 copy = xstrdup(pattern); 3771 /* "forget" pattern in o */ 3772 o->length = pattern - o->data; 3773 n = glob_brace(copy, o, n); 3774 free(copy); 3775 if (DEBUG_GLOB) 3776 debug_print_list("perform_glob returning", o, n); 3777 return n; 3778} 3779 3780#else /* !HUSH_BRACE_EXPANSION */ 3781 3782/* Helper */ 3783static int glob_needed(const char *s) 3784{ 3785 while (*s) { 3786 if (*s == '\\') { 3787 if (!s[1]) 3788 return 0; 3789 s += 2; 3790 continue; 3791 } 3792 if (*s == '*' || *s == '[' || *s == '?') 3793 return 1; 3794 s++; 3795 } 3796 return 0; 3797} 3798/* Performs globbing on last list[], 3799 * saving each result as a new list[]. 3800 */ 3801static int perform_glob(o_string *o, int n) 3802{ 3803#ifndef __U_BOOT__ 3804 glob_t globdata; 3805 int gr; 3806#endif /* __U_BOOT__ */ 3807 char *pattern; 3808 3809 debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data); 3810 if (!o->data) 3811 return o_save_ptr_helper(o, n); 3812 pattern = o->data + o_get_last_ptr(o, n); 3813 debug_printf_glob("glob pattern '%s'\n", pattern); 3814 if (!glob_needed(pattern)) { 3815#ifndef __U_BOOT__ 3816 literal: 3817#endif /* __U_BOOT__ */ 3818 /* unbackslash last string in o in place, fix length */ 3819 o->length = unbackslash(pattern) - o->data; 3820 debug_printf_glob("glob pattern '%s' is literal\n", pattern); 3821 return o_save_ptr_helper(o, n); 3822 } 3823 3824#ifndef __U_BOOT__ 3825 memset(&globdata, 0, sizeof(globdata)); 3826 /* Can't use GLOB_NOCHECK: it does not unescape the string. 3827 * If we glob "*.\*" and don't find anything, we need 3828 * to fall back to using literal "*.*", but GLOB_NOCHECK 3829 * will return "*.\*"! 3830 */ 3831 gr = glob(pattern, 0, NULL, &globdata); 3832 debug_printf_glob("glob('%s'):%d\n", pattern, gr); 3833 if (gr != 0) { 3834 if (gr == GLOB_NOMATCH) { 3835 globfree(&globdata); 3836 goto literal; 3837 } 3838 if (gr == GLOB_NOSPACE) 3839 bb_die_memory_exhausted(); 3840 /* GLOB_ABORTED? Only happens with GLOB_ERR flag, 3841 * but we didn't specify it. Paranoia again. */ 3842 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern); 3843 } 3844 if (globdata.gl_pathv && globdata.gl_pathv[0]) { 3845 char **argv = globdata.gl_pathv; 3846 /* "forget" pattern in o */ 3847 o->length = pattern - o->data; 3848 while (1) { 3849 o_addstr_with_NUL(o, *argv); 3850 n = o_save_ptr_helper(o, n); 3851 argv++; 3852 if (!*argv) 3853 break; 3854 } 3855 } 3856 globfree(&globdata); 3857 if (DEBUG_GLOB) 3858 debug_print_list("perform_glob returning", o, n); 3859 return n; 3860#else /* __U_BOOT__ */ 3861 /* 3862 * NOTE We only use perform glob to call unbackslash to remove backslash 3863 * from string once expanded. 3864 * So, it seems OK to return this if no previous return was done. 3865 */ 3866 return o_save_ptr_helper(o, n); 3867#endif /* __U_BOOT__ */ 3868} 3869 3870#endif /* !HUSH_BRACE_EXPANSION */ 3871 3872/* If o->o_expflags & EXP_FLAG_GLOB, glob the string so far remembered. 3873 * Otherwise, just finish current list[] and start new */ 3874static int o_save_ptr(o_string *o, int n) 3875{ 3876 if (o->o_expflags & EXP_FLAG_GLOB) { 3877 /* If o->has_empty_slot, list[n] was already globbed 3878 * (if it was requested back then when it was filled) 3879 * so don't do that again! */ 3880 if (!o->has_empty_slot) 3881 return perform_glob(o, n); /* o_save_ptr_helper is inside */ 3882 } 3883 return o_save_ptr_helper(o, n); 3884} 3885 3886/* "Please convert list[n] to real char* ptrs, and NULL terminate it." */ 3887static char **o_finalize_list(o_string *o, int n) 3888{ 3889 char **list; 3890 int string_start; 3891 3892 if (DEBUG_EXPAND) 3893 debug_print_list("finalized", o, n); 3894 debug_printf_expand("finalized n:%d\n", n); 3895 list = (char**)o->data; 3896 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]); 3897 list[--n] = NULL; 3898 while (n) { 3899 n--; 3900 list[n] = o->data + (int)(uintptr_t)list[n] + string_start; 3901 } 3902 return list; 3903} 3904 3905static void free_pipe_list(struct pipe *pi); 3906 3907/* Returns pi->next - next pipe in the list */ 3908static struct pipe *free_pipe(struct pipe *pi) 3909{ 3910 struct pipe *next; 3911 int i; 3912 3913#ifndef __U_BOOT__ 3914 debug_printf_clean("free_pipe (pid %d)\n", getpid()); 3915#endif /* !__U_BOOT__ */ 3916 for (i = 0; i < pi->num_cmds; i++) { 3917 struct command *command; 3918#ifndef __U_BOOT__ 3919 struct redir_struct *r, *rnext; 3920#endif /* !__U_BOOT__ */ 3921 3922 command = &pi->cmds[i]; 3923 debug_printf_clean(" command %d:\n", i); 3924 if (command->argv) { 3925 if (DEBUG_CLEAN) { 3926 int a; 3927 char **p; 3928 for (a = 0, p = command->argv; *p; a++, p++) { 3929 debug_printf_clean(" argv[%d] = %s\n", a, *p); 3930 } 3931 } 3932 free_strings(command->argv); 3933 //command->argv = NULL; 3934 } 3935 /* not "else if": on syntax error, we may have both! */ 3936 if (command->group) { 3937 debug_printf_clean(" begin group (cmd_type:%d)\n", 3938 command->cmd_type); 3939 free_pipe_list(command->group); 3940 debug_printf_clean(" end group\n"); 3941 //command->group = NULL; 3942 } 3943 /* else is crucial here. 3944 * If group != NULL, child_func is meaningless */ 3945#if ENABLE_HUSH_FUNCTIONS 3946 else if (command->child_func) { 3947 debug_printf_exec("cmd %p releases child func at %p\n", command, command->child_func); 3948 command->child_func->parent_cmd = NULL; 3949 } 3950#endif 3951#if !BB_MMU 3952 free(command->group_as_string); 3953 //command->group_as_string = NULL; 3954#endif 3955#ifndef __U_BOOT__ 3956 for (r = command->redirects; r; r = rnext) { 3957 debug_printf_clean(" redirect %d%s", 3958 r->rd_fd, redir_table[r->rd_type].descrip); 3959 /* guard against the case >$FOO, where foo is unset or blank */ 3960 if (r->rd_filename) { 3961 debug_printf_clean(" fname:'%s'\n", r->rd_filename); 3962 free(r->rd_filename); 3963 //r->rd_filename = NULL; 3964 } 3965 debug_printf_clean(" rd_dup:%d\n", r->rd_dup); 3966 rnext = r->next; 3967 free(r); 3968 } 3969 //command->redirects = NULL; 3970#endif /* !__U_BOOT__ */ 3971 } 3972 free(pi->cmds); /* children are an array, they get freed all at once */ 3973 //pi->cmds = NULL; 3974#ifndef __U_BOOT__ 3975#if ENABLE_HUSH_JOB 3976 free(pi->cmdtext); 3977 //pi->cmdtext = NULL; 3978#endif 3979#endif /* !__U_BOOT__ */ 3980 3981 next = pi->next; 3982 free(pi); 3983 return next; 3984} 3985 3986static void free_pipe_list(struct pipe *pi) 3987{ 3988 while (pi) { 3989#if HAS_KEYWORDS 3990 debug_printf_clean("pipe reserved word %d\n", pi->res_word); 3991#endif 3992 debug_printf_clean("pipe followup code %d\n", pi->followup); 3993 pi = free_pipe(pi); 3994 } 3995} 3996 3997/*** Parsing routines ***/ 3998 3999#ifndef debug_print_tree 4000static void debug_print_tree(struct pipe *pi, int lvl) 4001{ 4002 static const char *const PIPE[] ALIGN_PTR = { 4003 [PIPE_SEQ] = "SEQ", 4004 [PIPE_AND] = "AND", 4005 [PIPE_OR ] = "OR" , 4006 [PIPE_BG ] = "BG" , 4007 }; 4008 static const char *RES[] = { 4009 [RES_NONE ] = "NONE" , 4010# if ENABLE_HUSH_IF 4011 [RES_IF ] = "IF" , 4012 [RES_THEN ] = "THEN" , 4013 [RES_ELIF ] = "ELIF" , 4014 [RES_ELSE ] = "ELSE" , 4015 [RES_FI ] = "FI" , 4016# endif 4017# if ENABLE_HUSH_LOOPS 4018 [RES_FOR ] = "FOR" , 4019 [RES_WHILE] = "WHILE", 4020 [RES_UNTIL] = "UNTIL", 4021 [RES_DO ] = "DO" , 4022 [RES_DONE ] = "DONE" , 4023# endif 4024# if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE 4025 [RES_IN ] = "IN" , 4026# endif 4027# if ENABLE_HUSH_CASE 4028 [RES_CASE ] = "CASE" , 4029 [RES_CASE_IN ] = "CASE_IN" , 4030 [RES_MATCH] = "MATCH", 4031 [RES_CASE_BODY] = "CASE_BODY", 4032 [RES_ESAC ] = "ESAC" , 4033# endif 4034 [RES_XXXX ] = "XXXX" , 4035 [RES_SNTX ] = "SNTX" , 4036 }; 4037 static const char *const CMDTYPE[] ALIGN_PTR = { 4038 "{}", 4039 "()", 4040 "[noglob]", 4041# if ENABLE_HUSH_FUNCTIONS 4042 "func()", 4043# endif 4044 }; 4045 4046 int pin, prn; 4047 4048 pin = 0; 4049 while (pi) { 4050 fdprintf(2, "%*spipe %d #cmds:%d %sres_word=%s followup=%d %s\n", 4051 lvl*2, "", 4052 pin, 4053 pi->num_cmds, 4054 (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""), 4055 RES[pi->res_word], 4056 pi->followup, PIPE[pi->followup] 4057 ); 4058 prn = 0; 4059 while (prn < pi->num_cmds) { 4060 struct command *command = &pi->cmds[prn]; 4061 char **argv = command->argv; 4062 4063 fdprintf(2, "%*s cmd %d assignment_cnt:%d", 4064 lvl*2, "", prn, 4065 command->assignment_cnt); 4066# if ENABLE_HUSH_LINENO_VAR 4067 fdprintf(2, " LINENO:%u", command->lineno); 4068# endif 4069 if (command->group) { 4070 fdprintf(2, " group %s: (argv=%p)%s%s\n", 4071 CMDTYPE[command->cmd_type], 4072 argv 4073# if !BB_MMU 4074 , " group_as_string:", command->group_as_string 4075# else 4076 , "", "" 4077# endif 4078 ); 4079 debug_print_tree(command->group, lvl+1); 4080 prn++; 4081 continue; 4082 } 4083 if (argv) while (*argv) { 4084 fdprintf(2, " '%s'", *argv); 4085 argv++; 4086 } 4087#ifndef __U_BOOT__ 4088 if (command->redirects) 4089 fdprintf(2, " {redir}"); 4090#endif /* __U_BOOT__ */ 4091 fdprintf(2, "\n"); 4092 prn++; 4093 } 4094 pi = pi->next; 4095 pin++; 4096 } 4097} 4098#endif /* debug_print_tree */ 4099 4100static struct pipe *new_pipe(void) 4101{ 4102 struct pipe *pi; 4103 pi = xzalloc(sizeof(struct pipe)); 4104 /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */ 4105 return pi; 4106} 4107 4108/* Command (member of a pipe) is complete, or we start a new pipe 4109 * if ctx->command is NULL. 4110 * No errors possible here. 4111 */ 4112static int done_command(struct parse_context *ctx) 4113{ 4114 /* The command is really already in the pipe structure, so 4115 * advance the pipe counter and make a new, null command. */ 4116 struct pipe *pi = ctx->pipe; 4117 struct command *command = ctx->command; 4118 4119#if 0 /* Instead we emit error message at run time */ 4120 if (ctx->pending_redirect) { 4121 /* For example, "cmd >" (no filename to redirect to) */ 4122 syntax_error("invalid redirect"); 4123 ctx->pending_redirect = NULL; 4124 } 4125#endif 4126 4127 if (command) { 4128 if (IS_NULL_CMD(command)) { 4129 debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds); 4130 goto clear_and_ret; 4131 } 4132 pi->num_cmds++; 4133 debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds); 4134 //debug_print_tree(ctx->list_head, 20); 4135 } else { 4136 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds); 4137 } 4138 4139 /* Only real trickiness here is that the uncommitted 4140 * command structure is not counted in pi->num_cmds. */ 4141 pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1)); 4142 ctx->command = command = &pi->cmds[pi->num_cmds]; 4143 clear_and_ret: 4144 memset(command, 0, sizeof(*command)); 4145#if ENABLE_HUSH_LINENO_VAR 4146 command->lineno = G.parse_lineno; 4147 debug_printf_parse("command->lineno = G.parse_lineno (%u)\n", G.parse_lineno); 4148#endif 4149 return pi->num_cmds; /* used only for 0/nonzero check */ 4150} 4151 4152static void done_pipe(struct parse_context *ctx, pipe_style type) 4153{ 4154 int not_null; 4155 4156 debug_printf_parse("done_pipe entered, followup %d\n", type); 4157 /* Close previous command */ 4158 not_null = done_command(ctx); 4159#if HAS_KEYWORDS 4160 ctx->pipe->pi_inverted = ctx->ctx_inverted; 4161 ctx->ctx_inverted = 0; 4162 ctx->pipe->res_word = ctx->ctx_res_w; 4163#endif 4164 if (type == PIPE_BG && ctx->list_head != ctx->pipe) { 4165 /* Necessary since && and || have precedence over &: 4166 * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2, 4167 * in a backgrounded subshell. 4168 */ 4169 struct pipe *pi; 4170 struct command *command; 4171 4172 /* Is this actually this construct, all pipes end with && or ||? */ 4173 pi = ctx->list_head; 4174 while (pi != ctx->pipe) { 4175 if (pi->followup != PIPE_AND && pi->followup != PIPE_OR) 4176 goto no_conv; 4177 pi = pi->next; 4178 } 4179 4180 debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n"); 4181 pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */ 4182 pi = xzalloc(sizeof(*pi)); 4183 pi->followup = PIPE_BG; 4184 pi->num_cmds = 1; 4185 pi->cmds = xzalloc(sizeof(pi->cmds[0])); 4186 command = &pi->cmds[0]; 4187 if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */ 4188 command->cmd_type = CMD_NORMAL; 4189 command->group = ctx->list_head; 4190#if !BB_MMU 4191 command->group_as_string = xstrndup( 4192 ctx->as_string.data, 4193 ctx->as_string.length - 1 /* do not copy last char, "&" */ 4194 ); 4195#endif 4196 /* Replace all pipes in ctx with one newly created */ 4197 ctx->list_head = ctx->pipe = pi; 4198 /* for cases like "cmd && &", do not be tricked by last command 4199 * being null - the entire {...} & is NOT null! */ 4200 not_null = 1; 4201 } else { 4202 no_conv: 4203 ctx->pipe->followup = type; 4204 } 4205 4206 /* Without this check, even just <enter> on command line generates 4207 * tree of three NOPs (!). Which is harmless but annoying. 4208 * IOW: it is safe to do it unconditionally. */ 4209 if (not_null 4210#if ENABLE_HUSH_IF 4211 || ctx->ctx_res_w == RES_FI 4212#endif 4213#if ENABLE_HUSH_LOOPS 4214 || ctx->ctx_res_w == RES_DONE 4215 || ctx->ctx_res_w == RES_FOR 4216 || ctx->ctx_res_w == RES_IN 4217#endif 4218#if ENABLE_HUSH_CASE 4219 || ctx->ctx_res_w == RES_ESAC 4220#endif 4221 ) { 4222 struct pipe *new_p; 4223 debug_printf_parse("done_pipe: adding new pipe: " 4224#ifndef __U_BOOT__ 4225 "not_null:%d ctx->ctx_res_w:%d\n", 4226 not_null, ctx->ctx_res_w); 4227#else /* __U_BOOT__ */ 4228 "not_null:%d\n", 4229 not_null); 4230#endif /* __U_BOOT__ */ 4231 new_p = new_pipe(); 4232 ctx->pipe->next = new_p; 4233 ctx->pipe = new_p; 4234 /* RES_THEN, RES_DO etc are "sticky" - 4235 * they remain set for pipes inside if/while. 4236 * This is used to control execution. 4237 * RES_FOR and RES_IN are NOT sticky (needed to support 4238 * cases where variable or value happens to match a keyword): 4239 */ 4240#if ENABLE_HUSH_LOOPS 4241 if (ctx->ctx_res_w == RES_FOR 4242 || ctx->ctx_res_w == RES_IN) 4243 ctx->ctx_res_w = RES_NONE; 4244#endif 4245#if ENABLE_HUSH_CASE 4246 if (ctx->ctx_res_w == RES_MATCH) 4247 ctx->ctx_res_w = RES_CASE_BODY; 4248 if (ctx->ctx_res_w == RES_CASE) 4249 ctx->ctx_res_w = RES_CASE_IN; 4250#endif 4251 ctx->command = NULL; /* trick done_command below */ 4252 /* Create the memory for command, roughly: 4253 * ctx->pipe->cmds = new struct command; 4254 * ctx->command = &ctx->pipe->cmds[0]; 4255 */ 4256 done_command(ctx); 4257 //debug_print_tree(ctx->list_head, 10); 4258 } 4259 debug_printf_parse("done_pipe return\n"); 4260} 4261 4262static void initialize_context(struct parse_context *ctx) 4263{ 4264 memset(ctx, 0, sizeof(*ctx)); 4265 if (MAYBE_ASSIGNMENT != 0) 4266 ctx->is_assignment = MAYBE_ASSIGNMENT; 4267 ctx->pipe = ctx->list_head = new_pipe(); 4268 /* Create the memory for command, roughly: 4269 * ctx->pipe->cmds = new struct command; 4270 * ctx->command = &ctx->pipe->cmds[0]; 4271 */ 4272 done_command(ctx); 4273} 4274 4275/* If a reserved word is found and processed, parse context is modified 4276 * and 1 is returned. 4277 */ 4278#if HAS_KEYWORDS 4279struct reserved_combo { 4280 char literal[6]; 4281 unsigned char res; 4282 unsigned char assignment_flag; 4283 uint32_t flag; 4284}; 4285enum { 4286 FLAG_END = (1 << RES_NONE ), 4287# if ENABLE_HUSH_IF 4288 FLAG_IF = (1 << RES_IF ), 4289 FLAG_THEN = (1 << RES_THEN ), 4290 FLAG_ELIF = (1 << RES_ELIF ), 4291 FLAG_ELSE = (1 << RES_ELSE ), 4292 FLAG_FI = (1 << RES_FI ), 4293# endif 4294# if ENABLE_HUSH_LOOPS 4295 FLAG_FOR = (1 << RES_FOR ), 4296 FLAG_WHILE = (1 << RES_WHILE), 4297 FLAG_UNTIL = (1 << RES_UNTIL), 4298 FLAG_DO = (1 << RES_DO ), 4299 FLAG_DONE = (1 << RES_DONE ), 4300 FLAG_IN = (1 << RES_IN ), 4301# endif 4302# if ENABLE_HUSH_CASE 4303 FLAG_MATCH = (1 << RES_MATCH), 4304 FLAG_ESAC = (1 << RES_ESAC ), 4305# endif 4306 FLAG_START = (1 << RES_XXXX ), 4307}; 4308 4309static const struct reserved_combo* match_reserved_word(o_string *word) 4310{ 4311 /* Mostly a list of accepted follow-up reserved words. 4312 * FLAG_END means we are done with the sequence, and are ready 4313 * to turn the compound list into a command. 4314 * FLAG_START means the word must start a new compound list. 4315 */ 4316 static const struct reserved_combo reserved_list[] ALIGN4 = { 4317# if ENABLE_HUSH_IF 4318 { "!", RES_NONE, NOT_ASSIGNMENT , 0 }, 4319 { "if", RES_IF, MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START }, 4320 { "then", RES_THEN, MAYBE_ASSIGNMENT, FLAG_ELIF | FLAG_ELSE | FLAG_FI }, 4321 { "elif", RES_ELIF, MAYBE_ASSIGNMENT, FLAG_THEN }, 4322 { "else", RES_ELSE, MAYBE_ASSIGNMENT, FLAG_FI }, 4323 { "fi", RES_FI, NOT_ASSIGNMENT , FLAG_END }, 4324# endif 4325# if ENABLE_HUSH_LOOPS 4326 { "for", RES_FOR, NOT_ASSIGNMENT , FLAG_IN | FLAG_DO | FLAG_START }, 4327 { "while", RES_WHILE, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START }, 4328 { "until", RES_UNTIL, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START }, 4329 { "in", RES_IN, NOT_ASSIGNMENT , FLAG_DO }, 4330 { "do", RES_DO, MAYBE_ASSIGNMENT, FLAG_DONE }, 4331 { "done", RES_DONE, NOT_ASSIGNMENT , FLAG_END }, 4332# endif 4333# if ENABLE_HUSH_CASE 4334 { "case", RES_CASE, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_START }, 4335 { "esac", RES_ESAC, NOT_ASSIGNMENT , FLAG_END }, 4336# endif 4337 }; 4338 const struct reserved_combo *r; 4339 4340 for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) { 4341 if (strcmp(word->data, r->literal) == 0) 4342 return r; 4343 } 4344 return NULL; 4345} 4346/* Return NULL: not a keyword, else: keyword 4347 */ 4348static const struct reserved_combo* reserved_word(struct parse_context *ctx) 4349{ 4350# if ENABLE_HUSH_CASE 4351 static const struct reserved_combo reserved_match = { 4352 "", RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC 4353 }; 4354# endif 4355 const struct reserved_combo *r; 4356 4357 if (ctx->word.has_quoted_part) 4358 return 0; 4359 r = match_reserved_word(&ctx->word); 4360 if (!r) 4361 return r; /* NULL */ 4362 4363 debug_printf("found reserved word %s, res %d\n", r->literal, r->res); 4364# if ENABLE_HUSH_CASE 4365 if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE_IN) { 4366 /* "case word IN ..." - IN part starts first MATCH part */ 4367 r = &reserved_match; 4368 } else 4369# endif 4370 if (r->flag == 0) { /* '!' */ 4371 if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */ 4372 syntax_error("! ! command"); 4373 ctx->ctx_res_w = RES_SNTX; 4374 } 4375 ctx->ctx_inverted = 1; 4376 return r; 4377 } 4378 if (r->flag & FLAG_START) { 4379 struct parse_context *old; 4380 4381 old = xmemdup(ctx, sizeof(*ctx)); 4382 debug_printf_parse("push stack %p\n", old); 4383 initialize_context(ctx); 4384 ctx->stack = old; 4385 } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) { 4386 syntax_error_at(ctx->word.data); 4387 ctx->ctx_res_w = RES_SNTX; 4388 return r; 4389 } else { 4390 /* "{...} fi" is ok. "{...} if" is not 4391 * Example: 4392 * if { echo foo; } then { echo bar; } fi */ 4393 if (ctx->command->group) 4394 done_pipe(ctx, PIPE_SEQ); 4395 } 4396 4397 ctx->ctx_res_w = r->res; 4398 ctx->old_flag = r->flag; 4399 ctx->is_assignment = r->assignment_flag; 4400 debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]); 4401 4402 if (ctx->old_flag & FLAG_END) { 4403 struct parse_context *old; 4404 4405 done_pipe(ctx, PIPE_SEQ); 4406 debug_printf_parse("pop stack %p\n", ctx->stack); 4407 old = ctx->stack; 4408 old->command->group = ctx->list_head; 4409 old->command->cmd_type = CMD_NORMAL; 4410# if !BB_MMU 4411 /* At this point, the compound command's string is in 4412 * ctx->as_string... except for the leading keyword! 4413 * Consider this example: "echo a | if true; then echo a; fi" 4414 * ctx->as_string will contain "true; then echo a; fi", 4415 * with "if " remaining in old->as_string! 4416 */ 4417 { 4418 char *str; 4419 int len = old->as_string.length; 4420 /* Concatenate halves */ 4421 o_addstr(&old->as_string, ctx->as_string.data); 4422 o_free(&ctx->as_string); 4423 /* Find where leading keyword starts in first half */ 4424 str = old->as_string.data + len; 4425 if (str > old->as_string.data) 4426 str--; /* skip whitespace after keyword */ 4427 while (str > old->as_string.data && isalpha(str[-1])) 4428 str--; 4429 /* Ugh, we're done with this horrid hack */ 4430 old->command->group_as_string = xstrdup(str); 4431 debug_printf_parse("pop, remembering as:'%s'\n", 4432 old->command->group_as_string); 4433 } 4434# endif 4435 *ctx = *old; /* physical copy */ 4436 free(old); 4437 } 4438 return r; 4439} 4440#endif /* HAS_KEYWORDS */ 4441 4442/* Word is complete, look at it and update parsing context. 4443 * Normal return is 0. Syntax errors return 1. 4444 * Note: on return, word is reset, but not o_free'd! 4445 */ 4446static int done_word(struct parse_context *ctx) 4447{ 4448 struct command *command = ctx->command; 4449 4450 debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command); 4451 if (ctx->word.length == 0 && !ctx->word.has_quoted_part) { 4452 debug_printf_parse("done_word return 0: true null, ignored\n"); 4453 return 0; 4454 } 4455 4456#ifndef __U_BOOT__ 4457 if (ctx->pending_redirect) { 4458 /* We do not glob in e.g. >*.tmp case. bash seems to glob here 4459 * only if run as "bash", not "sh" */ 4460 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html 4461 * "2.7 Redirection 4462 * If the redirection operator is "<<" or "<<-", the word 4463 * that follows the redirection operator shall be 4464 * subjected to quote removal; it is unspecified whether 4465 * any of the other expansions occur. For the other 4466 * redirection operators, the word that follows the 4467 * redirection operator shall be subjected to tilde 4468 * expansion, parameter expansion, command substitution, 4469 * arithmetic expansion, and quote removal. 4470 * Pathname expansion shall not be performed 4471 * on the word by a non-interactive shell; an interactive 4472 * shell may perform it, but shall do so only when 4473 * the expansion would result in one word." 4474 */ 4475//bash does not do parameter/command substitution or arithmetic expansion 4476//for _heredoc_ redirection word: these constructs look for exact eof marker 4477// as written: 4478// <<EOF$t 4479// <<EOF$((1)) 4480// <<EOF`true` [this case also makes heredoc "quoted", a-la <<"EOF". Probably bash-4.3.43 bug] 4481 4482 ctx->pending_redirect->rd_filename = xstrdup(ctx->word.data); 4483 /* Cater for >\file case: 4484 * >\a creates file a; >\\a, >"\a", >"\\a" create file \a 4485 * Same with heredocs: 4486 * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H 4487 */ 4488 if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) { 4489 unbackslash(ctx->pending_redirect->rd_filename); 4490 /* Is it <<"HEREDOC"? */ 4491 if (ctx->word.has_quoted_part) { 4492 ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; 4493 } 4494 } 4495 debug_printf_parse("word stored in rd_filename: '%s'\n", ctx->word.data); 4496 ctx->pending_redirect = NULL; 4497 } else { 4498#endif /* !__U_BOOT__ */ 4499#if HAS_KEYWORDS 4500# if ENABLE_HUSH_CASE 4501 if (ctx->ctx_dsemicolon 4502 && strcmp(ctx->word.data, "esac") != 0 /* not "... pattern) cmd;; esac" */ 4503 ) { 4504 /* already done when ctx_dsemicolon was set to 1: */ 4505 /* ctx->ctx_res_w = RES_MATCH; */ 4506 ctx->ctx_dsemicolon = 0; 4507 } else 4508# endif 4509# if defined(CMD_TEST2_SINGLEWORD_NOGLOB) 4510 if (command->cmd_type == CMD_TEST2_SINGLEWORD_NOGLOB 4511 && strcmp(ctx->word.data, "]]") == 0 4512 ) { 4513 /* allow "[[ ]] >file" etc */ 4514 command->cmd_type = CMD_SINGLEWORD_NOGLOB; 4515 } else 4516# endif 4517 if (!command->argv /* if it's the first word... */ 4518# if ENABLE_HUSH_LOOPS 4519 && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */ 4520 && ctx->ctx_res_w != RES_IN 4521# endif 4522# if ENABLE_HUSH_CASE 4523 && ctx->ctx_res_w != RES_CASE 4524# endif 4525 ) { 4526 const struct reserved_combo *reserved; 4527 reserved = reserved_word(ctx); 4528 debug_printf_parse("checking for reserved-ness: %d\n", !!reserved); 4529 if (reserved) { 4530# if ENABLE_HUSH_LINENO_VAR 4531/* Case: 4532 * "while ...; do 4533 * cmd ..." 4534 * If we don't close the pipe _now_, immediately after "do", lineno logic 4535 * sees "cmd" as starting at "do" - i.e., at the previous line. 4536 */ 4537 if (0 4538 IF_HUSH_IF(|| reserved->res == RES_THEN) 4539 IF_HUSH_IF(|| reserved->res == RES_ELIF) 4540 IF_HUSH_IF(|| reserved->res == RES_ELSE) 4541 IF_HUSH_LOOPS(|| reserved->res == RES_DO) 4542 ) { 4543 done_pipe(ctx, PIPE_SEQ); 4544 } 4545# endif 4546 o_reset_to_empty_unquoted(&ctx->word); 4547 debug_printf_parse("done_word return %d\n", 4548 (ctx->ctx_res_w == RES_SNTX)); 4549 return (ctx->ctx_res_w == RES_SNTX); 4550 } 4551# if defined(CMD_TEST2_SINGLEWORD_NOGLOB) 4552 if (strcmp(ctx->word.data, "[[") == 0) { 4553 command->cmd_type = CMD_TEST2_SINGLEWORD_NOGLOB; 4554 } else 4555# endif 4556# if defined(CMD_SINGLEWORD_NOGLOB) 4557 if (0 4558 /* In bash, local/export/readonly are special, args 4559 * are assignments and therefore expansion of them 4560 * should be "one-word" expansion: 4561 * $ export i=`echo 'a b'` # one arg: "i=a b" 4562 * compare with: 4563 * $ ls i=`echo 'a b'` # two args: "i=a" and "b" 4564 * ls: cannot access i=a: No such file or directory 4565 * ls: cannot access b: No such file or directory 4566 * Note: bash 3.2.33(1) does this only if export word 4567 * itself is not quoted: 4568 * $ export i=`echo 'aaa bbb'`; echo "$i" 4569 * aaa bbb 4570 * $ "export" i=`echo 'aaa bbb'`; echo "$i" 4571 * aaa 4572 */ 4573 IF_HUSH_LOCAL( || strcmp(ctx->word.data, "local") == 0) 4574 IF_HUSH_EXPORT( || strcmp(ctx->word.data, "export") == 0) 4575 IF_HUSH_READONLY(|| strcmp(ctx->word.data, "readonly") == 0) 4576 ) { 4577 command->cmd_type = CMD_SINGLEWORD_NOGLOB; 4578 } 4579# else 4580 { /* empty block to pair "if ... else" */ } 4581# endif 4582 } 4583#endif /* HAS_KEYWORDS */ 4584 4585 if (command->group) { 4586 /* "{ echo foo; } echo bar" - bad */ 4587 syntax_error_at(ctx->word.data); 4588 debug_printf_parse("done_word return 1: syntax error, " 4589 "groups and arglists don't mix\n"); 4590 return 1; 4591 } 4592 4593 /* If this word wasn't an assignment, next ones definitely 4594 * can't be assignments. Even if they look like ones. */ 4595 if (ctx->is_assignment != DEFINITELY_ASSIGNMENT 4596 && ctx->is_assignment != WORD_IS_KEYWORD 4597 ) { 4598 ctx->is_assignment = NOT_ASSIGNMENT; 4599 } else { 4600 if (ctx->is_assignment == DEFINITELY_ASSIGNMENT) { 4601 command->assignment_cnt++; 4602 debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt); 4603 } 4604 debug_printf_parse("ctx->is_assignment was:'%s'\n", assignment_flag[ctx->is_assignment]); 4605 ctx->is_assignment = MAYBE_ASSIGNMENT; 4606 } 4607 debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]); 4608 command->argv = add_string_to_strings(command->argv, xstrdup(ctx->word.data)); 4609#ifdef __U_BOOT__ 4610 command->argc++; 4611#endif /* __U_BOOT__ */ 4612 debug_print_strings("word appended to argv", command->argv); 4613 4614#ifndef __U_BOOT__ 4615 } 4616#endif /* !__U_BOOT__ */ 4617 4618#if ENABLE_HUSH_LOOPS 4619 if (ctx->ctx_res_w == RES_FOR) { 4620 if (ctx->word.has_quoted_part 4621 || endofname(command->argv[0])[0] != '\0' 4622 ) { 4623 /* bash says just "not a valid identifier" */ 4624 syntax_error("bad for loop variable"); 4625 return 1; 4626 } 4627 /* Force FOR to have just one word (variable name) */ 4628 /* NB: basically, this makes hush see "for v in ..." 4629 * syntax as if it is "for v; in ...". FOR and IN become 4630 * two pipe structs in parse tree. */ 4631 done_pipe(ctx, PIPE_SEQ); 4632 } 4633#endif 4634#if ENABLE_HUSH_CASE 4635 /* Force CASE to have just one word */ 4636 if (ctx->ctx_res_w == RES_CASE) { 4637 done_pipe(ctx, PIPE_SEQ); 4638 } 4639#endif 4640 4641 o_reset_to_empty_unquoted(&ctx->word); 4642 4643 debug_printf_parse("done_word return 0\n"); 4644 return 0; 4645} 4646 4647#ifndef __U_BOOT__ 4648/* Peek ahead in the input to find out if we have a "&n" construct, 4649 * as in "2>&1", that represents duplicating a file descriptor. 4650 * Return: 4651 * REDIRFD_CLOSE if >&- "close fd" construct is seen, 4652 * REDIRFD_SYNTAX_ERR if syntax error, 4653 * REDIRFD_TO_FILE if no & was seen, 4654 * or the number found. 4655 */ 4656#if BB_MMU 4657#define parse_redir_right_fd(as_string, input) \ 4658 parse_redir_right_fd(input) 4659#endif 4660static int parse_redir_right_fd(o_string *as_string, struct in_str *input) 4661{ 4662 int ch, d, ok; 4663 4664 ch = i_peek(input); 4665 if (ch != '&') 4666 return REDIRFD_TO_FILE; 4667 4668 ch = i_getch(input); /* get the & */ 4669 nommu_addchr(as_string, ch); 4670 ch = i_peek(input); 4671 if (ch == '-') { 4672 ch = i_getch(input); 4673 nommu_addchr(as_string, ch); 4674 return REDIRFD_CLOSE; 4675 } 4676 d = 0; 4677 ok = 0; 4678 while (ch != EOF && isdigit(ch)) { 4679 d = d*10 + (ch-'0'); 4680 ok = 1; 4681 ch = i_getch(input); 4682 nommu_addchr(as_string, ch); 4683 ch = i_peek(input); 4684 } 4685 if (ok) return d; 4686 4687//TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2) 4688 4689 bb_simple_error_msg("ambiguous redirect"); 4690 return REDIRFD_SYNTAX_ERR; 4691} 4692 4693/* Return code is 0 normal, 1 if a syntax error is detected 4694 */ 4695static int parse_redirect(struct parse_context *ctx, 4696 int fd, 4697 redir_type style, 4698 struct in_str *input) 4699{ 4700 struct command *command = ctx->command; 4701 struct redir_struct *redir; 4702 struct redir_struct **redirp; 4703 int dup_num; 4704 4705 dup_num = REDIRFD_TO_FILE; 4706 if (style != REDIRECT_HEREDOC) { 4707 /* Check for a '>&1' type redirect */ 4708 dup_num = parse_redir_right_fd(&ctx->as_string, input); 4709 if (dup_num == REDIRFD_SYNTAX_ERR) 4710 return 1; 4711 } else { 4712 int ch = i_peek_and_eat_bkslash_nl(input); 4713 dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */ 4714 if (dup_num) { /* <<-... */ 4715 ch = i_getch(input); 4716 nommu_addchr(&ctx->as_string, ch); 4717 ch = i_peek(input); 4718 } 4719 } 4720 4721 if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) { 4722 int ch = i_peek_and_eat_bkslash_nl(input); 4723 if (ch == '|') { 4724 /* >|FILE redirect ("clobbering" >). 4725 * Since we do not support "set -o noclobber" yet, 4726 * >| and > are the same for now. Just eat |. 4727 */ 4728 ch = i_getch(input); 4729 nommu_addchr(&ctx->as_string, ch); 4730 } 4731 } 4732 4733 /* Create a new redir_struct and append it to the linked list */ 4734 redirp = &command->redirects; 4735 while ((redir = *redirp) != NULL) { 4736 redirp = &(redir->next); 4737 } 4738 *redirp = redir = xzalloc(sizeof(*redir)); 4739 /* redir->next = NULL; */ 4740 /* redir->rd_filename = NULL; */ 4741 redir->rd_type = style; 4742 redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd; 4743 4744 debug_printf_parse("redirect type %d %s\n", redir->rd_fd, 4745 redir_table[style].descrip); 4746 4747 redir->rd_dup = dup_num; 4748 if (style != REDIRECT_HEREDOC && dup_num != REDIRFD_TO_FILE) { 4749 /* Erik had a check here that the file descriptor in question 4750 * is legit; I postpone that to "run time" 4751 * A "-" representation of "close me" shows up as a -3 here */ 4752 debug_printf_parse("duplicating redirect '%d>&%d'\n", 4753 redir->rd_fd, redir->rd_dup); 4754 } else { 4755#if 0 /* Instead we emit error message at run time */ 4756 if (ctx->pending_redirect) { 4757 /* For example, "cmd > <file" */ 4758 syntax_error("invalid redirect"); 4759 } 4760#endif 4761 /* Set ctx->pending_redirect, so we know what to do at the 4762 * end of the next parsed word. */ 4763 ctx->pending_redirect = redir; 4764 } 4765 return 0; 4766} 4767 4768/* If a redirect is immediately preceded by a number, that number is 4769 * supposed to tell which file descriptor to redirect. This routine 4770 * looks for such preceding numbers. In an ideal world this routine 4771 * needs to handle all the following classes of redirects... 4772 * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo 4773 * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo 4774 * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo 4775 * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo 4776 * 4777 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html 4778 * "2.7 Redirection 4779 * ... If n is quoted, the number shall not be recognized as part of 4780 * the redirection expression. For example: 4781 * echo \2>a 4782 * writes the character 2 into file a" 4783 * We are getting it right by setting ->has_quoted_part on any \<char> 4784 * 4785 * A -1 return means no valid number was found, 4786 * the caller should use the appropriate default for this redirection. 4787 */ 4788static int redirect_opt_num(o_string *o) 4789{ 4790 int num; 4791 4792 if (o->data == NULL) 4793 return -1; 4794 num = bb_strtou(o->data, NULL, 10); 4795 if (errno || num < 0) 4796 return -1; 4797 o_reset_to_empty_unquoted(o); 4798 return num; 4799} 4800 4801#if BB_MMU 4802#define fetch_till_str(as_string, input, word, skip_tabs) \ 4803 fetch_till_str(input, word, skip_tabs) 4804#endif 4805static char *fetch_till_str(o_string *as_string, 4806 struct in_str *input, 4807 const char *word, 4808 int heredoc_flags) 4809{ 4810 o_string heredoc = NULL_O_STRING; 4811 unsigned past_EOL; 4812 int prev = 0; /* not \ */ 4813 int ch; 4814 4815 /* Starting with "" is necessary for this case: 4816 * cat <<EOF 4817 * 4818 * xxx 4819 * EOF 4820 */ 4821 heredoc.data = xzalloc(1); /* start as "", not as NULL */ 4822 4823 goto jump_in; 4824 4825 while (1) { 4826 ch = i_getch(input); 4827 if (ch != EOF) 4828 nommu_addchr(as_string, ch); 4829 if (ch == '\n' || ch == EOF) { 4830 check_heredoc_end: 4831#ifndef __U_BOOT__ 4832 if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') { 4833#else /* __U_BOOT__ */ 4834 if (prev != '\\') { 4835#endif 4836 /* End-of-line, and not a line continuation */ 4837 if (strcmp(heredoc.data + past_EOL, word) == 0) { 4838 heredoc.data[past_EOL] = '\0'; 4839 debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data); 4840 return heredoc.data; 4841 } 4842 if (ch == '\n') { 4843 /* This is a new line. 4844 * Remember position and backslash-escaping status. 4845 */ 4846 o_addchr(&heredoc, ch); 4847 prev = ch; 4848 jump_in: 4849 past_EOL = heredoc.length; 4850 /* Get 1st char of next line, possibly skipping leading tabs */ 4851 do { 4852 ch = i_getch(input); 4853 if (ch != EOF) 4854 nommu_addchr(as_string, ch); 4855#ifndef __U_BOOT__ 4856 } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t'); 4857#else /* __U_BOOT__ */ 4858 } while (ch == '\t'); 4859#endif 4860 /* If this immediately ended the line, 4861 * go back to end-of-line checks. 4862 */ 4863 if (ch == '\n') 4864 goto check_heredoc_end; 4865 } 4866 } else { 4867 /* Backslash-line continuation in an unquoted 4868 * heredoc. This does not need special handling 4869 * for heredoc body (unquoted heredocs are 4870 * expanded on "execution" and that would take 4871 * care of this case too), but not the case 4872 * of line continuation *in terminator*: 4873 * cat <<EOF 4874 * Ok1 4875 * EO\ 4876 * F 4877 */ 4878 heredoc.data[--heredoc.length] = '\0'; 4879 prev = 0; /* not '\' */ 4880 continue; 4881 } 4882 } 4883 if (ch == EOF) { 4884 o_free(&heredoc); 4885 return NULL; /* error */ 4886 } 4887 o_addchr(&heredoc, ch); 4888 nommu_addchr(as_string, ch); 4889 if (prev == '\\' && ch == '\\') 4890 /* Correctly handle foo\\<eol> (not a line cont.) */ 4891 prev = 0; /* not '\' */ 4892 else 4893 prev = ch; 4894 } 4895} 4896#endif /* !__U_BOOT__ */ 4897 4898/* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs 4899 * and load them all. There should be exactly heredoc_cnt of them. 4900 */ 4901#if BB_MMU 4902#define fetch_heredocs(as_string, pi, heredoc_cnt, input) \ 4903 fetch_heredocs(pi, heredoc_cnt, input) 4904#endif 4905static int fetch_heredocs(o_string *as_string, struct pipe *pi, int heredoc_cnt, struct in_str *input) 4906{ 4907 while (pi && heredoc_cnt) { 4908 int i; 4909 struct command *cmd = pi->cmds; 4910 4911 debug_printf_heredoc("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n", 4912 pi->num_cmds, 4913 cmd->argv ? cmd->argv[0] : "NONE" 4914 ); 4915 for (i = 0; i < pi->num_cmds; i++) { 4916#ifndef __U_BOOT__ 4917 struct redir_struct *redir = cmd->redirects; 4918 4919#endif /* !__U_BOOT__ */ 4920 debug_printf_heredoc("fetch_heredocs: %d cmd argv0:'%s'\n", 4921 i, cmd->argv ? cmd->argv[0] : "NONE"); 4922#ifndef __U_BOOT__ 4923 while (redir) { 4924 if (redir->rd_type == REDIRECT_HEREDOC) { 4925 char *p; 4926 4927 redir->rd_type = REDIRECT_HEREDOC2; 4928 /* redir->rd_dup is (ab)used to indicate <<- */ 4929 p = fetch_till_str(as_string, input, 4930 redir->rd_filename, redir->rd_dup); 4931 if (!p) { 4932 syntax_error("unexpected EOF in here document"); 4933 return -1; 4934 } 4935 free(redir->rd_filename); 4936 redir->rd_filename = p; 4937 heredoc_cnt--; 4938 } 4939 redir = redir->next; 4940 } 4941#endif /* !__U_BOOT__ */ 4942 if (cmd->group) { 4943 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt); 4944 heredoc_cnt = fetch_heredocs(as_string, cmd->group, heredoc_cnt, input); 4945 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt); 4946 if (heredoc_cnt < 0) 4947 return heredoc_cnt; /* error */ 4948 } 4949 cmd++; 4950 } 4951 pi = pi->next; 4952 } 4953 return heredoc_cnt; 4954} 4955 4956static int run_list(struct pipe *pi); 4957#if BB_MMU 4958#define parse_stream(pstring, heredoc_cnt_ptr, input, end_trigger) \ 4959 parse_stream(heredoc_cnt_ptr, input, end_trigger) 4960#endif 4961static struct pipe *parse_stream(char **pstring, 4962 int *heredoc_cnt_ptr, 4963 struct in_str *input, 4964 int end_trigger); 4965 4966/* Returns number of heredocs not yet consumed, 4967 * or -1 on error. 4968 */ 4969static int parse_group(struct parse_context *ctx, 4970 struct in_str *input, int ch) 4971{ 4972 /* ctx->word contains characters seen prior to ( or {. 4973 * Typically it's empty, but for function defs, 4974 * it contains function name (without '()'). */ 4975#if BB_MMU 4976# define as_string NULL 4977#else 4978 char *as_string = NULL; 4979#endif 4980 struct pipe *pipe_list; 4981 int heredoc_cnt = 0; 4982 int endch; 4983 struct command *command = ctx->command; 4984 4985 debug_printf_parse("parse_group entered\n"); 4986#if ENABLE_HUSH_FUNCTIONS 4987 if (ch == '(' && !ctx->word.has_quoted_part) { 4988 if (ctx->word.length) 4989 if (done_word(ctx)) 4990 return -1; 4991 if (!command->argv) 4992 goto skip; /* (... */ 4993 if (command->argv[1]) { /* word word ... (... */ 4994 syntax_error_unexpected_ch('('); 4995 return -1; 4996 } 4997 /* it is "word(..." or "word (..." */ 4998 do 4999 ch = i_getch(input); 5000 while (ch == ' ' || ch == '\t'); 5001 if (ch != ')') { 5002 syntax_error_unexpected_ch(ch); 5003 return -1; 5004 } 5005 nommu_addchr(&ctx->as_string, ch); 5006 do 5007 ch = i_getch(input); 5008 while (ch == ' ' || ch == '\t' || ch == '\n'); 5009 if (ch != '{' && ch != '(') { 5010 syntax_error_unexpected_ch(ch); 5011 return -1; 5012 } 5013//bash allows functions named "123", "..", "return"! 5014// if (endofname(command->argv[0])[0] != '\0') { 5015// syntax_error("bad function name"); 5016// return -1; 5017// } 5018 nommu_addchr(&ctx->as_string, ch); 5019 command->cmd_type = CMD_FUNCDEF; 5020 goto skip; 5021 } 5022#endif 5023 5024#if 0 /* Prevented by caller */ 5025 if (command->argv /* word [word]{... */ 5026 || ctx->word.length /* word{... */ 5027 || ctx->word.has_quoted_part /* ""{... */ 5028 ) { 5029 syntax_error(NULL); 5030 debug_printf_parse("parse_group return -1: " 5031 "syntax error, groups and arglists don't mix\n"); 5032 return -1; 5033 } 5034#endif 5035 5036#ifndef __U_BOOT__ 5037 IF_HUSH_FUNCTIONS(skip:) 5038#endif /* !__U_BOOT__ */ 5039 5040 endch = '}'; 5041 if (ch == '(') { 5042 endch = ')'; 5043#ifndef __U_BOOT__ 5044 IF_HUSH_FUNCTIONS(if (command->cmd_type != CMD_FUNCDEF)) 5045 command->cmd_type = CMD_SUBSHELL; 5046#endif /* !__U_BOOT__ */ 5047 } else { 5048 /* bash does not allow "{echo...", requires whitespace */ 5049 ch = i_peek(input); 5050 if (ch != ' ' && ch != '\t' && ch != '\n' 5051 && ch != '(' /* but "{(..." is allowed (without whitespace) */ 5052 ) { 5053 syntax_error_unexpected_ch(ch); 5054 return -1; 5055 } 5056 if (ch != '(') { 5057 ch = i_getch(input); 5058 nommu_addchr(&ctx->as_string, ch); 5059 } 5060 } 5061 5062 debug_printf_heredoc("calling parse_stream, heredoc_cnt:%d\n", heredoc_cnt); 5063 pipe_list = parse_stream(&as_string, &heredoc_cnt, input, endch); 5064 debug_printf_heredoc("parse_stream returned: heredoc_cnt:%d\n", heredoc_cnt); 5065#if !BB_MMU 5066 if (as_string) 5067 o_addstr(&ctx->as_string, as_string); 5068#endif 5069 5070 /* empty ()/{} or parse error? */ 5071 if (!pipe_list || pipe_list == ERR_PTR) { 5072 /* parse_stream already emitted error msg */ 5073 if (!BB_MMU) 5074 free(as_string); 5075 debug_printf_parse("parse_group return -1: " 5076 "parse_stream returned %p\n", pipe_list); 5077 return -1; 5078 } 5079#if !BB_MMU 5080 as_string[strlen(as_string) - 1] = '\0'; /* plink ')' or '}' */ 5081 command->group_as_string = as_string; 5082 debug_printf_parse("end of group, remembering as:'%s'\n", 5083 command->group_as_string); 5084#endif 5085 5086#if ENABLE_HUSH_FUNCTIONS 5087 /* Convert "f() (cmds)" to "f() {(cmds)}" */ 5088 if (command->cmd_type == CMD_FUNCDEF && endch == ')') { 5089 struct command *cmd2; 5090 5091 cmd2 = xzalloc(sizeof(*cmd2)); 5092 cmd2->cmd_type = CMD_SUBSHELL; 5093 cmd2->group = pipe_list; 5094# if !BB_MMU 5095//UNTESTED! 5096 cmd2->group_as_string = command->group_as_string; 5097 command->group_as_string = xasprintf("(%s)", command->group_as_string); 5098# endif 5099 5100 pipe_list = new_pipe(); 5101 pipe_list->cmds = cmd2; 5102 pipe_list->num_cmds = 1; 5103 } 5104#endif 5105 5106 command->group = pipe_list; 5107 5108 debug_printf_parse("parse_group return %d\n", heredoc_cnt); 5109 return heredoc_cnt; 5110 /* command remains "open", available for possible redirects */ 5111#undef as_string 5112} 5113 5114#ifndef __U_BOOT__ 5115#if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS 5116/* Subroutines for copying $(...) and `...` things */ 5117/* '...' */ 5118static int add_till_single_quote(o_string *dest, struct in_str *input) 5119{ 5120 while (1) { 5121 int ch = i_getch(input); 5122 if (ch == EOF) { 5123 syntax_error_unterm_ch('\''); 5124 return 0; 5125 } 5126 if (ch == '\'') 5127 return 1; 5128 o_addchr(dest, ch); 5129 } 5130} 5131static int add_till_single_quote_dquoted(o_string *dest, struct in_str *input) 5132{ 5133 while (1) { 5134 int ch = i_getch(input); 5135 if (ch == EOF) { 5136 syntax_error_unterm_ch('\''); 5137 return 0; 5138 } 5139 if (ch == '\'') 5140 return 1; 5141 o_addqchr(dest, ch); 5142 } 5143} 5144 5145/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ 5146static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); 5147static int add_till_double_quote(o_string *dest, struct in_str *input) 5148{ 5149 while (1) { 5150 int ch = i_getch(input); 5151 if (ch == EOF) { 5152 syntax_error_unterm_ch('"'); 5153 return 0; 5154 } 5155 if (ch == '"') 5156 return 1; 5157 if (ch == '\\') { /* \x. Copy both chars. */ 5158 o_addchr(dest, ch); 5159 ch = i_getch(input); 5160 } 5161 o_addchr(dest, ch); 5162 if (ch == '`') { 5163 if (!add_till_backquote(dest, input, /*in_dquote:*/ 1)) 5164 return 0; 5165 o_addchr(dest, ch); 5166 continue; 5167 } 5168 //if (ch == '$') ... 5169 } 5170} 5171 5172/* Process `cmd` - copy contents until "`" is seen. Complicated by 5173 * \` quoting. 5174 * "Within the backquoted style of command substitution, backslash 5175 * shall retain its literal meaning, except when followed by: '$', '`', or '\'. 5176 * The search for the matching backquote shall be satisfied by the first 5177 * backquote found without a preceding backslash; during this search, 5178 * if a non-escaped backquote is encountered within a shell comment, 5179 * a here-document, an embedded command substitution of the $(command) 5180 * form, or a quoted string, undefined results occur. A single-quoted 5181 * or double-quoted string that begins, but does not end, within the 5182 * "`...`" sequence produces undefined results." 5183 * Example Output 5184 * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST 5185 */ 5186static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote) 5187{ 5188 while (1) { 5189 int ch = i_getch(input); 5190 if (ch == '`') 5191 return 1; 5192 if (ch == '\\') { 5193 /* \x. Copy both unless it is \`, \$, \\ and maybe \" */ 5194 ch = i_getch(input); 5195 if (ch != '`' 5196 && ch != '$' 5197 && ch != '\\' 5198 && (!in_dquote || ch != '"') 5199 ) { 5200 o_addchr(dest, '\\'); 5201 } 5202 } 5203 if (ch == EOF) { 5204 syntax_error_unterm_ch('`'); 5205 return 0; 5206 } 5207 o_addchr(dest, ch); 5208 } 5209} 5210/* Process $(cmd) - copy contents until ")" is seen. Complicated by 5211 * quoting and nested ()s. 5212 * "With the $(command) style of command substitution, all characters 5213 * following the open parenthesis to the matching closing parenthesis 5214 * constitute the command. Any valid shell script can be used for command, 5215 * except a script consisting solely of redirections which produces 5216 * unspecified results." 5217 * Example Output 5218 * echo $(echo '(TEST)' BEST) (TEST) BEST 5219 * echo $(echo 'TEST)' BEST) TEST) BEST 5220 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST 5221 * 5222 * Also adapted to eat ${var%...} and $((...)) constructs, since ... part 5223 * can contain arbitrary constructs, just like $(cmd). 5224 * In bash compat mode, it needs to also be able to stop on ':' or '/' 5225 * for ${var:N[:M]} and ${var/P[/R]} parsing. 5226 */ 5227#define DOUBLE_CLOSE_CHAR_FLAG 0x80 5228static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsigned end_ch) 5229{ 5230 int ch; 5231 char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG; 5232# if BASH_SUBSTR || BASH_PATTERN_SUBST 5233 char end_char2 = end_ch >> 8; 5234# endif 5235 end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1); 5236 5237# if ENABLE_HUSH_INTERACTIVE 5238 G.promptmode = 1; /* PS2 */ 5239# endif 5240 debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode); 5241 5242 while (1) { 5243 ch = i_getch(input); 5244 if (ch == EOF) { 5245 syntax_error_unterm_ch(end_ch); 5246 return 0; 5247 } 5248 if (ch == end_ch 5249# if BASH_SUBSTR || BASH_PATTERN_SUBST 5250 || ch == end_char2 5251# endif 5252 ) { 5253 if (!dbl) 5254 break; 5255 /* we look for closing )) of $((EXPR)) */ 5256 if (i_peek_and_eat_bkslash_nl(input) == end_ch) { 5257 i_getch(input); /* eat second ')' */ 5258 break; 5259 } 5260 } 5261 o_addchr(dest, ch); 5262 //bb_error_msg("%s:o_addchr('%c')", __func__, ch); 5263 if (ch == '(' || ch == '{') { 5264 ch = (ch == '(' ? ')' : '}'); 5265 if (!add_till_closing_bracket(dest, input, ch)) 5266 return 0; 5267 o_addchr(dest, ch); 5268 continue; 5269 } 5270 if (ch == '\'') { 5271 if (!add_till_single_quote(dest, input)) 5272 return 0; 5273 o_addchr(dest, ch); 5274 continue; 5275 } 5276 if (ch == '"') { 5277 if (!add_till_double_quote(dest, input)) 5278 return 0; 5279 o_addchr(dest, ch); 5280 continue; 5281 } 5282 if (ch == '`') { 5283 if (!add_till_backquote(dest, input, /*in_dquote:*/ 0)) 5284 return 0; 5285 o_addchr(dest, ch); 5286 continue; 5287 } 5288 if (ch == '\\') { 5289 /* \x. Copy verbatim. Important for \(, \) */ 5290 ch = i_getch(input); 5291 if (ch == EOF) { 5292 syntax_error_unterm_ch(end_ch); 5293 return 0; 5294 } 5295# if 0 5296 if (ch == '\n') { 5297 /* "backslash+newline", ignore both */ 5298 o_delchr(dest); /* undo insertion of '\' */ 5299 continue; 5300 } 5301# endif 5302 o_addchr(dest, ch); 5303 //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch); 5304 continue; 5305 } 5306 } 5307 debug_printf_parse("%s return '%s' ch:'%c'\n", __func__, dest->data, ch); 5308 return ch; 5309} 5310#endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */ 5311 5312#if BASH_DOLLAR_SQUOTE 5313/* Return code: 1 for "found and parsed", 0 for "seen something else" */ 5314# if BB_MMU 5315#define parse_dollar_squote(as_string, dest, input) \ 5316 parse_dollar_squote(dest, input) 5317#define as_string NULL 5318# endif 5319static int parse_dollar_squote(o_string *as_string, o_string *dest, struct in_str *input) 5320{ 5321 int start; 5322 int ch = i_peek_and_eat_bkslash_nl(input); /* first character after the $ */ 5323 debug_printf_parse("parse_dollar_squote entered: ch='%c'\n", ch); 5324 if (ch != '\'') 5325 return 0; 5326 5327 dest->has_quoted_part = 1; 5328 start = dest->length; 5329 5330 ch = i_getch(input); /* eat ' */ 5331 nommu_addchr(as_string, ch); 5332 while (1) { 5333 ch = i_getch(input); 5334 nommu_addchr(as_string, ch); 5335 if (ch == EOF) { 5336 syntax_error_unterm_ch('\''); 5337 return 0; 5338 } 5339 if (ch == '\'') 5340 break; 5341 if (ch == SPECIAL_VAR_SYMBOL) { 5342 /* Convert raw ^C to corresponding special variable reference */ 5343 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5344 o_addchr(dest, SPECIAL_VAR_QUOTED_SVS); 5345 /* will addchr() another SPECIAL_VAR_SYMBOL (see after the if() block) */ 5346 } else if (ch == '\\') { 5347 static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567"; 5348 5349 ch = i_getch(input); 5350 nommu_addchr(as_string, ch); 5351 if (strchr(C_escapes, ch)) { 5352 char buf[4]; 5353 char *p = buf; 5354 int cnt = 2; 5355 5356 buf[0] = ch; 5357 if ((unsigned char)(ch - '0') <= 7) { /* \ooo */ 5358 do { 5359 ch = i_peek(input); 5360 if ((unsigned char)(ch - '0') > 7) 5361 break; 5362 *++p = ch = i_getch(input); 5363 nommu_addchr(as_string, ch); 5364 } while (--cnt != 0); 5365 } else if (ch == 'x') { /* \xHH */ 5366 do { 5367 ch = i_peek(input); 5368 if (!isxdigit(ch)) 5369 break; 5370 *++p = ch = i_getch(input); 5371 nommu_addchr(as_string, ch); 5372 } while (--cnt != 0); 5373 if (cnt == 2) { /* \x but next char is "bad" */ 5374 ch = 'x'; 5375 goto unrecognized; 5376 } 5377 } /* else simple seq like \\ or \t */ 5378 *++p = '\0'; 5379 p = buf; 5380 ch = bb_process_escape_sequence((void*)&p); 5381 //bb_error_msg("buf:'%s' ch:%x", buf, ch); 5382 if (ch == '\0') 5383 continue; /* bash compat: $'...\0...' emits nothing */ 5384 } else { /* unrecognized "\z": encode both chars unless ' or " */ 5385 if (ch != '\'' && ch != '"') { 5386 unrecognized: 5387 o_addqchr(dest, '\\'); 5388 } 5389 } 5390 } /* if (\...) */ 5391 o_addqchr(dest, ch); 5392 } 5393 5394 if (dest->length == start) { 5395 /* $'', $'\0', $'\000\x00' and the like */ 5396 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5397 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5398 } 5399 5400 return 1; 5401# undef as_string 5402} 5403#else 5404# define parse_dollar_squote(as_string, dest, input) 0 5405#endif /* BASH_DOLLAR_SQUOTE */ 5406#endif /* !__U_BOOT__ */ 5407 5408/* Return code: 0 for OK, 1 for syntax error */ 5409#if BB_MMU 5410#define parse_dollar(as_string, dest, input, quote_mask) \ 5411 parse_dollar(dest, input, quote_mask) 5412#define as_string NULL 5413#endif 5414static int parse_dollar(o_string *as_string, 5415 o_string *dest, 5416 struct in_str *input, unsigned char quote_mask) 5417{ 5418 int ch = i_peek_and_eat_bkslash_nl(input); /* first character after the $ */ 5419 5420 debug_printf_parse("parse_dollar entered: ch='%c' quote_mask:0x%x\n", ch, quote_mask); 5421 if (isalpha(ch)) { 5422 make_var: 5423 ch = i_getch(input); 5424 nommu_addchr(as_string, ch); 5425 /*make_var1:*/ 5426 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5427 while (1) { 5428 debug_printf_parse(": '%c'\n", ch); 5429 o_addchr(dest, ch | quote_mask); 5430 quote_mask = 0; 5431 ch = i_peek_and_eat_bkslash_nl(input); 5432 if (!isalnum(ch) && ch != '_') { 5433 /* End of variable name reached */ 5434 break; 5435 } 5436 ch = i_getch(input); 5437 nommu_addchr(as_string, ch); 5438 } 5439 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5440 } else if (isdigit(ch)) { 5441 make_one_char_var: 5442 ch = i_getch(input); 5443 nommu_addchr(as_string, ch); 5444 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5445 debug_printf_parse(": '%c'\n", ch); 5446 o_addchr(dest, ch | quote_mask); 5447 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5448 } else switch (ch) { 5449#ifndef __U_BOOT__ 5450 case '$': /* pid */ 5451 case '!': /* last bg pid */ 5452#endif /* !__U_BOOT__ */ 5453 case '?': /* last exit code */ 5454 case '#': /* number of args */ 5455 case '*': /* args */ 5456 case '@': /* args */ 5457 case '-': /* $- option flags set by set builtin or shell options (-i etc) */ 5458 goto make_one_char_var; 5459 case '{': { 5460 char len_single_ch; 5461 5462 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5463 5464 ch = i_getch(input); /* eat '{' */ 5465 nommu_addchr(as_string, ch); 5466 5467 ch = i_getch_and_eat_bkslash_nl(input); /* first char after '{' */ 5468 /* It should be ${?}, or ${#var}, 5469 * or even ${?+subst} - operator acting on a special variable, 5470 * or the beginning of variable name. 5471 */ 5472 if (ch == EOF 5473 || (!strchr(_SPECIAL_VARS_STR, ch) && !isalnum(ch)) /* not one of those */ 5474 ) { 5475 bad_dollar_syntax: 5476 syntax_error_unterm_str("${name}"); 5477 debug_printf_parse("parse_dollar return 0: unterminated ${name}\n"); 5478 return 0; 5479 } 5480 nommu_addchr(as_string, ch); 5481 len_single_ch = ch; 5482 ch |= quote_mask; 5483 5484 /* It's possible to just call add_till_closing_bracket() at this point. 5485 * However, this regresses some of our testsuite cases 5486 * which check invalid constructs like ${%}. 5487 * Oh well... let's check that the var name part is fine... */ 5488 5489 if (isdigit(len_single_ch) 5490 || (len_single_ch == '#' && isdigit(i_peek_and_eat_bkslash_nl(input))) 5491 ) { 5492 /* Execution engine uses plain xatoi_positive() 5493 * to interpret ${NNN} and {#NNN}, 5494 * check syntax here in the parser. 5495 * (bash does not support expressions in ${#NN}, 5496 * e.g. ${#$var} and {#1:+WORD} are not supported). 5497 */ 5498 unsigned cnt = 9; /* max 9 digits for ${NN} and 8 for {#NN} */ 5499 while (1) { 5500 o_addchr(dest, ch); 5501 debug_printf_parse(": '%c'\n", ch); 5502 ch = i_getch_and_eat_bkslash_nl(input); 5503 nommu_addchr(as_string, ch); 5504 if (ch == '}') 5505 break; 5506 if (--cnt == 0) 5507 goto bad_dollar_syntax; 5508 if (len_single_ch != '#' && strchr(VAR_SUBST_OPS, ch)) 5509 /* ${NN<op>...} is valid */ 5510 goto eat_until_closing; 5511 if (!isdigit(ch)) 5512 goto bad_dollar_syntax; 5513 } 5514 } else 5515 while (1) { 5516 unsigned pos; 5517 5518 o_addchr(dest, ch); 5519 debug_printf_parse(": '%c'\n", ch); 5520 5521 ch = i_getch(input); 5522 nommu_addchr(as_string, ch); 5523 if (ch == '}') 5524 break; 5525#ifndef __U_BOOT__ 5526 if (!isalnum(ch) && ch != '_') { 5527#else /* __U_BOOT__ */ 5528 /* 5529 * In several places in U-Boot, we use variable like 5530 * foo# (e.g. serial#), particularly in env. 5531 * So, we need to authorize # to appear inside 5532 * variable name and then expand this variable. 5533 * NOTE Having # in variable name is not permitted in 5534 * upstream hush but expansion will be done (even though 5535 * the result will be empty). 5536 */ 5537 if (!isalnum(ch) && ch != '_' && ch != '#') { 5538#endif /* __U_BOOT__ */ 5539 unsigned end_ch; 5540#ifndef __U_BOOT__ 5541 unsigned char last_ch; 5542#endif /* !__U_BOOT__ */ 5543 /* handle parameter expansions 5544 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02 5545 */ 5546 if (!strchr(VAR_SUBST_OPS, ch)) { /* ${var<bad_char>... */ 5547 if (len_single_ch != '#' 5548 /*|| !strchr(SPECIAL_VARS_STR, ch) - disallow errors like ${#+} ? */ 5549 || i_peek(input) != '}' 5550 ) { 5551 goto bad_dollar_syntax; 5552 } 5553 /* else: it's "length of C" ${#C} op, 5554 * where C is a single char 5555 * special var name, e.g. ${#!}. 5556 */ 5557 } 5558 eat_until_closing: 5559 /* Eat everything until closing '}' (or ':') */ 5560 end_ch = '}'; 5561#ifndef __U_BOOT__ 5562 if (BASH_SUBSTR 5563 && ch == ':' 5564 && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input)) 5565 ) { 5566 /* It's ${var:N[:M]} thing */ 5567 end_ch = '}' * 0x100 + ':'; 5568 } 5569 if (BASH_PATTERN_SUBST 5570 && ch == '/' 5571 ) { 5572 /* It's ${var/[/]pattern[/repl]} thing */ 5573 if (i_peek(input) == '/') { /* ${var//pattern[/repl]}? */ 5574 i_getch(input); 5575 nommu_addchr(as_string, '/'); 5576 ch = '\\'; 5577 } 5578 end_ch = '}' * 0x100 + '/'; 5579 } 5580#endif /* !__U_BOOT__ */ 5581 o_addchr(dest, ch); 5582 /* The pattern can't be empty. 5583 * IOW: if the first char after "${v//" is a slash, 5584 * it does not terminate the pattern - it's the first char of the pattern: 5585 * v=/dev/ram; echo ${v////-} prints -dev-ram (pattern is "/") 5586 * v=/dev/ram; echo ${v///r/-} prints /dev-am (pattern is "/r") 5587 */ 5588 if (i_peek(input) == '/') { 5589 o_addchr(dest, i_getch(input)); 5590 } 5591#ifndef __U_BOOT__ 5592 again: 5593#endif /* !__U_BOOT__ */ 5594 if (!BB_MMU) 5595 pos = dest->length; 5596#if ENABLE_HUSH_DOLLAR_OPS 5597#ifndef __U_BOOT__ 5598 last_ch = add_till_closing_bracket(dest, input, end_ch); 5599 if (last_ch == 0) /* error? */ 5600 return 0; 5601#endif /* !__U_BOOT__ */ 5602#else 5603# error Simple code to only allow ${var} is not implemented 5604#endif 5605 if (as_string) { 5606 o_addstr(as_string, dest->data + pos); 5607#ifndef __U_BOOT__ 5608 o_addchr(as_string, last_ch); 5609#endif /* !__U_BOOT__ */ 5610 } 5611 5612#ifndef __U_BOOT__ 5613 if ((BASH_SUBSTR || BASH_PATTERN_SUBST) 5614 && (end_ch & 0xff00) 5615 ) { 5616 /* close the first block: */ 5617 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5618 /* while parsing N from ${var:N[:M]} 5619 * or pattern from ${var/[/]pattern[/repl]} */ 5620 if ((end_ch & 0xff) == last_ch) { 5621 /* got ':' or '/'- parse the rest */ 5622 end_ch = '}'; 5623 goto again; 5624 } 5625 /* got '}' */ 5626 if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') { 5627 /* it's ${var:N} - emulate :999999999 */ 5628 o_addstr(dest, "999999999"); 5629 } /* else: it's ${var/[/]pattern} */ 5630 } 5631#endif /* !__U_BOOT__ */ 5632 break; 5633 } 5634 len_single_ch = 0; /* it can't be ${#C} op */ 5635 } 5636 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5637 break; 5638 } 5639#if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_TICK 5640 case '(': { 5641 unsigned pos; 5642 5643 ch = i_getch(input); 5644 nommu_addchr(as_string, ch); 5645# if ENABLE_FEATURE_SH_MATH 5646 if (i_peek_and_eat_bkslash_nl(input) == '(') { 5647 ch = i_getch(input); 5648 nommu_addchr(as_string, ch); 5649 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5650 o_addchr(dest, quote_mask | '+'); 5651 if (!BB_MMU) 5652 pos = dest->length; 5653 if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG)) 5654 return 0; /* error */ 5655 if (as_string) { 5656 o_addstr(as_string, dest->data + pos); 5657 o_addchr(as_string, ')'); 5658 o_addchr(as_string, ')'); 5659 } 5660 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5661 break; 5662 } 5663# endif 5664# if ENABLE_HUSH_TICK 5665 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5666 o_addchr(dest, quote_mask | '`'); 5667 if (!BB_MMU) 5668 pos = dest->length; 5669 if (!add_till_closing_bracket(dest, input, ')')) 5670 return 0; /* error */ 5671 if (as_string) { 5672 o_addstr(as_string, dest->data + pos); 5673 o_addchr(as_string, ')'); 5674 } 5675 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5676# endif 5677 break; 5678 } 5679#endif 5680 case '_': 5681 goto make_var; 5682#if 0 5683 /* TODO: $_: */ 5684 /* $_ Shell or shell script name; or last argument of last command 5685 * (if last command wasn't a pipe; if it was, bash sets $_ to ""); 5686 * but in command's env, set to full pathname used to invoke it */ 5687 ch = i_getch(input); 5688 nommu_addchr(as_string, ch); 5689 ch = i_peek_and_eat_bkslash_nl(input); 5690 if (isalnum(ch)) { /* it's $_name or $_123 */ 5691 ch = '_'; 5692 goto make_var1; 5693 } 5694 /* else: it's $_ */ 5695#endif 5696 default: 5697 o_addQchr(dest, '$'); 5698 } 5699 debug_printf_parse("parse_dollar return 1 (ok)\n"); 5700 return 1; 5701#undef as_string 5702} 5703 5704#if BB_MMU 5705#define encode_string(as_string, dest, input, dquote_end) \ 5706 encode_string(dest, input, dquote_end) 5707#define as_string NULL 5708#endif 5709static int encode_string(o_string *as_string, 5710 o_string *dest, 5711 struct in_str *input, 5712 int dquote_end) 5713{ 5714 int ch; 5715 int next; 5716 5717 again: 5718 ch = i_getch(input); 5719 if (ch != EOF) 5720 nommu_addchr(as_string, ch); 5721 if (ch == dquote_end) { /* may be only '"' or EOF */ 5722 debug_printf_parse("encode_string return 1 (ok)\n"); 5723 return 1; 5724 } 5725 /* note: can't move it above ch == dquote_end check! */ 5726 if (ch == EOF) { 5727 syntax_error_unterm_ch('"'); 5728 return 0; /* error */ 5729 } 5730 next = '\0'; 5731 if (ch != '\n') { 5732 next = i_peek(input); 5733 } 5734 debug_printf_parse("\" ch=%c (%d) escape=%d\n", 5735 ch, ch, !!(dest->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); 5736 if (ch == '\\') { 5737 if (next == EOF) { 5738 /* Testcase: in interactive shell a file with 5739 * echo "unterminated string\<eof> 5740 * is sourced. 5741 */ 5742 syntax_error_unterm_ch('"'); 5743 return 0; /* error */ 5744 } 5745 /* bash: 5746 * "The backslash retains its special meaning [in "..."] 5747 * only when followed by one of the following characters: 5748 * $, `, ", \, or <newline>. A double quote may be quoted 5749 * within double quotes by preceding it with a backslash." 5750 * NB: in (unquoted) heredoc, above does not apply to ", 5751 * therefore we check for it by "next == dquote_end" cond. 5752 */ 5753 if (next == dquote_end || strchr("$`\\\n", next)) { 5754 ch = i_getch(input); /* eat next */ 5755 if (ch == '\n') 5756 goto again; /* skip \<newline> */ 5757 } /* else: ch remains == '\\', and we double it below: */ 5758 o_addqchr(dest, ch); /* \c if c is a glob char, else just c */ 5759 nommu_addchr(as_string, ch); 5760 goto again; 5761 } 5762 if (ch == '$') { 5763 //if (parse_dollar_squote(as_string, dest, input)) 5764 // goto again; 5765 if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) { 5766 debug_printf_parse("encode_string return 0: " 5767 "parse_dollar returned 0 (error)\n"); 5768 return 0; 5769 } 5770 goto again; 5771 } 5772#if ENABLE_HUSH_TICK 5773 if (ch == '`') { 5774 //unsigned pos = dest->length; 5775 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5776 o_addchr(dest, 0x80 | '`'); 5777 if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"')) 5778 return 0; /* error */ 5779 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5780 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); 5781 goto again; 5782 } 5783#endif 5784 o_addQchr(dest, ch); 5785 if (ch == SPECIAL_VAR_SYMBOL) { 5786 /* Convert "^C" to corresponding special variable reference */ 5787 o_addchr(dest, SPECIAL_VAR_QUOTED_SVS); 5788 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5789 } 5790 goto again; 5791#undef as_string 5792} 5793 5794/* 5795 * Scan input until EOF or end_trigger char. 5796 * Return a list of pipes to execute, or NULL on EOF 5797 * or if end_trigger character is met. 5798 * On syntax error, exit if shell is not interactive, 5799 * reset parsing machinery and start parsing anew, 5800 * or return ERR_PTR. 5801 */ 5802static struct pipe *parse_stream(char **pstring, 5803 int *heredoc_cnt_ptr, 5804 struct in_str *input, 5805 int end_trigger) 5806{ 5807 struct parse_context ctx; 5808 int heredoc_cnt; 5809 5810 /* Single-quote triggers a bypass of the main loop until its mate is 5811 * found. When recursing, quote state is passed in via ctx.word.o_expflags. 5812 */ 5813 debug_printf_parse("parse_stream entered, end_trigger='%c'\n", 5814 end_trigger ? end_trigger : 'X'); 5815 debug_enter(); 5816 5817 initialize_context(&ctx); 5818 5819 /* If very first arg is "" or '', ctx.word.data may end up NULL. 5820 * Preventing this: 5821 */ 5822 ctx.word.data = xzalloc(1); /* start as "", not as NULL */ 5823 5824 /* We used to separate words on $IFS here. This was wrong. 5825 * $IFS is used only for word splitting when $var is expanded, 5826 * here we should use blank chars as separators, not $IFS 5827 */ 5828 5829 heredoc_cnt = 0; 5830 while (1) { 5831 const char *is_blank; 5832 const char *is_special; 5833 int ch; 5834 int next; 5835#ifndef __U_BOOT__ 5836 int redir_fd; 5837 redir_type redir_style; 5838#endif /* !__U_BOOT__ */ 5839 5840 ch = i_getch(input); 5841 debug_printf_parse(": ch=%c (%d) escape=%d\n", 5842 ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); 5843 if (ch == EOF) { 5844 struct pipe *pi; 5845 5846 if (heredoc_cnt) { 5847 syntax_error_unterm_str("here document"); 5848 goto parse_error_exitcode1; 5849 } 5850 if (end_trigger == ')') { 5851 syntax_error_unterm_ch('('); 5852 goto parse_error_exitcode1; 5853 } 5854 if (end_trigger == '}') { 5855 syntax_error_unterm_ch('{'); 5856 goto parse_error_exitcode1; 5857 } 5858 5859 if (done_word(&ctx)) { 5860 goto parse_error_exitcode1; 5861 } 5862 o_free_and_set_NULL(&ctx.word); 5863 done_pipe(&ctx, PIPE_SEQ); 5864 5865 /* Do we sit inside of any if's, loops or case's? */ 5866 if (HAS_KEYWORDS 5867 IF_HAS_KEYWORDS(&& (ctx.ctx_res_w != RES_NONE || ctx.old_flag != 0)) 5868 ) { 5869 syntax_error_unterm_str("compound statement"); 5870 goto parse_error_exitcode1; 5871 } 5872 5873 pi = ctx.list_head; 5874 /* If we got nothing... */ 5875 /* (this makes bare "&" cmd a no-op. 5876 * bash says: "syntax error near unexpected token '&'") */ 5877 if (pi->num_cmds == 0 5878 IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE) 5879 ) { 5880 free_pipe_list(pi); 5881 pi = NULL; 5882 } 5883#if !BB_MMU 5884 debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data); 5885 if (pstring) 5886 *pstring = ctx.as_string.data; 5887 else 5888 o_free(&ctx.as_string); 5889#endif 5890 // heredoc_cnt must be 0 here anyway 5891 //if (heredoc_cnt_ptr) 5892 // *heredoc_cnt_ptr = heredoc_cnt; 5893 debug_leave(); 5894 debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt); 5895 debug_printf_parse("parse_stream return %p: EOF\n", pi); 5896 return pi; 5897 } 5898 5899 /* Handle "'" and "\" first, as they won't play nice with 5900 * i_peek_and_eat_bkslash_nl() anyway: 5901 * echo z\\ 5902 * and 5903 * echo '\ 5904 * ' 5905 * would break. 5906 */ 5907 if (ch == '\\') { 5908 ch = i_getch(input); 5909 if (ch == '\n') 5910 continue; /* drop \<newline>, get next char */ 5911 nommu_addchr(&ctx.as_string, '\\'); 5912 if (ch == SPECIAL_VAR_SYMBOL) { 5913 nommu_addchr(&ctx.as_string, ch); 5914 /* Convert \^C to corresponding special variable reference */ 5915 goto case_SPECIAL_VAR_SYMBOL; 5916 } 5917 o_addchr(&ctx.word, '\\'); 5918 if (ch == EOF) { 5919 /* Testcase: eval 'echo Ok\' */ 5920 /* bash-4.3.43 was removing backslash, 5921 * but 4.4.19 retains it, most other shells too 5922 */ 5923 continue; /* get next char */ 5924 } 5925 /* Example: echo Hello \2>file 5926 * we need to know that word 2 is quoted 5927 */ 5928 ctx.word.has_quoted_part = 1; 5929 nommu_addchr(&ctx.as_string, ch); 5930 o_addchr(&ctx.word, ch); 5931 continue; /* get next char */ 5932 } 5933 nommu_addchr(&ctx.as_string, ch); 5934 if (ch == '\'') { 5935 ctx.word.has_quoted_part = 1; 5936 next = i_getch(input); 5937#ifndef __U_BOOT__ 5938 if (next == '\'' && !ctx.pending_redirect) 5939 goto insert_empty_quoted_str_marker; 5940#endif /* !__U_BOOT__ */ 5941 5942 ch = next; 5943 while (1) { 5944 if (ch == EOF) { 5945 syntax_error_unterm_ch('\''); 5946 goto parse_error_exitcode1; 5947 } 5948 nommu_addchr(&ctx.as_string, ch); 5949 if (ch == '\'') 5950 break; 5951 if (ch == SPECIAL_VAR_SYMBOL) { 5952 /* Convert raw ^C to corresponding special variable reference */ 5953 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); 5954 o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS); 5955 } 5956 o_addqchr(&ctx.word, ch); 5957 ch = i_getch(input); 5958 } 5959 continue; /* get next char */ 5960 } 5961 5962 next = '\0'; 5963 if (ch != '\n') 5964 next = i_peek_and_eat_bkslash_nl(input); 5965 5966 is_special = "{}<>&|();#" /* special outside of "str" */ 5967#ifndef __U_BOOT__ 5968 "$\"" IF_HUSH_TICK("`") /* always special */ 5969#else /* __U_BOOT__ */ 5970 "$\"" 5971#endif /* __U_BOOT__ */ 5972 SPECIAL_VAR_SYMBOL_STR; 5973#if defined(CMD_TEST2_SINGLEWORD_NOGLOB) 5974 if (ctx.command->cmd_type == CMD_TEST2_SINGLEWORD_NOGLOB) { 5975 /* In [[ ]], {}<>&|() are not special */ 5976 is_special += 8; 5977 } else 5978#endif 5979 /* Are { and } special here? */ 5980 if (ctx.command->argv /* word [word]{... - non-special */ 5981 || ctx.word.length /* word{... - non-special */ 5982 || ctx.word.has_quoted_part /* ""{... - non-special */ 5983 || (next != ';' /* }; - special */ 5984 && next != ')' /* }) - special */ 5985 && next != '(' /* {( - special */ 5986 && next != '&' /* }& and }&& ... - special */ 5987 && next != '|' /* }|| ... - special */ 5988 && !strchr(defifs, next) /* {word - non-special */ 5989 ) 5990 ) { 5991 /* They are not special, skip "{}" */ 5992 is_special += 2; 5993 } 5994 is_special = strchr(is_special, ch); 5995 is_blank = strchr(defifs, ch); 5996 5997 if (!is_special && !is_blank) { /* ordinary char */ 5998 ordinary_char: 5999 o_addQchr(&ctx.word, ch); 6000 if ((ctx.is_assignment == MAYBE_ASSIGNMENT 6001 || ctx.is_assignment == WORD_IS_KEYWORD) 6002 && ch == '=' 6003 && endofname(ctx.word.data)[0] == '=' 6004 ) { 6005 ctx.is_assignment = DEFINITELY_ASSIGNMENT; 6006 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]); 6007 } 6008 continue; 6009 } 6010 6011 if (is_blank) { 6012#if ENABLE_HUSH_LINENO_VAR 6013/* Case: 6014 * "while ...; do<whitespace><newline> 6015 * cmd ..." 6016 * would think that "cmd" starts in <whitespace> - 6017 * i.e., at the previous line. 6018 * We need to skip all whitespace before newlines. 6019 */ 6020 while (ch != '\n') { 6021 next = i_peek(input); 6022 if (next != ' ' && next != '\t' && next != '\n') 6023 break; /* next char is not ws */ 6024 ch = i_getch(input); 6025 } 6026 /* ch == last eaten whitespace char */ 6027#endif 6028 if (done_word(&ctx)) { 6029 goto parse_error_exitcode1; 6030 } 6031 if (ch == '\n') { 6032 /* Is this a case when newline is simply ignored? 6033 * Some examples: 6034 * "cmd | <newline> cmd ..." 6035 * "case ... in <newline> word) ..." 6036 */ 6037 if (IS_NULL_CMD(ctx.command) 6038 && ctx.word.length == 0 6039 && !ctx.word.has_quoted_part 6040 && heredoc_cnt == 0 6041 ) { 6042 /* This newline can be ignored. But... 6043 * Without check #1, interactive shell 6044 * ignores even bare <newline>, 6045 * and shows the continuation prompt: 6046 * ps1_prompt$ <enter> 6047 * ps2> _ <=== wrong, should be ps1 6048 * Without check #2, "cmd & <newline>" 6049 * is similarly mistreated. 6050 * (BTW, this makes "cmd & cmd" 6051 * and "cmd && cmd" non-orthogonal. 6052 * Really, ask yourself, why 6053 * "cmd && <newline>" doesn't start 6054 * cmd but waits for more input? 6055 * The only reason is that it might be 6056 * a "cmd1 && <nl> cmd2 &" construct, 6057 * cmd1 may need to run in BG). 6058 */ 6059 struct pipe *pi = ctx.list_head; 6060 if (pi->num_cmds != 0 /* check #1 */ 6061 && pi->followup != PIPE_BG /* check #2 */ 6062 ) { 6063 continue; 6064 } 6065 } 6066 /* Treat newline as a command separator. */ 6067 done_pipe(&ctx, PIPE_SEQ); 6068 debug_printf_heredoc("heredoc_cnt:%d\n", heredoc_cnt); 6069 if (heredoc_cnt) { 6070 heredoc_cnt = fetch_heredocs(&ctx.as_string, ctx.list_head, heredoc_cnt, input); 6071 if (heredoc_cnt != 0) 6072 goto parse_error_exitcode1; 6073 } 6074 ctx.is_assignment = MAYBE_ASSIGNMENT; 6075 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]); 6076 ch = ';'; 6077 /* note: if (is_blank) continue; 6078 * will still trigger for us */ 6079 } 6080 } 6081 6082 /* "cmd}" or "cmd }..." without semicolon or &: 6083 * } is an ordinary char in this case, even inside { cmd; } 6084 * Pathological example: { ""}; } should exec "}" cmd 6085 */ 6086#ifndef __U_BOOT__ 6087 if (ch == '}') { 6088#else /* __U_BOOT__ */ 6089 if (ch == '}' || ch == ')') { 6090#endif /* __U_BOOT__ */ 6091 if (ctx.word.length != 0 /* word} */ 6092 || ctx.word.has_quoted_part /* ""} */ 6093 ) { 6094 goto ordinary_char; 6095 } 6096 if (!IS_NULL_CMD(ctx.command)) { /* cmd } */ 6097 /* Generally, there should be semicolon: "cmd; }" 6098 * However, bash allows to omit it if "cmd" is 6099 * a group. Examples: 6100 * { { echo 1; } } 6101 * {(echo 1)} 6102 * { echo 0 >&2 | { echo 1; } } 6103 * { while false; do :; done } 6104 * { case a in b) ;; esac } 6105 */ 6106 if (ctx.command->group) 6107 goto term_group; 6108 goto ordinary_char; 6109 } 6110 if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */ 6111 /* Can't be an end of {cmd}, skip the check */ 6112 goto skip_end_trigger; 6113 /* else: } does terminate a group */ 6114 } 6115 term_group: 6116 if (end_trigger && end_trigger == ch 6117 && (ch != ';' || heredoc_cnt == 0) 6118#if ENABLE_HUSH_CASE 6119 && (ch != ')' 6120 || ctx.ctx_res_w != RES_MATCH 6121 || (!ctx.word.has_quoted_part && strcmp(ctx.word.data, "esac") == 0) 6122 ) 6123#endif 6124 ) { 6125 if (done_word(&ctx)) { 6126 goto parse_error_exitcode1; 6127 } 6128 done_pipe(&ctx, PIPE_SEQ); 6129 ctx.is_assignment = MAYBE_ASSIGNMENT; 6130 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]); 6131 /* Do we sit outside of any if's, loops or case's? */ 6132 if (!HAS_KEYWORDS 6133 IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0)) 6134 ) { 6135 o_free_and_set_NULL(&ctx.word); 6136#if !BB_MMU 6137 debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data); 6138 if (pstring) 6139 *pstring = ctx.as_string.data; 6140 else 6141 o_free(&ctx.as_string); 6142#endif 6143 if (ch != ';' && IS_NULL_PIPE(ctx.list_head)) { 6144 /* Example: bare "{ }", "()" */ 6145 G.last_exitcode = 2; /* bash compat */ 6146 syntax_error_unexpected_ch(ch); 6147 goto parse_error; 6148 } 6149 if (heredoc_cnt_ptr) 6150 *heredoc_cnt_ptr = heredoc_cnt; 6151 debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt); 6152 debug_printf_parse("parse_stream return %p: " 6153 "end_trigger char found\n", 6154 ctx.list_head); 6155 debug_leave(); 6156 return ctx.list_head; 6157 } 6158 } 6159 6160 if (is_blank) 6161 continue; 6162 6163 /* Catch <, > before deciding whether this word is 6164 * an assignment. a=1 2>z b=2: b=2 is still assignment */ 6165 switch (ch) { 6166#ifndef __U_BOOT__ 6167 case '>': 6168 redir_fd = redirect_opt_num(&ctx.word); 6169 if (done_word(&ctx)) { 6170 goto parse_error_exitcode1; 6171 } 6172 redir_style = REDIRECT_OVERWRITE; 6173 if (next == '>') { 6174 redir_style = REDIRECT_APPEND; 6175 ch = i_getch(input); 6176 nommu_addchr(&ctx.as_string, ch); 6177 } 6178#if 0 6179 else if (next == '(') { 6180 syntax_error(">(process) not supported"); 6181 goto parse_error_exitcode1; 6182 } 6183#endif 6184 if (parse_redirect(&ctx, redir_fd, redir_style, input)) 6185 goto parse_error_exitcode1; 6186 continue; /* get next char */ 6187 case '<': 6188 redir_fd = redirect_opt_num(&ctx.word); 6189 if (done_word(&ctx)) { 6190 goto parse_error_exitcode1; 6191 } 6192 redir_style = REDIRECT_INPUT; 6193 if (next == '<') { 6194 redir_style = REDIRECT_HEREDOC; 6195 heredoc_cnt++; 6196 debug_printf_heredoc("++heredoc_cnt=%d\n", heredoc_cnt); 6197 ch = i_getch(input); 6198 nommu_addchr(&ctx.as_string, ch); 6199 } else if (next == '>') { 6200 redir_style = REDIRECT_IO; 6201 ch = i_getch(input); 6202 nommu_addchr(&ctx.as_string, ch); 6203 } 6204#if 0 6205 else if (next == '(') { 6206 syntax_error("<(process) not supported"); 6207 goto parse_error_exitcode1; 6208 } 6209#endif 6210 if (parse_redirect(&ctx, redir_fd, redir_style, input)) 6211 goto parse_error_exitcode1; 6212 continue; /* get next char */ 6213#else /* __U_BOOT__ */ 6214 /* 6215 * In U-Boot, '<' and '>' can be used in test command to test if 6216 * a string is, alphabetically, before or after another. 6217 * In 2021 Busybox hush, we will keep the same behavior and so not treat 6218 * them as redirection operator. 6219 * 6220 * Indeed, in U-Boot, tests are handled by the test command and not by the 6221 * shell code. 6222 * So, better to give this character as input to test command. 6223 * 6224 * NOTE In my opinion, when you use '<' or '>' I am almost sure 6225 * you wanted to use "-gt" or "-lt" in place, so thinking to 6226 * escape these will make you should check your code (sh syntax 6227 * at this level is, for me, error prone). 6228 */ 6229 case '>': 6230 fallthrough; 6231 case '<': 6232 o_addQchr(&ctx.word, ch); 6233 continue; 6234#endif /* __U_BOOT__ */ 6235 case '#': 6236 if (ctx.word.length == 0 && !ctx.word.has_quoted_part) { 6237 /* skip "#comment" */ 6238 /* note: we do not add it to &ctx.as_string */ 6239/* TODO: in bash: 6240 * comment inside $() goes to the next \n, even inside quoted string (!): 6241 * cmd "$(cmd2 #comment)" - syntax error 6242 * cmd "`cmd2 #comment`" - ok 6243 * We accept both (comment ends where command subst ends, in both cases). 6244 */ 6245 while (1) { 6246 ch = i_peek(input); 6247 if (ch == '\n') { 6248 nommu_addchr(&ctx.as_string, '\n'); 6249 break; 6250 } 6251 ch = i_getch(input); 6252 if (ch == EOF) 6253 break; 6254 } 6255 continue; /* get next char */ 6256 } 6257 break; 6258 } 6259 skip_end_trigger: 6260 6261 if (ctx.is_assignment == MAYBE_ASSIGNMENT 6262#ifndef __U_BOOT__ 6263 /* check that we are not in word in "a=1 2>word b=1": */ 6264 && !ctx.pending_redirect 6265#endif /* !__U_BOOT__ */ 6266 ) { 6267 /* ch is a special char and thus this word 6268 * cannot be an assignment */ 6269 ctx.is_assignment = NOT_ASSIGNMENT; 6270 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]); 6271 } 6272 6273 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */ 6274 6275 switch (ch) { 6276 case_SPECIAL_VAR_SYMBOL: 6277 case SPECIAL_VAR_SYMBOL: 6278 /* Convert raw ^C to corresponding special variable reference */ 6279 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); 6280 o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS); 6281 /* fall through */ 6282 case '#': 6283 /* non-comment #: "echo a#b" etc */ 6284 o_addchr(&ctx.word, ch); 6285 continue; /* get next char */ 6286 case '$': 6287#ifndef __U_BOOT__ 6288 if (parse_dollar_squote(&ctx.as_string, &ctx.word, input)) 6289 continue; /* get next char */ 6290#endif /* !__U_BOOT__ */ 6291 if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) { 6292 debug_printf_parse("parse_stream parse error: " 6293 "parse_dollar returned 0 (error)\n"); 6294 goto parse_error_exitcode1; 6295 } 6296 continue; /* get next char */ 6297 case '"': 6298 ctx.word.has_quoted_part = 1; 6299#ifndef __U_BOOT__ 6300 if (next == '"' && !ctx.pending_redirect) { 6301#else /* __U_BOOT__ */ 6302 if (next == '"') { 6303#endif /* __U_BOOT__ */ 6304 i_getch(input); /* eat second " */ 6305#ifndef __U_BOOT__ 6306 insert_empty_quoted_str_marker: 6307#endif /* !__U_BOOT__ */ 6308 nommu_addchr(&ctx.as_string, next); 6309 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); 6310 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); 6311 continue; /* get next char */ 6312 } 6313 if (ctx.is_assignment == NOT_ASSIGNMENT) 6314 ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS; 6315 if (!encode_string(&ctx.as_string, &ctx.word, input, '"')) 6316 goto parse_error_exitcode1; 6317 ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS; 6318 continue; /* get next char */ 6319#if ENABLE_HUSH_TICK 6320 case '`': { 6321 USE_FOR_NOMMU(unsigned pos;) 6322 6323 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); 6324 o_addchr(&ctx.word, '`'); 6325 USE_FOR_NOMMU(pos = ctx.word.length;) 6326 if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0)) 6327 goto parse_error_exitcode1; 6328# if !BB_MMU 6329 o_addstr(&ctx.as_string, ctx.word.data + pos); 6330 o_addchr(&ctx.as_string, '`'); 6331# endif 6332 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); 6333 //debug_printf_subst("SUBST RES3 '%s'\n", ctx.word.data + pos); 6334 continue; /* get next char */ 6335 } 6336#endif 6337 case ';': 6338#if ENABLE_HUSH_CASE 6339 case_semi: 6340#endif 6341 if (done_word(&ctx)) { 6342 goto parse_error_exitcode1; 6343 } 6344 done_pipe(&ctx, PIPE_SEQ); 6345#if ENABLE_HUSH_CASE 6346 /* Eat multiple semicolons, detect 6347 * whether it means something special */ 6348 while (1) { 6349 ch = i_peek_and_eat_bkslash_nl(input); 6350 if (ch != ';') 6351 break; 6352 ch = i_getch(input); 6353 nommu_addchr(&ctx.as_string, ch); 6354 if (ctx.ctx_res_w == RES_CASE_BODY) { 6355 ctx.ctx_dsemicolon = 1; 6356 ctx.ctx_res_w = RES_MATCH; 6357 break; 6358 } 6359 } 6360#endif 6361 new_cmd: 6362 /* We just finished a cmd. New one may start 6363 * with an assignment */ 6364 ctx.is_assignment = MAYBE_ASSIGNMENT; 6365 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]); 6366 continue; /* get next char */ 6367 case '&': 6368 if (done_word(&ctx)) { 6369 goto parse_error_exitcode1; 6370 } 6371 if (next == '&') { 6372 ch = i_getch(input); 6373 nommu_addchr(&ctx.as_string, ch); 6374 done_pipe(&ctx, PIPE_AND); 6375 } else { 6376 done_pipe(&ctx, PIPE_BG); 6377 } 6378 goto new_cmd; 6379 case '|': 6380 if (done_word(&ctx)) { 6381 goto parse_error_exitcode1; 6382 } 6383#if ENABLE_HUSH_CASE 6384 if (ctx.ctx_res_w == RES_MATCH) 6385 break; /* we are in case's "word | word)" */ 6386#endif 6387 if (next == '|') { /* || */ 6388 ch = i_getch(input); 6389 nommu_addchr(&ctx.as_string, ch); 6390 done_pipe(&ctx, PIPE_OR); 6391 } else { 6392 /* we could pick up a file descriptor choice here 6393 * with redirect_opt_num(), but bash doesn't do it. 6394 * "echo foo 2| cat" yields "foo 2". */ 6395 done_command(&ctx); 6396 } 6397 goto new_cmd; 6398 case '(': 6399#if ENABLE_HUSH_CASE 6400 /* "case... in [(]word)..." - skip '(' */ 6401 if (ctx.ctx_res_w == RES_MATCH 6402 && ctx.command->argv == NULL /* not (word|(... */ 6403 && ctx.word.length == 0 /* not word(... */ 6404 && ctx.word.has_quoted_part == 0 /* not ""(... */ 6405 ) { 6406 continue; /* get next char */ 6407 } 6408#endif 6409 /* fall through */ 6410 case '{': { 6411 int n = parse_group(&ctx, input, ch); 6412 if (n < 0) { 6413 goto parse_error_exitcode1; 6414 } 6415 debug_printf_heredoc("parse_group done, needs heredocs:%d\n", n); 6416 heredoc_cnt += n; 6417 goto new_cmd; 6418 } 6419 case ')': 6420#if ENABLE_HUSH_CASE 6421 if (ctx.ctx_res_w == RES_MATCH) 6422 goto case_semi; 6423#endif 6424 case '}': 6425 /* proper use of this character is caught by end_trigger: 6426 * if we see {, we call parse_group(..., end_trigger='}') 6427 * and it will match } earlier (not here). */ 6428 G.last_exitcode = 2; 6429 syntax_error_unexpected_ch(ch); 6430 goto parse_error; 6431 default: 6432 if (HUSH_DEBUG) 6433 bb_error_msg_and_die("BUG: unexpected %c", ch); 6434 } 6435 } /* while (1) */ 6436 6437 parse_error_exitcode1: 6438 G.last_exitcode = 1; 6439 parse_error: 6440 { 6441 struct parse_context *pctx; 6442 IF_HAS_KEYWORDS(struct parse_context *p2;) 6443 6444 /* Clean up allocated tree. 6445 * Sample for finding leaks on syntax error recovery path. 6446 * Run it from interactive shell, watch pmap `pidof hush`. 6447 * while if false; then false; fi; do break; fi 6448 * Samples to catch leaks at execution: 6449 * while if (true | { true;}); then echo ok; fi; do break; done 6450 * while if (true | { true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done 6451 */ 6452 pctx = &ctx; 6453 do { 6454 /* Update pipe/command counts, 6455 * otherwise freeing may miss some */ 6456 done_pipe(pctx, PIPE_SEQ); 6457 debug_printf_clean("freeing list %p from ctx %p\n", 6458 pctx->list_head, pctx); 6459 debug_print_tree(pctx->list_head, 0); 6460 free_pipe_list(pctx->list_head); 6461 debug_printf_clean("freed list %p\n", pctx->list_head); 6462#if !BB_MMU 6463 o_free(&pctx->as_string); 6464#endif 6465 IF_HAS_KEYWORDS(p2 = pctx->stack;) 6466 if (pctx != &ctx) { 6467 free(pctx); 6468 } 6469 IF_HAS_KEYWORDS(pctx = p2;) 6470 } while (HAS_KEYWORDS && pctx); 6471 6472 o_free(&ctx.word); 6473#if !BB_MMU 6474 if (pstring) 6475 *pstring = NULL; 6476#endif 6477 debug_leave(); 6478 return ERR_PTR; 6479 } 6480} 6481 6482/*** Execution routines ***/ 6483 6484/* Expansion can recurse, need forward decls: */ 6485#if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE 6486#define expand_string_to_string(str, EXP_flags, do_unbackslash) \ 6487 expand_string_to_string(str) 6488#endif 6489static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash); 6490#if ENABLE_HUSH_TICK 6491static int process_command_subs(o_string *dest, const char *s); 6492#endif 6493static int expand_vars_to_list(o_string *output, int n, char *arg); 6494 6495/* expand_strvec_to_strvec() takes a list of strings, expands 6496 * all variable references within and returns a pointer to 6497 * a list of expanded strings, possibly with larger number 6498 * of strings. (Think VAR="a b"; echo $VAR). 6499 * This new list is allocated as a single malloc block. 6500 * NULL-terminated list of char* pointers is at the beginning of it, 6501 * followed by strings themselves. 6502 * Caller can deallocate entire list by single free(list). */ 6503 6504/* A horde of its helpers come first: */ 6505 6506static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len) 6507{ 6508 while (--len >= 0) { 6509 char c = *str++; 6510 6511#if ENABLE_HUSH_BRACE_EXPANSION 6512 if (c == '{' || c == '}') { 6513 /* { -> \{, } -> \} */ 6514 o_addchr(o, '\\'); 6515 /* And now we want to add { or } and continue: 6516 * o_addchr(o, c); 6517 * continue; 6518 * luckily, just falling through achieves this. 6519 */ 6520 } 6521#endif 6522 o_addchr(o, c); 6523 if (c == '\\') { 6524 /* \z -> \\\z; \<eol> -> \\<eol> */ 6525 o_addchr(o, '\\'); 6526 if (len) { 6527 len--; 6528 o_addchr(o, '\\'); 6529 o_addchr(o, *str++); 6530 } 6531 } 6532 } 6533} 6534 6535/* Store given string, finalizing the word and starting new one whenever 6536 * we encounter IFS char(s). This is used for expanding variable values. 6537 * End-of-string does NOT finalize word: think about 'echo -$VAR-'. 6538 * Return in output->ended_in_ifs: 6539 * 1 - ended with IFS char, else 0 (this includes case of empty str). 6540 */ 6541static int expand_on_ifs(o_string *output, int n, const char *str) 6542{ 6543 int last_is_ifs = 0; 6544 6545 while (1) { 6546 int word_len; 6547 6548 if (!*str) /* EOL - do not finalize word */ 6549 break; 6550 word_len = strcspn(str, G.ifs); 6551 if (word_len) { 6552 /* We have WORD_LEN leading non-IFS chars */ 6553 if (!(output->o_expflags & EXP_FLAG_GLOB)) { 6554 o_addblock(output, str, word_len); 6555 } else { 6556 /* Protect backslashes against globbing up :) 6557 * Example: "v='\*'; echo b$v" prints "b\*" 6558 * (and does not try to glob on "*") 6559 */ 6560 o_addblock_duplicate_backslash(output, str, word_len); 6561 /*/ Why can't we do it easier? */ 6562 /*o_addblock(output, str, word_len); - WRONG: "v='\*'; echo Z$v" prints "Z*" instead of "Z\*" */ 6563 /*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */ 6564 } 6565 last_is_ifs = 0; 6566 str += word_len; 6567 if (!*str) /* EOL - do not finalize word */ 6568 break; 6569 } 6570 6571 /* We know str here points to at least one IFS char */ 6572 last_is_ifs = 1; 6573 str += strspn(str, G.ifs_whitespace); /* skip IFS whitespace chars */ 6574 if (!*str) /* EOL - do not finalize word */ 6575 break; 6576 6577 if (G.ifs_whitespace != G.ifs /* usually false ($IFS is usually all whitespace), */ 6578 && strchr(G.ifs, *str) /* the second check would fail */ 6579 ) { 6580 /* This is a non-whitespace $IFS char */ 6581 /* Skip it and IFS whitespace chars, start new word */ 6582 str++; 6583 str += strspn(str, G.ifs_whitespace); 6584 goto new_word; 6585 } 6586 6587 /* Start new word... but not always! */ 6588 /* Case "v=' a'; echo ''$v": we do need to finalize empty word: */ 6589 if (output->has_quoted_part 6590 /* 6591 * Case "v=' a'; echo $v": 6592 * here nothing precedes the space in $v expansion, 6593 * therefore we should not finish the word 6594 * (IOW: if there *is* word to finalize, only then do it): 6595 * It's okay if this accesses the byte before first argv[]: 6596 * past call to o_save_ptr() cleared it to zero byte 6597 * (grep for -prev-ifs-check-). 6598 */ 6599 || output->data[output->length - 1] 6600 ) { 6601 new_word: 6602 o_addchr(output, '\0'); 6603 debug_print_list("expand_on_ifs", output, n); 6604 n = o_save_ptr(output, n); 6605 } 6606 } 6607 6608 output->ended_in_ifs = last_is_ifs; 6609 debug_print_list("expand_on_ifs[1]", output, n); 6610 return n; 6611} 6612 6613#ifndef __U_BOOT__ 6614/* Helper to expand $((...)) and heredoc body. These act as if 6615 * they are in double quotes, with the exception that they are not :). 6616 * Just the rules are similar: "expand only $var and `cmd`" 6617 * 6618 * Returns malloced string. 6619 * As an optimization, we return NULL if expansion is not needed. 6620 */ 6621static char *encode_then_expand_string(const char *str) 6622{ 6623 char *exp_str; 6624 struct in_str input; 6625 o_string dest = NULL_O_STRING; 6626 const char *cp; 6627 6628 cp = str; 6629 for (;;) { 6630 if (!*cp) return NULL; /* string has no special chars */ 6631 if (*cp == '$') break; 6632 if (*cp == '\\') break; 6633#if ENABLE_HUSH_TICK 6634 if (*cp == '`') break; 6635#endif 6636 cp++; 6637 } 6638 6639 /* We need to expand. Example: 6640 * echo $(($a + `echo 1`)) $((1 + $((2)) )) 6641 */ 6642 setup_string_in_str(&input, str); 6643 encode_string(NULL, &dest, &input, EOF); 6644//TODO: error check (encode_string returns 0 on error)? 6645 //bb_error_msg("'%s' -> '%s'", str, dest.data); 6646 exp_str = expand_string_to_string(dest.data, 6647 EXP_FLAG_ESC_GLOB_CHARS, 6648 /*unbackslash:*/ 1 6649 ); 6650 //bb_error_msg("'%s' -> '%s'", dest.data, exp_str); 6651 o_free(&dest); 6652 return exp_str; 6653} 6654 6655static const char *first_special_char_in_vararg(const char *cp) 6656{ 6657 for (;;) { 6658 if (!*cp) return NULL; /* string has no special chars */ 6659 if (*cp == '$') return cp; 6660 if (*cp == '\\') return cp; 6661 if (*cp == '\'') return cp; 6662 if (*cp == '"') return cp; 6663#if ENABLE_HUSH_TICK 6664 if (*cp == '`') return cp; 6665#endif 6666 /* dquoted "${x:+ARG}" should not glob, therefore 6667 * '*' et al require some non-literal processing: */ 6668 if (*cp == '*') return cp; 6669 if (*cp == '?') return cp; 6670 if (*cp == '[') return cp; 6671 cp++; 6672 } 6673} 6674 6675/* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}. 6676 * These can contain single- and double-quoted strings, 6677 * and treated as if the ARG string is initially unquoted. IOW: 6678 * ${var#ARG} and "${var#ARG}" treat ARG the same (ARG can even be 6679 * a dquoted string: "${var#"zz"}"), the difference only comes later 6680 * (word splitting and globbing of the ${var...} result). 6681 */ 6682#if !BASH_PATTERN_SUBST 6683#define encode_then_expand_vararg(str, handle_squotes, do_unbackslash) \ 6684 encode_then_expand_vararg(str, handle_squotes) 6685#endif 6686static char *encode_then_expand_vararg(const char *str, int handle_squotes, int do_unbackslash) 6687{ 6688#if !BASH_PATTERN_SUBST && ENABLE_HUSH_CASE 6689 const int do_unbackslash = 0; 6690#endif 6691 char *exp_str; 6692 struct in_str input; 6693 o_string dest = NULL_O_STRING; 6694 6695 if (!first_special_char_in_vararg(str)) { 6696 /* string has no special chars */ 6697 return NULL; 6698 } 6699 6700 setup_string_in_str(&input, str); 6701 dest.data = xzalloc(1); /* start as "", not as NULL */ 6702 exp_str = NULL; 6703 6704 for (;;) { 6705 int ch; 6706 6707 ch = i_getch(&input); 6708 debug_printf_parse("%s: ch=%c (%d) escape=%d\n", 6709 __func__, ch, ch, !!dest.o_expflags); 6710 6711 if (!dest.o_expflags) { 6712 if (ch == EOF) 6713 break; 6714 if (handle_squotes && ch == '\'') { 6715 if (!add_till_single_quote_dquoted(&dest, &input)) 6716 goto ret; /* error */ 6717 continue; 6718 } 6719 } 6720 if (ch == EOF) { 6721 syntax_error_unterm_ch('"'); 6722 goto ret; /* error */ 6723 } 6724 if (ch == '"') { 6725 dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS; 6726 continue; 6727 } 6728 if (ch == '\\') { 6729 ch = i_getch(&input); 6730 if (ch == EOF) { 6731//example? error message? syntax_error_unterm_ch('"'); 6732 debug_printf_parse("%s: error: \\<eof>\n", __func__); 6733 goto ret; 6734 } 6735 o_addqchr(&dest, ch); 6736 continue; 6737 } 6738 if (ch == '$') { 6739 if (parse_dollar_squote(NULL, &dest, &input)) 6740 continue; 6741 if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ 0x80)) { 6742 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__); 6743 goto ret; 6744 } 6745 continue; 6746 } 6747#if ENABLE_HUSH_TICK 6748 if (ch == '`') { 6749 //unsigned pos = dest->length; 6750 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6751 o_addchr(&dest, 0x80 | '`'); 6752 if (!add_till_backquote(&dest, &input, 6753 /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */ 6754 ) 6755 ) { 6756 goto ret; /* error */ 6757 } 6758 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6759 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); 6760 continue; 6761 } 6762#endif 6763 o_addQchr(&dest, ch); 6764 } /* for (;;) */ 6765 6766 debug_printf_parse("encode: '%s' -> '%s'\n", str, dest.data); 6767 exp_str = expand_string_to_string(dest.data, 6768 do_unbackslash ? EXP_FLAG_ESC_GLOB_CHARS : 0, 6769 do_unbackslash 6770 ); 6771 ret: 6772 debug_printf_parse("expand: '%s' -> '%s'\n", dest.data, exp_str); 6773 o_free(&dest); 6774 return exp_str; 6775} 6776 6777/* Expanding ARG in ${var+ARG}, ${var-ARG} 6778 */ 6779static NOINLINE int encode_then_append_var_plusminus(o_string *output, int n, 6780 char *str, int dquoted) 6781{ 6782 struct in_str input; 6783 o_string dest = NULL_O_STRING; 6784 6785 if (!first_special_char_in_vararg(str) 6786 && '\0' == str[strcspn(str, G.ifs)] 6787 ) { 6788 /* string has no special chars 6789 * && string has no $IFS chars 6790 */ 6791 if (dquoted) { 6792 /* Prints 1 (quoted expansion is a "" word, not nothing): 6793 * set -- "${notexist-}"; echo $# 6794 */ 6795 output->has_quoted_part = 1; 6796 } 6797 return expand_vars_to_list(output, n, str); 6798 } 6799 6800 setup_string_in_str(&input, str); 6801 6802 for (;;) { 6803 int ch; 6804 6805 ch = i_getch(&input); 6806 debug_printf_parse("%s: ch=%c (%d) escape=%x\n", 6807 __func__, ch, ch, dest.o_expflags); 6808 6809 if (!dest.o_expflags) { 6810 if (ch == EOF) 6811 break; 6812 if (!dquoted && !(output->o_expflags & EXP_FLAG_SINGLEWORD) && strchr(G.ifs, ch)) { 6813 /* PREFIX${x:d${e}f ...} and we met space: expand "d${e}f" and start new word. 6814 * do not assume we are at the start of the word (PREFIX above). 6815 */ 6816 if (dest.data) { 6817 n = expand_vars_to_list(output, n, dest.data); 6818 o_free_and_set_NULL(&dest); 6819 o_addchr(output, '\0'); 6820 n = o_save_ptr(output, n); /* create next word */ 6821 } else 6822 if (output->length != o_get_last_ptr(output, n) 6823 || output->has_quoted_part 6824 ) { 6825 /* For these cases: 6826 * f() { for i; do echo "|$i|"; done; }; x=x 6827 * f a${x:+ }b # 1st condition 6828 * |a| 6829 * |b| 6830 * f ""${x:+ }b # 2nd condition 6831 * || 6832 * |b| 6833 */ 6834 o_addchr(output, '\0'); 6835 n = o_save_ptr(output, n); /* create next word */ 6836 } 6837 continue; 6838 } 6839 if (!dquoted && ch == '\'') { 6840 if (!add_till_single_quote_dquoted(&dest, &input)) 6841 goto ret; /* error */ 6842 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6843 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6844 continue; 6845 } 6846 } 6847 if (ch == EOF) { 6848 syntax_error_unterm_ch('"'); 6849 goto ret; /* error */ 6850 } 6851 if (ch == '"') { 6852 dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS; 6853 if (dest.o_expflags) { 6854 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6855 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6856 } 6857 continue; 6858 } 6859 if (ch == '\\') { 6860 ch = i_getch(&input); 6861 if (ch == EOF) { 6862//example? error message? syntax_error_unterm_ch('"'); 6863 debug_printf_parse("%s: error: \\<eof>\n", __func__); 6864 goto ret; 6865 } 6866 o_addqchr(&dest, ch); 6867 continue; 6868 } 6869 if (ch == '$') { 6870 if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ (dest.o_expflags || dquoted) ? 0x80 : 0)) { 6871 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__); 6872 goto ret; 6873 } 6874 continue; 6875 } 6876#if ENABLE_HUSH_TICK 6877 if (ch == '`') { 6878 //unsigned pos = dest->length; 6879 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6880 o_addchr(&dest, (dest.o_expflags || dquoted) ? 0x80 | '`' : '`'); 6881 if (!add_till_backquote(&dest, &input, 6882 /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */ 6883 ) 6884 ) { 6885 goto ret; /* error */ 6886 } 6887 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 6888 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); 6889 continue; 6890 } 6891#endif 6892 if (dquoted) { 6893 /* Always glob-protect if in dquotes: 6894 * x=x; echo "${x:+/bin/c*}" - prints: /bin/c* 6895 * x=x; echo "${x:+"/bin/c*"}" - prints: /bin/c* 6896 */ 6897 o_addqchr(&dest, ch); 6898 } else { 6899 /* Glob-protect only if char is quoted: 6900 * x=x; echo ${x:+/bin/c*} - prints many filenames 6901 * x=x; echo ${x:+"/bin/c*"} - prints: /bin/c* 6902 */ 6903 o_addQchr(&dest, ch); 6904 } 6905 } /* for (;;) */ 6906 6907 if (dest.data) { 6908 n = expand_vars_to_list(output, n, dest.data); 6909 } 6910 ret: 6911 o_free(&dest); 6912 return n; 6913} 6914#endif /* !__U_BOOT__ */ 6915 6916#ifndef __U_BOOT__ 6917#if ENABLE_FEATURE_SH_MATH 6918static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) 6919{ 6920 arith_state_t math_state; 6921 arith_t res; 6922 char *exp_str; 6923 6924 math_state.lookupvar = get_local_var_value; 6925 math_state.setvar = set_local_var_from_halves; 6926 //math_state.endofname = endofname; 6927 exp_str = encode_then_expand_string(arg); 6928 res = arith(&math_state, exp_str ? exp_str : arg); 6929 free(exp_str); 6930 if (errmsg_p) 6931 *errmsg_p = math_state.errmsg; 6932 if (math_state.errmsg) 6933 msg_and_die_if_script(math_state.errmsg); 6934 return res; 6935} 6936#endif 6937#endif /* !__U_BOOT__ */ 6938 6939#ifndef __U_BOOT__ 6940#if BASH_PATTERN_SUBST 6941/* ${var/[/]pattern[/repl]} helpers */ 6942static char *strstr_pattern(char *val, const char *pattern, int *size) 6943{ 6944 int first_escaped = (pattern[0] == '\\' && pattern[1]); 6945 /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars" 6946 * as literal too (as it is semi-common, and easy to accomodate 6947 * by just using str + 1). 6948 */ 6949 int sz = strcspn(pattern + first_escaped * 2, "*?[\\"); 6950 if ((pattern + first_escaped * 2)[sz] == '\0') { 6951 /* Optimization for trivial patterns. 6952 * Testcase for very slow replace (performs about 22k replaces): 6953 * x=:::::::::::::::::::::: 6954 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} 6955 * echo "${x//:/|}" 6956 */ 6957 *size = sz + first_escaped; 6958 return strstr(val, pattern + first_escaped); 6959 } 6960 6961 while (1) { 6962 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF); 6963 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end); 6964 if (end) { 6965 *size = end - val; 6966 return val; 6967 } 6968 if (*val == '\0') 6969 return NULL; 6970 /* Optimization: if "*pat" did not match the start of "string", 6971 * we know that "tring", "ring" etc will not match too: 6972 */ 6973 if (pattern[0] == '*') 6974 return NULL; 6975 val++; 6976 } 6977} 6978static char *replace_pattern(char *val, const char *pattern, const char *repl, char exp_op) 6979{ 6980 char *result = NULL; 6981 unsigned res_len = 0; 6982 unsigned repl_len = strlen(repl); 6983 6984 /* Null pattern never matches, including if "var" is empty */ 6985 if (!pattern[0]) 6986 return result; /* NULL, no replaces happened */ 6987 6988 while (1) { 6989 int size; 6990 char *s = strstr_pattern(val, pattern, &size); 6991 if (!s) 6992 break; 6993 6994 result = xrealloc(result, res_len + (s - val) + repl_len + 1); 6995 strcpy(mempcpy(result + res_len, val, s - val), repl); 6996 res_len += (s - val) + repl_len; 6997 debug_printf_varexp("val:'%s' s:'%s' result:'%s'\n", val, s, result); 6998 6999 val = s + size; 7000 if (exp_op == '/') 7001 break; 7002 } 7003 if (*val && result) { 7004 result = xrealloc(result, res_len + strlen(val) + 1); 7005 strcpy(result + res_len, val); 7006 debug_printf_varexp("val:'%s' result:'%s'\n", val, result); 7007 } 7008 debug_printf_varexp("result:'%s'\n", result); 7009 return result; 7010} 7011#endif /* BASH_PATTERN_SUBST */ 7012#endif /* !__U_BOOT__ */ 7013 7014static int append_str_maybe_ifs_split(o_string *output, int n, 7015 int first_ch, const char *val) 7016{ 7017 if (!(first_ch & 0x80)) { /* unquoted $VAR */ 7018 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, 7019 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); 7020 if (val && val[0]) 7021 n = expand_on_ifs(output, n, val); 7022 } else { /* quoted "$VAR" */ 7023 output->has_quoted_part = 1; 7024 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, 7025 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); 7026 if (val && val[0]) 7027 o_addQstr(output, val); 7028 } 7029 return n; 7030} 7031 7032/* Handle <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. 7033 */ 7034static NOINLINE int expand_one_var(o_string *output, int n, 7035 int first_ch, char *arg, char **pp) 7036{ 7037 const char *val; 7038 char *to_be_freed; 7039 char *p; 7040 char *var; 7041 char exp_op; 7042 char exp_save = exp_save; /* for compiler */ 7043 char *exp_saveptr; /* points to expansion operator */ 7044 char *exp_word = exp_word; /* for compiler */ 7045 char arg0; 7046 7047 val = NULL; 7048 to_be_freed = NULL; 7049 p = *pp; 7050 *p = '\0'; /* replace trailing SPECIAL_VAR_SYMBOL */ 7051 var = arg; 7052 exp_saveptr = arg[1] ? strchr(VAR_ENCODED_SUBST_OPS, arg[1]) : NULL; 7053 arg0 = arg[0]; 7054 arg[0] = (arg0 & 0x7f); 7055 exp_op = 0; 7056 7057 if (arg[0] == '#' && arg[1] /* ${#...} but not ${#} */ 7058 && (!exp_saveptr /* and ( not(${#<op_char>...}) */ 7059 || (arg[2] == '\0' && strchr(SPECIAL_VARS_STR, arg[1])) /* or ${#C} "len of $C" ) */ 7060 ) /* NB: skipping ^^^specvar check mishandles ${#::2} */ 7061 ) { 7062 /* It must be length operator: ${#var} */ 7063 var++; 7064 exp_op = 'L'; 7065 } else { 7066 /* Maybe handle parameter expansion */ 7067 if (exp_saveptr /* if 2nd char is one of expansion operators */ 7068 && strchr(NUMERIC_SPECVARS_STR, arg[0]) /* 1st char is special variable */ 7069 ) { 7070 /* ${?:0}, ${#[:]%0} etc */ 7071 exp_saveptr = var + 1; 7072 } else { 7073 /* ${?}, ${var}, ${var:0}, ${var[:]%0} etc */ 7074 exp_saveptr = var+1 + strcspn(var+1, VAR_ENCODED_SUBST_OPS); 7075 } 7076 exp_op = exp_save = *exp_saveptr; 7077#ifndef __U_BOOT__ 7078 if (exp_op) { 7079 exp_word = exp_saveptr + 1; 7080 if (exp_op == ':') { 7081 exp_op = *exp_word++; 7082//TODO: try ${var:} and ${var:bogus} in non-bash config 7083 if (BASH_SUBSTR 7084 && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op)) 7085 ) { 7086 /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */ 7087 exp_op = ':'; 7088 exp_word--; 7089 } 7090 } 7091 *exp_saveptr = '\0'; 7092 } /* else: it's not an expansion op, but bare ${var} */ 7093#endif /* !__U_BOOT__ */ 7094 } 7095 7096 /* Look up the variable in question */ 7097 if (isdigit(var[0])) { 7098 /* parse_dollar should have vetted var for us */ 7099#ifndef __U_BOOT__ 7100 int nn = xatoi_positive(var); 7101#else /* __U_BOOT__ */ 7102 int nn = simple_strtoul(var, NULL, 10); 7103#endif /* __U_BOOT__ */ 7104 if (nn < G.global_argc) 7105 val = G.global_argv[nn]; 7106 /* else val remains NULL: $N with too big N */ 7107 } else { 7108 switch (var[0]) { 7109#ifndef __U_BOOT__ 7110 case '$': /* pid */ 7111 val = utoa(G.root_pid); 7112 break; 7113 case '!': /* bg pid */ 7114 val = G.last_bg_pid ? utoa(G.last_bg_pid) : ""; 7115 break; 7116#endif /* !__U_BOOT__ */ 7117 case '?': /* exitcode */ 7118 val = utoa(G.last_exitcode); 7119 break; 7120 case '#': /* argc */ 7121 val = utoa(G.global_argc ? G.global_argc-1 : 0); 7122 break; 7123#ifndef __U_BOOT__ 7124 case '-': { /* active options */ 7125 /* Check set_mode() to see what option chars we support */ 7126 char *cp; 7127 val = cp = G.optstring_buf; 7128 if (G.o_opt[OPT_O_ERREXIT]) 7129 *cp++ = 'e'; 7130 if (G_interactive_fd) 7131 *cp++ = 'i'; 7132 if (G_x_mode) 7133 *cp++ = 'x'; 7134 /* If G.o_opt[OPT_O_NOEXEC] is true, 7135 * commands read but are not executed, 7136 * so $- can not execute too, 'n' is never seen in $-. 7137 */ 7138 if (G.opt_c) 7139 *cp++ = 'c'; 7140 if (G.opt_s) 7141 *cp++ = 's'; 7142 *cp = '\0'; 7143 break; 7144 } 7145#endif /* !__U_BOOT__ */ 7146 default: 7147#ifndef __U_BOOT__ 7148 val = get_local_var_value(var); 7149#else /* __U_BOOT__ */ 7150 /* 7151 * Environment variable set with setenv* have to be 7152 * expanded. 7153 * So, we first search if the variable exists in 7154 * environment, if this is not the case, we default to 7155 * local value. 7156 */ 7157 val = env_get(var); 7158 if (!val) 7159 val = get_local_var_value(var); 7160#endif /* __U_BOOT__ */ 7161 } 7162 } 7163 7164#ifndef __U_BOOT__ 7165 /* Handle any expansions */ 7166 if (exp_op == 'L') { 7167 reinit_unicode_for_hush(); 7168 debug_printf_expand("expand: length(%s)=", val); 7169 val = utoa(val ? unicode_strlen(val) : 0); 7170 debug_printf_expand("%s\n", val); 7171 } else if (exp_op) { 7172 if (exp_op == '%' || exp_op == '#') { 7173 /* Standard-mandated substring removal ops: 7174 * ${parameter%word} - remove smallest suffix pattern 7175 * ${parameter%%word} - remove largest suffix pattern 7176 * ${parameter#word} - remove smallest prefix pattern 7177 * ${parameter##word} - remove largest prefix pattern 7178 * 7179 * Word is expanded to produce a glob pattern. 7180 * Then var's value is matched to it and matching part removed. 7181 */ 7182 /* bash compat: if x is "" and no shrinking of it is possible, 7183 * inner ${...} is not evaluated. Example: 7184 * unset b; : ${a%${b=B}}; echo $b 7185 * assignment b=B only happens if $a is not "". 7186 */ 7187 if (val && val[0]) { 7188 char *t; 7189 char *exp_exp_word; 7190 char *loc; 7191 unsigned scan_flags = pick_scan(exp_op, *exp_word); 7192 if (exp_op == *exp_word) /* ## or %% */ 7193 exp_word++; 7194 debug_printf_expand("expand: exp_word:'%s'\n", exp_word); 7195 exp_exp_word = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0); 7196 if (exp_exp_word) 7197 exp_word = exp_exp_word; 7198 debug_printf_expand("expand: exp_word:'%s'\n", exp_word); 7199 /* 7200 * HACK ALERT. We depend here on the fact that 7201 * G.global_argv and results of utoa and get_local_var_value 7202 * are actually in writable memory: 7203 * scan_and_match momentarily stores NULs there. 7204 */ 7205 t = (char*)val; 7206 loc = scan_and_match(t, exp_word, scan_flags); 7207 debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc); 7208 free(exp_exp_word); 7209 if (loc) { /* match was found */ 7210 if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */ 7211 val = loc; /* take right part */ 7212 else /* %[%] */ 7213 val = to_be_freed = xstrndup(val, loc - val); /* left */ 7214 } 7215 } 7216 } 7217#if BASH_PATTERN_SUBST 7218 else if (exp_op == '/' || exp_op == '\\') { 7219 /* It's ${var/[/]pattern[/repl]} thing. 7220 * Note that in encoded form it has TWO parts: 7221 * var/pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL> 7222 * and if // is used, it is encoded as \: 7223 * var\pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL> 7224 */ 7225 /* bash compat: if var is "", both pattern and repl 7226 * are still evaluated, if it is unset, then not: 7227 * unset b; a=; : ${a/z/${b=3}}; echo $b # b=3 7228 * unset b; unset a; : ${a/z/${b=3}}; echo $b # b not set 7229 */ 7230 if (val /*&& val[0]*/) { 7231 /* pattern uses non-standard expansion. 7232 * repl should be unbackslashed and globbed 7233 * by the usual expansion rules: 7234 * >az >bz 7235 * v='a bz'; echo "${v/a*z/a*z}" #prints "a*z" 7236 * v='a bz'; echo "${v/a*z/\z}" #prints "z" 7237 * v='a bz'; echo ${v/a*z/a*z} #prints "az" 7238 * v='a bz'; echo ${v/a*z/\z} #prints "z" 7239 * (note that a*z _pattern_ is never globbed!) 7240 */ 7241 char *pattern, *repl, *t; 7242 pattern = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0); 7243 if (!pattern) 7244 pattern = xstrdup(exp_word); 7245 debug_printf_varexp("pattern:'%s'->'%s'\n", exp_word, pattern); 7246 *p++ = SPECIAL_VAR_SYMBOL; 7247 exp_word = p; 7248 p = strchr(p, SPECIAL_VAR_SYMBOL); 7249 *p = '\0'; 7250 repl = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 1); 7251 debug_printf_varexp("repl:'%s'->'%s'\n", exp_word, repl); 7252 /* HACK ALERT. We depend here on the fact that 7253 * G.global_argv and results of utoa and get_local_var_value 7254 * are actually in writable memory: 7255 * replace_pattern momentarily stores NULs there. */ 7256 t = (char*)val; 7257 to_be_freed = replace_pattern(t, 7258 pattern, 7259 (repl ? repl : exp_word), 7260 exp_op); 7261 if (to_be_freed) /* at least one replace happened */ 7262 val = to_be_freed; 7263 free(pattern); 7264 free(repl); 7265 } else { 7266 /* Unset variable always gives nothing */ 7267 // a=; echo ${a/*/w} # "w" 7268 // unset a; echo ${a/*/w} # "" 7269 /* Just skip "replace" part */ 7270 *p++ = SPECIAL_VAR_SYMBOL; 7271 p = strchr(p, SPECIAL_VAR_SYMBOL); 7272 *p = '\0'; 7273 } 7274 } 7275#endif /* BASH_PATTERN_SUBST */ 7276 else if (exp_op == ':') { 7277#if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH 7278 /* It's ${var:N[:M]} bashism. 7279 * Note that in encoded form it has TWO parts: 7280 * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL> 7281 */ 7282 arith_t beg, len; 7283 unsigned vallen; 7284 const char *errmsg; 7285 7286 beg = expand_and_evaluate_arith(exp_word, &errmsg); 7287 if (errmsg) 7288 goto empty_result; 7289 debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg); 7290 *p++ = SPECIAL_VAR_SYMBOL; 7291 exp_word = p; 7292 p = strchr(p, SPECIAL_VAR_SYMBOL); 7293 *p = '\0'; 7294 vallen = val ? strlen(val) : 0; 7295 if (beg < 0) { 7296 /* negative beg counts from the end */ 7297 beg = (arith_t)vallen + beg; 7298 } 7299 /* If expansion will be empty, do not even evaluate len */ 7300 if (!val || beg < 0 || beg > vallen) { 7301 /* Why > vallen, not >=? bash: 7302 * unset b; a=ab; : ${a:2:${b=3}}; echo $b # "", b=3 (!!!) 7303 * unset b; a=a; : ${a:2:${b=3}}; echo $b # "", b not set 7304 */ 7305 goto empty_result; 7306 } 7307 len = expand_and_evaluate_arith(exp_word, &errmsg); 7308 if (errmsg) 7309 goto empty_result; 7310 debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len); 7311 debug_printf_varexp("from val:'%s'\n", val); 7312 if (len < 0) { 7313 /* in bash, len=-n means strlen()-n */ 7314 len = (arith_t)vallen - beg + len; 7315 if (len < 0) /* bash compat */ 7316 msg_and_die_if_script("%s: substring expression < 0", var); 7317 } 7318 if (len <= 0 || !val /*|| beg >= vallen*/) { 7319 empty_result: 7320 val = NULL; 7321 } else { 7322 /* Paranoia. What if user entered 9999999999999 7323 * which fits in arith_t but not int? */ 7324 if (len > INT_MAX) 7325 len = INT_MAX; 7326 val = to_be_freed = xstrndup(val + beg, len); 7327 } 7328 debug_printf_varexp("val:'%s'\n", val); 7329#else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */ 7330 msg_and_die_if_script("malformed ${%s:...}", var); 7331 val = NULL; 7332#endif 7333 } else { /* one of "-=+?" */ 7334 /* Standard-mandated substitution ops: 7335 * ${var?word} - indicate error if unset 7336 * If var is unset, word (or a message indicating it is unset 7337 * if word is null) is written to standard error 7338 * and the shell exits with a non-zero exit status. 7339 * Otherwise, the value of var is substituted. 7340 * ${var-word} - use default value 7341 * If var is unset, word is substituted. 7342 * ${var=word} - assign and use default value 7343 * If var is unset, word is assigned to var. 7344 * In all cases, final value of var is substituted. 7345 * ${var+word} - use alternative value 7346 * If var is unset, null is substituted. 7347 * Otherwise, word is substituted. 7348 * 7349 * Word is subjected to tilde expansion, parameter expansion, 7350 * command substitution, and arithmetic expansion. 7351 * If word is not needed, it is not expanded. 7352 * 7353 * Colon forms (${var:-word}, ${var:=word} etc) do the same, 7354 * but also treat null var as if it is unset. 7355 * 7356 * Word-splitting and single quote behavior: 7357 * 7358 * $ f() { for i; do echo "|$i|"; done; } 7359 * 7360 * $ x=; f ${x:?'x y' z}; echo $? 7361 * bash: x: x y z # neither f nor "echo $?" executes 7362 * (if interactive, bash does not exit, but merely aborts to prompt. $? is set to 1) 7363 * $ x=; f "${x:?'x y' z}" 7364 * bash: x: x y z # dash prints: dash: x: 'x y' z 7365 * 7366 * $ x=; f ${x:='x y' z} 7367 * |x| 7368 * |y| 7369 * |z| 7370 * $ x=; f "${x:='x y' z}" 7371 * |'x y' z| 7372 * 7373 * $ x=x; f ${x:+'x y' z} 7374 * |x y| 7375 * |z| 7376 * $ x=x; f "${x:+'x y' z}" 7377 * |'x y' z| 7378 * 7379 * $ x=; f ${x:-'x y' z} 7380 * |x y| 7381 * |z| 7382 * $ x=; f "${x:-'x y' z}" 7383 * |'x y' z| 7384 */ 7385 int use_word = (!val || ((exp_save == ':') && !val[0])); 7386 if (exp_op == '+') 7387 use_word = !use_word; 7388 debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, 7389 (exp_save == ':') ? "true" : "false", use_word); 7390 if (use_word) { 7391 if (exp_op == '+' || exp_op == '-') { 7392 /* ${var+word} - use alternative value */ 7393 /* ${var-word} - use default value */ 7394 n = encode_then_append_var_plusminus(output, n, exp_word, 7395 /*dquoted:*/ (arg0 & 0x80) 7396 ); 7397 val = NULL; 7398 } else { 7399 /* ${var?word} - indicate error if unset */ 7400 /* ${var=word} - assign and use default value */ 7401 to_be_freed = encode_then_expand_vararg(exp_word, 7402 /*handle_squotes:*/ !(arg0 & 0x80), 7403 /*unbackslash:*/ 0 7404 ); 7405 if (to_be_freed) 7406 exp_word = to_be_freed; 7407 if (exp_op == '?') { 7408 /* mimic bash message */ 7409 msg_and_die_if_script("%s: %s", 7410 var, 7411 exp_word[0] 7412 ? exp_word 7413 : "parameter null or not set" 7414 /* ash has more specific messages, a-la: */ 7415 /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/ 7416 ); 7417//TODO: how interactive bash aborts expansion mid-command? 7418//It aborts the entire line, returns to prompt: 7419// $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO 7420// bash: x: x y z 7421// $ 7422// ("echo YO" is not executed, neither the f function call) 7423 } else { 7424 val = exp_word; 7425 } 7426 if (exp_op == '=') { 7427 /* ${var=[word]} or ${var:=[word]} */ 7428 if (isdigit(var[0]) || var[0] == '#') { 7429 /* mimic bash message */ 7430 msg_and_die_if_script("$%s: cannot assign in this way", var); 7431 val = NULL; 7432 } else { 7433 char *new_var = xasprintf("%s=%s", var, val); 7434 set_local_var0(new_var); 7435 } 7436 } 7437 } 7438 } 7439 } /* one of "-=+?" */ 7440 7441 *exp_saveptr = exp_save; 7442 } /* if (exp_op) */ 7443 7444#endif /* !__U_BOOT__ */ 7445 arg[0] = arg0; 7446 *pp = p; 7447 7448 n = append_str_maybe_ifs_split(output, n, first_ch, val); 7449 7450 free(to_be_freed); 7451 return n; 7452} 7453 7454/* Expand all variable references in given string, adding words to list[] 7455 * at n, n+1,... positions. Return updated n (so that list[n] is next one 7456 * to be filled). This routine is extremely tricky: has to deal with 7457 * variables/parameters with whitespace, $* and $@, and constructs like 7458 * 'echo -$*-'. If you play here, you must run testsuite afterwards! */ 7459static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) 7460{ 7461 /* output->o_expflags & EXP_FLAG_SINGLEWORD (0x80) if we are in 7462 * expansion of right-hand side of assignment == 1-element expand. 7463 */ 7464 char cant_be_null = 0; /* only bit 0x80 matters */ 7465 char *p; 7466 7467 debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg, 7468 !!(output->o_expflags & EXP_FLAG_SINGLEWORD)); 7469 debug_print_list("expand_vars_to_list[0]", output, n); 7470 7471 while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { 7472 char first_ch; 7473#if ENABLE_FEATURE_SH_MATH 7474 char arith_buf[sizeof(arith_t)*3 + 2]; 7475#endif 7476 7477 if (output->ended_in_ifs) { 7478 o_addchr(output, '\0'); 7479 n = o_save_ptr(output, n); 7480 output->ended_in_ifs = 0; 7481 } 7482 7483 o_addblock(output, arg, p - arg); 7484 debug_print_list("expand_vars_to_list[1]", output, n); 7485 arg = ++p; 7486 p = strchr(p, SPECIAL_VAR_SYMBOL); 7487 7488 /* Fetch special var name (if it is indeed one of them) 7489 * and quote bit, force the bit on if singleword expansion - 7490 * important for not getting v=$@ expand to many words. */ 7491 first_ch = arg[0] | (output->o_expflags & EXP_FLAG_SINGLEWORD); 7492 7493 /* Is this variable quoted and thus expansion can't be null? 7494 * "$@" is special. Even if quoted, it can still 7495 * expand to nothing (not even an empty string), 7496 * thus it is excluded. */ 7497 if ((first_ch & 0x7f) != '@') 7498 cant_be_null |= first_ch; 7499 7500 switch (first_ch & 0x7f) { 7501 /* Highest bit in first_ch indicates that var is double-quoted */ 7502 case '*': 7503 case '@': { 7504 int i; 7505#ifndef __U_BOOT__ 7506 if (!G.global_argv[1]) 7507#else /* __U_BOOT__ */ 7508 if (!G.global_argv || !G.global_argv[1]) 7509#endif /* __U_BOOT__ */ 7510 break; 7511 i = 1; 7512 cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */ 7513 if (!(first_ch & 0x80)) { /* unquoted $* or $@ */ 7514 while (G.global_argv[i]) { 7515 n = expand_on_ifs(output, n, G.global_argv[i]); 7516 debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1); 7517 if (G.global_argv[i++][0] && G.global_argv[i]) { 7518 /* this argv[] is not empty and not last: 7519 * put terminating NUL, start new word */ 7520 o_addchr(output, '\0'); 7521 debug_print_list("expand_vars_to_list[2]", output, n); 7522 n = o_save_ptr(output, n); 7523 debug_print_list("expand_vars_to_list[3]", output, n); 7524 } 7525 } 7526 } else 7527 /* If EXP_FLAG_SINGLEWORD, we handle assignment 'a=....$@.....' 7528 * and in this case should treat it like '$*' - see 'else...' below */ 7529 if (first_ch == (char)('@'|0x80) /* quoted $@ */ 7530 && !(output->o_expflags & EXP_FLAG_SINGLEWORD) /* not v="$@" case */ 7531 ) { 7532 while (1) { 7533 o_addQstr(output, G.global_argv[i]); 7534 if (++i >= G.global_argc) 7535 break; 7536 o_addchr(output, '\0'); 7537 debug_print_list("expand_vars_to_list[4]", output, n); 7538 n = o_save_ptr(output, n); 7539 } 7540 } else { /* quoted $* (or v="$@" case): add as one word */ 7541 while (1) { 7542 o_addQstr(output, G.global_argv[i]); 7543 if (!G.global_argv[++i]) 7544 break; 7545 if (G.ifs[0]) 7546 o_addchr(output, G.ifs[0]); 7547 } 7548 output->has_quoted_part = 1; 7549 } 7550 break; 7551 } 7552 case SPECIAL_VAR_SYMBOL: { 7553 /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */ 7554 /* "Empty variable", used to make "" etc to not disappear */ 7555 output->has_quoted_part = 1; 7556 cant_be_null = 0x80; 7557 arg++; 7558 break; 7559 } 7560 case SPECIAL_VAR_QUOTED_SVS: 7561 /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_QUOTED_SVS><SPECIAL_VAR_SYMBOL> */ 7562 /* "^C variable", represents literal ^C char (possible in scripts) */ 7563 o_addchr(output, SPECIAL_VAR_SYMBOL); 7564 arg++; 7565 break; 7566#if ENABLE_HUSH_TICK 7567 case '`': { 7568 /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */ 7569 o_string subst_result = NULL_O_STRING; 7570 7571 *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */ 7572 arg++; 7573 /* Can't just stuff it into output o_string, 7574 * expanded result may need to be globbed 7575 * and $IFS-split */ 7576 debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); 7577 G.last_exitcode = process_command_subs(&subst_result, arg); 7578 G.expand_exitcode = G.last_exitcode; 7579 debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); 7580 n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data); 7581 o_free(&subst_result); 7582 break; 7583 } 7584#endif 7585#if ENABLE_FEATURE_SH_MATH 7586 case '+': { 7587 /* <SPECIAL_VAR_SYMBOL>+arith<SPECIAL_VAR_SYMBOL> */ 7588 arith_t res; 7589 7590 arg++; /* skip '+' */ 7591 *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */ 7592 debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch); 7593 res = expand_and_evaluate_arith(arg, NULL); 7594 debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res); 7595 sprintf(arith_buf, ARITH_FMT, res); 7596 if (res < 0 7597 && first_ch == (char)('+'|0x80) 7598 /* && (output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS) */ 7599 ) { 7600 /* Quoted negative ariths, like filename[0"$((-9))"], 7601 * should not be interpreted as glob ranges. 7602 * Convert leading '-' to '\-': 7603 */ 7604 o_grow_by(output, 1); 7605 output->data[output->length++] = '\\'; 7606 } 7607 o_addstr(output, arith_buf); 7608 break; 7609 } 7610#endif 7611 default: 7612 /* <SPECIAL_VAR_SYMBOL>varname[ops]<SPECIAL_VAR_SYMBOL> */ 7613 n = expand_one_var(output, n, first_ch, arg, &p); 7614 break; 7615 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ 7616 7617 /* Restore NULL'ed SPECIAL_VAR_SYMBOL. 7618 * Do the check to avoid writing to a const string. */ 7619 if (*p != SPECIAL_VAR_SYMBOL) 7620 *p = SPECIAL_VAR_SYMBOL; 7621 arg = ++p; 7622 } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */ 7623 7624 if (*arg) { 7625 /* handle trailing string */ 7626 if (output->ended_in_ifs) { 7627 o_addchr(output, '\0'); 7628 n = o_save_ptr(output, n); 7629 } 7630 debug_print_list("expand_vars_to_list[a]", output, n); 7631 /* this part is literal, and it was already pre-quoted 7632 * if needed (much earlier), do not use o_addQstr here! 7633 */ 7634 o_addstr(output, arg); 7635 debug_print_list("expand_vars_to_list[b]", output, n); 7636 } else 7637 if (output->length == o_get_last_ptr(output, n) /* expansion is empty */ 7638 && !(cant_be_null & 0x80) /* and all vars were not quoted */ 7639 && !output->has_quoted_part 7640 ) { 7641 n--; 7642 /* allow to reuse list[n] later without re-growth */ 7643 output->has_empty_slot = 1; 7644 } 7645 7646 return n; 7647} 7648 7649static char **expand_variables(char **argv, unsigned expflags) 7650{ 7651 int n; 7652 char **list; 7653 o_string output = NULL_O_STRING; 7654 7655 output.o_expflags = expflags; 7656 7657 n = 0; 7658 for (;;) { 7659 /* go to next list[n] */ 7660 output.ended_in_ifs = 0; 7661 n = o_save_ptr(&output, n); 7662 7663 if (!*argv) 7664 break; 7665 7666 /* expand argv[i] */ 7667 n = expand_vars_to_list(&output, n, *argv++); 7668 /* if (!output->has_empty_slot) -- need this?? */ 7669 o_addchr(&output, '\0'); 7670 } 7671 debug_print_list("expand_variables", &output, n); 7672 7673 /* output.data (malloced in one block) gets returned in "list" */ 7674 list = o_finalize_list(&output, n); 7675 debug_print_strings("expand_variables[1]", list); 7676 return list; 7677} 7678 7679static char **expand_strvec_to_strvec(char **argv) 7680{ 7681 return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS); 7682} 7683 7684#if defined(CMD_SINGLEWORD_NOGLOB) || defined(CMD_TEST2_SINGLEWORD_NOGLOB) 7685static char **expand_strvec_to_strvec_singleword_noglob(char **argv) 7686{ 7687 return expand_variables(argv, EXP_FLAG_SINGLEWORD); 7688} 7689#endif 7690 7691/* Used for expansion of right hand of assignments, 7692 * $((...)), heredocs, variable expansion parts. 7693 * 7694 * NB: should NOT do globbing! 7695 * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*" 7696 */ 7697static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash) 7698{ 7699#if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE 7700 const int do_unbackslash = 1; 7701 const int EXP_flags = EXP_FLAG_ESC_GLOB_CHARS; 7702#endif 7703 char *argv[2], **list; 7704 7705 debug_printf_expand("string_to_string<='%s'\n", str); 7706 /* This is generally an optimization, but it also 7707 * handles "", which otherwise trips over !list[0] check below. 7708 * (is this ever happens that we actually get str="" here?) 7709 */ 7710 if (!strchr(str, SPECIAL_VAR_SYMBOL) && !strchr(str, '\\')) { 7711 //TODO: Can use on strings with \ too, just unbackslash() them? 7712 debug_printf_expand("string_to_string(fast)=>'%s'\n", str); 7713 return xstrdup(str); 7714 } 7715 7716 argv[0] = (char*)str; 7717 argv[1] = NULL; 7718 list = expand_variables(argv, EXP_flags | EXP_FLAG_SINGLEWORD); 7719 if (!list[0]) { 7720 /* Example where it happens: 7721 * x=; echo ${x:-"$@"} 7722 */ 7723 ((char*)list)[0] = '\0'; 7724 } else { 7725 if (HUSH_DEBUG) 7726 if (list[1]) 7727 bb_simple_error_msg_and_die("BUG in varexp2"); 7728 /* actually, just move string 2*sizeof(char*) bytes back */ 7729 overlapping_strcpy((char*)list, list[0]); 7730 if (do_unbackslash) 7731 unbackslash((char*)list); 7732 } 7733 debug_printf_expand("string_to_string=>'%s'\n", (char*)list); 7734 return (char*)list; 7735} 7736 7737#if 0 7738static char* expand_strvec_to_string(char **argv) 7739{ 7740 char **list; 7741 7742 list = expand_variables(argv, EXP_FLAG_SINGLEWORD); 7743 /* Convert all NULs to spaces */ 7744 if (list[0]) { 7745 int n = 1; 7746 while (list[n]) { 7747 if (HUSH_DEBUG) 7748 if (list[n-1] + strlen(list[n-1]) + 1 != list[n]) 7749 bb_error_msg_and_die("BUG in varexp3"); 7750 /* bash uses ' ' regardless of $IFS contents */ 7751 list[n][-1] = ' '; 7752 n++; 7753 } 7754 } 7755 overlapping_strcpy((char*)list, list[0] ? list[0] : ""); 7756 debug_printf_expand("strvec_to_string='%s'\n", (char*)list); 7757 return (char*)list; 7758} 7759#endif 7760 7761#ifndef __U_BOOT__ 7762static char **expand_assignments(char **argv, int count) 7763{ 7764 int i; 7765 char **p; 7766 7767 G.expanded_assignments = p = NULL; 7768 /* Expand assignments into one string each */ 7769 for (i = 0; i < count; i++) { 7770 p = add_string_to_strings(p, 7771 expand_string_to_string(argv[i], 7772 EXP_FLAG_ESC_GLOB_CHARS, 7773 /*unbackslash:*/ 1 7774 ) 7775 ); 7776 G.expanded_assignments = p; 7777 } 7778 G.expanded_assignments = NULL; 7779 return p; 7780} 7781 7782static void switch_off_special_sigs(unsigned mask) 7783{ 7784 unsigned sig = 0; 7785 while ((mask >>= 1) != 0) { 7786 sig++; 7787 if (!(mask & 1)) 7788 continue; 7789#if ENABLE_HUSH_TRAP 7790 if (G_traps) { 7791 if (G_traps[sig] && !G_traps[sig][0]) 7792 /* trap is '', has to remain SIG_IGN */ 7793 continue; 7794 free(G_traps[sig]); 7795 G_traps[sig] = NULL; 7796 } 7797#endif 7798 /* We are here only if no trap or trap was not '' */ 7799 install_sighandler(sig, SIG_DFL); 7800 } 7801} 7802#endif /* !__U_BOOT__ */ 7803 7804#ifndef __U_BOOT__ 7805#if BB_MMU 7806/* never called */ 7807void re_execute_shell(char ***to_free, const char *s, 7808 char *g_argv0, char **g_argv, 7809 char **builtin_argv) NORETURN; 7810 7811static void reset_traps_to_defaults(void) 7812{ 7813 /* This function is always called in a child shell 7814 * after fork (not vfork, NOMMU doesn't use this function). 7815 */ 7816 IF_HUSH_TRAP(unsigned sig;) 7817 unsigned mask; 7818 7819 /* Child shells are not interactive. 7820 * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling. 7821 * Testcase: (while :; do :; done) + ^Z should background. 7822 * Same goes for SIGTERM, SIGHUP, SIGINT. 7823 */ 7824 mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask; 7825 if (!G_traps && !mask) 7826 return; /* already no traps and no special sigs */ 7827 7828 /* Switch off special sigs */ 7829 switch_off_special_sigs(mask); 7830# if ENABLE_HUSH_JOB 7831 G_fatal_sig_mask = 0; 7832# endif 7833 G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS; 7834 /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS 7835 * remain set in G.special_sig_mask */ 7836 7837# if ENABLE_HUSH_TRAP 7838 if (!G_traps) 7839 return; 7840 7841 /* Reset all sigs to default except ones with empty traps */ 7842 for (sig = 0; sig < NSIG; sig++) { 7843 if (!G_traps[sig]) 7844 continue; /* no trap: nothing to do */ 7845 if (!G_traps[sig][0]) 7846 continue; /* empty trap: has to remain SIG_IGN */ 7847 /* sig has non-empty trap, reset it: */ 7848 free(G_traps[sig]); 7849 G_traps[sig] = NULL; 7850 /* There is no signal for trap 0 (EXIT) */ 7851 if (sig == 0) 7852 continue; 7853 install_sighandler(sig, pick_sighandler(sig)); 7854 } 7855# endif 7856} 7857 7858#else /* !BB_MMU */ 7859 7860static void re_execute_shell(char ***to_free, const char *s, 7861 char *g_argv0, char **g_argv, 7862 char **builtin_argv) NORETURN; 7863static void re_execute_shell(char ***to_free, const char *s, 7864 char *g_argv0, char **g_argv, 7865 char **builtin_argv) 7866{ 7867# define NOMMU_HACK_FMT ("-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x")) 7868 /* delims + 2 * (number of bytes in printed hex numbers) */ 7869 char param_buf[sizeof(NOMMU_HACK_FMT) + 2 * (sizeof(int)*6 + sizeof(long long)*1)]; 7870 char *heredoc_argv[4]; 7871 struct variable *cur; 7872# if ENABLE_HUSH_FUNCTIONS 7873 struct function *funcp; 7874# endif 7875 char **argv, **pp; 7876 unsigned cnt; 7877 unsigned long long empty_trap_mask; 7878 7879 if (!g_argv0) { /* heredoc */ 7880 argv = heredoc_argv; 7881 argv[0] = (char *) G.argv0_for_re_execing; 7882 argv[1] = (char *) "-<"; 7883 argv[2] = (char *) s; 7884 argv[3] = NULL; 7885 pp = &argv[3]; /* used as pointer to empty environment */ 7886 goto do_exec; 7887 } 7888 7889 cnt = 0; 7890 pp = builtin_argv; 7891 if (pp) while (*pp++) 7892 cnt++; 7893 7894 empty_trap_mask = 0; 7895 if (G_traps) { 7896 int sig; 7897 for (sig = 1; sig < NSIG; sig++) { 7898 if (G_traps[sig] && !G_traps[sig][0]) 7899 empty_trap_mask |= 1LL << sig; 7900 } 7901 } 7902 7903 sprintf(param_buf, NOMMU_HACK_FMT 7904 , (unsigned) G.root_pid 7905 , (unsigned) G.root_ppid 7906 , (unsigned) G.last_bg_pid 7907 , (unsigned) G.last_exitcode 7908 , cnt 7909 , empty_trap_mask 7910 IF_HUSH_LOOPS(, G.depth_of_loop) 7911 ); 7912# undef NOMMU_HACK_FMT 7913 /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<etc...> <vars...> <funcs...> 7914 * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL 7915 */ 7916 cnt += 6; 7917 for (cur = G.top_var; cur; cur = cur->next) { 7918 if (!cur->flg_export || cur->flg_read_only) 7919 cnt += 2; 7920 } 7921# if ENABLE_HUSH_LINENO_VAR 7922 cnt += 2; 7923# endif 7924# if ENABLE_HUSH_FUNCTIONS 7925 for (funcp = G.top_func; funcp; funcp = funcp->next) 7926 cnt += 3; 7927# endif 7928 pp = g_argv; 7929 while (*pp++) 7930 cnt++; 7931 *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt); 7932 *pp++ = (char *) G.argv0_for_re_execing; 7933 *pp++ = param_buf; 7934 for (cur = G.top_var; cur; cur = cur->next) { 7935 if (strcmp(cur->varstr, hush_version_str) == 0) 7936 continue; 7937 if (cur->flg_read_only) { 7938 *pp++ = (char *) "-R"; 7939 *pp++ = cur->varstr; 7940 } else if (!cur->flg_export) { 7941 *pp++ = (char *) "-V"; 7942 *pp++ = cur->varstr; 7943 } 7944 } 7945# if ENABLE_HUSH_LINENO_VAR 7946 *pp++ = (char *) "-L"; 7947 *pp++ = utoa(G.execute_lineno); 7948# endif 7949# if ENABLE_HUSH_FUNCTIONS 7950 for (funcp = G.top_func; funcp; funcp = funcp->next) { 7951 *pp++ = (char *) "-F"; 7952 *pp++ = funcp->name; 7953 *pp++ = funcp->body_as_string; 7954 } 7955# endif 7956 /* We can pass activated traps here. Say, -Tnn:trap_string 7957 * 7958 * However, POSIX says that subshells reset signals with traps 7959 * to SIG_DFL. 7960 * I tested bash-3.2 and it not only does that with true subshells 7961 * of the form ( list ), but with any forked children shells. 7962 * I set trap "echo W" WINCH; and then tried: 7963 * 7964 * { echo 1; sleep 20; echo 2; } & 7965 * while true; do echo 1; sleep 20; echo 2; break; done & 7966 * true | { echo 1; sleep 20; echo 2; } | cat 7967 * 7968 * In all these cases sending SIGWINCH to the child shell 7969 * did not run the trap. If I add trap "echo V" WINCH; 7970 * _inside_ group (just before echo 1), it works. 7971 * 7972 * I conclude it means we don't need to pass active traps here. 7973 */ 7974 *pp++ = (char *) "-c"; 7975 *pp++ = (char *) s; 7976 if (builtin_argv) { 7977 while (*++builtin_argv) 7978 *pp++ = *builtin_argv; 7979 *pp++ = (char *) ""; 7980 } 7981 *pp++ = g_argv0; 7982 while (*g_argv) 7983 *pp++ = *g_argv++; 7984 /* *pp = NULL; - is already there */ 7985 pp = environ; 7986 7987 do_exec: 7988 debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s); 7989 /* Don't propagate SIG_IGN to the child */ 7990 if (SPECIAL_JOBSTOP_SIGS != 0) 7991 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); 7992 execve(bb_busybox_exec_path, argv, pp); 7993 /* Fallback. Useful for init=/bin/hush usage etc */ 7994 if (argv[0][0] == '/') 7995 execve(argv[0], argv, pp); 7996 xfunc_error_retval = 127; 7997 bb_simple_error_msg_and_die("can't re-execute the shell"); 7998} 7999#endif /* !BB_MMU */ 8000 8001#endif /* !__U_BOOT__ */ 8002 8003static int run_and_free_list(struct pipe *pi); 8004 8005/* Executing from string: eval, sh -c '...' 8006 * or from file: /etc/profile, . file, sh <script>, sh (intereactive) 8007 * end_trigger controls how often we stop parsing 8008 * NUL: parse all, execute, return 8009 * ';': parse till ';' or newline, execute, repeat till EOF 8010 */ 8011#ifndef __U_BOOT__ 8012static void parse_and_run_stream(struct in_str *inp, int end_trigger) 8013#else /* __U_BOOT__ */ 8014static int parse_and_run_stream(struct in_str *inp, int end_trigger) 8015#endif /* __U_BOOT__ */ 8016{ 8017 /* Why we need empty flag? 8018 * An obscure corner case "false; ``; echo $?": 8019 * empty command in `` should still set $? to 0. 8020 * But we can't just set $? to 0 at the start, 8021 * this breaks "false; echo `echo $?`" case. 8022 */ 8023 bool empty = 1; 8024#ifndef __U_BOOT__ 8025 while (1) { 8026#else /* __U_BOOT__ */ 8027 do { 8028#endif /* __U_BOOT__ */ 8029 struct pipe *pipe_list; 8030 8031#if ENABLE_HUSH_INTERACTIVE 8032 if (end_trigger == ';') { 8033 G.promptmode = 0; /* PS1 */ 8034 debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode); 8035 } 8036#endif 8037 pipe_list = parse_stream(NULL, NULL, inp, end_trigger); 8038 if (!pipe_list || pipe_list == ERR_PTR) { /* EOF/error */ 8039 /* If we are in "big" script 8040 * (not in `cmd` or something similar)... 8041 */ 8042 if (pipe_list == ERR_PTR && end_trigger == ';') { 8043 /* Discard cached input (rest of line) */ 8044 int ch = inp->last_char; 8045 while (ch != EOF && ch != '\n') { 8046 //bb_error_msg("Discarded:'%c'", ch); 8047 ch = i_getch(inp); 8048 } 8049 /* Force prompt */ 8050 inp->p = NULL; 8051 /* This stream isn't empty */ 8052 empty = 0; 8053 continue; 8054 } 8055 if (!pipe_list && empty) 8056 G.last_exitcode = 0; 8057 break; 8058 } 8059 debug_print_tree(pipe_list, 0); 8060 debug_printf_exec("parse_and_run_stream: run_and_free_list\n"); 8061#ifndef __U_BOOT__ 8062 run_and_free_list(pipe_list); 8063#else /* __U_BOOT__ */ 8064 int rcode = run_and_free_list(pipe_list); 8065 /* 8066 * We reset input string to not run the following command, so running 8067 * 'exit; echo foo' does not print foo. 8068 */ 8069 if (rcode <= EXIT_RET_CODE) 8070 setup_file_in_str(inp); 8071#endif /* __U_BOOT__ */ 8072 empty = 0; 8073 if (G_flag_return_in_progress == 1) 8074 break; 8075#ifndef __U_BOOT__ 8076 } 8077#else /* __U_BOOT__ */ 8078 /* 8079 * This do/while is needed by run_command to avoid looping on a command 8080 * with syntax error. 8081 */ 8082 } while (!(G.run_command_flags & FLAG_EXIT_FROM_LOOP)); 8083 8084 return G.last_exitcode; 8085#endif /* __U_BOOT__ */ 8086} 8087 8088#ifndef __U_BOOT__ 8089static void parse_and_run_string(const char *s) 8090#else /* __U_BOOT__ */ 8091static int parse_and_run_string(const char *s) 8092#endif /* __U_BOOT__ */ 8093{ 8094 struct in_str input; 8095#ifndef __U_BOOT__ 8096 IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) 8097#else /* __U_BOOT__ */ 8098 //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) 8099#endif /* __U_BOOT__ */ 8100 8101 setup_string_in_str(&input, s); 8102#ifndef __U_BOOT__ 8103 parse_and_run_stream(&input, '\0'); 8104#else /* __U_BOOT__ */ 8105 return parse_and_run_stream(&input, '\0'); 8106#endif /* __U_BOOT__ */ 8107#ifndef __U_BOOT__ 8108 IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) 8109#else /* __U_BOOT__ */ 8110 //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) 8111#endif /* __U_BOOT__ */ 8112} 8113 8114#ifdef __U_BOOT__ 8115int parse_string_outer_modern(const char *cmd, int flags) 8116{ 8117 int ret; 8118 int old_flags; 8119 8120 /* 8121 * Keep old values of run_command to be able to restore them once 8122 * command was executed. 8123 */ 8124 old_flags = G.run_command_flags; 8125 G.run_command_flags = flags; 8126 8127 ret = parse_and_run_string(cmd); 8128 8129 G.run_command_flags = old_flags; 8130 8131 return ret; 8132} 8133#endif /* __U_BOOT__ */ 8134#ifndef __U_BOOT__ 8135static void parse_and_run_file(HFILE *fp) 8136#else /* __U_BOOT__ */ 8137void parse_and_run_file(void) 8138#endif /* __U_BOOT__ */ 8139{ 8140 struct in_str input; 8141#ifndef __U_BOOT__ 8142 IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;) 8143 8144 IF_HUSH_LINENO_VAR(G.parse_lineno = 1;) 8145 setup_file_in_str(&input, fp); 8146#else /* __U_BOOT__ */ 8147 setup_file_in_str(&input); 8148#endif /* __U_BOOT__ */ 8149 parse_and_run_stream(&input, ';'); 8150#ifndef __U_BOOT__ 8151 IF_HUSH_LINENO_VAR(G.parse_lineno = sv;) 8152#endif /* !__U_BOOT__ */ 8153} 8154 8155#ifndef __U_BOOT__ 8156#if ENABLE_HUSH_TICK 8157static int generate_stream_from_string(const char *s, pid_t *pid_p) 8158{ 8159 pid_t pid; 8160 int channel[2]; 8161# if !BB_MMU 8162 char **to_free = NULL; 8163# endif 8164 8165 xpipe(channel); 8166 pid = BB_MMU ? xfork() : xvfork(); 8167 if (pid == 0) { /* child */ 8168 disable_restore_tty_pgrp_on_exit(); 8169 /* Process substitution is not considered to be usual 8170 * 'command execution'. 8171 * SUSv3 says ctrl-Z should be ignored, ctrl-C should not. 8172 */ 8173 bb_signals(0 8174 + (1 << SIGTSTP) 8175 + (1 << SIGTTIN) 8176 + (1 << SIGTTOU) 8177 , SIG_IGN); 8178 close(channel[0]); /* NB: close _first_, then move fd! */ 8179 xmove_fd(channel[1], 1); 8180# if ENABLE_HUSH_TRAP 8181 /* Awful hack for `trap` or $(trap). 8182 * 8183 * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html 8184 * contains an example where "trap" is executed in a subshell: 8185 * 8186 * save_traps=$(trap) 8187 * ... 8188 * eval "$save_traps" 8189 * 8190 * Standard does not say that "trap" in subshell shall print 8191 * parent shell's traps. It only says that its output 8192 * must have suitable form, but then, in the above example 8193 * (which is not supposed to be normative), it implies that. 8194 * 8195 * bash (and probably other shell) does implement it 8196 * (traps are reset to defaults, but "trap" still shows them), 8197 * but as a result, "trap" logic is hopelessly messed up: 8198 * 8199 * # trap 8200 * trap -- 'echo Ho' SIGWINCH <--- we have a handler 8201 * # (trap) <--- trap is in subshell - no output (correct, traps are reset) 8202 * # true | trap <--- trap is in subshell - no output (ditto) 8203 * # echo `true | trap` <--- in subshell - output (but traps are reset!) 8204 * trap -- 'echo Ho' SIGWINCH 8205 * # echo `(trap)` <--- in subshell in subshell - output 8206 * trap -- 'echo Ho' SIGWINCH 8207 * # echo `true | (trap)` <--- in subshell in subshell in subshell - output! 8208 * trap -- 'echo Ho' SIGWINCH 8209 * 8210 * The rules when to forget and when to not forget traps 8211 * get really complex and nonsensical. 8212 * 8213 * Our solution: ONLY bare $(trap) or `trap` is special. 8214 */ 8215 s = skip_whitespace(s); 8216 if (is_prefixed_with(s, "trap") 8217 && skip_whitespace(s + 4)[0] == '\0' 8218 ) { 8219 static const char *const argv[] ALIGN_PTR = { NULL, NULL }; 8220 builtin_trap((char**)argv); 8221 fflush_all(); /* important */ 8222 _exit(0); 8223 } 8224# endif 8225# if BB_MMU 8226 /* Prevent it from trying to handle ctrl-z etc */ 8227 IF_HUSH_JOB(G.run_list_level = 1;) 8228 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ 8229 reset_traps_to_defaults(); 8230 IF_HUSH_MODE_X(G.x_mode_depth++;) 8231 //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); 8232 parse_and_run_string(s); 8233 _exit(G.last_exitcode); 8234# else 8235 /* We re-execute after vfork on NOMMU. This makes this script safe: 8236 * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG 8237 * huge=`cat BIG` # was blocking here forever 8238 * echo OK 8239 */ 8240 re_execute_shell(&to_free, 8241 s, 8242 G.global_argv[0], 8243 G.global_argv + 1, 8244 NULL); 8245# endif 8246 } 8247 8248 /* parent */ 8249 *pid_p = pid; 8250# if ENABLE_HUSH_FAST 8251 G.count_SIGCHLD++; 8252//bb_error_msg("[%d] fork in generate_stream_from_string:" 8253// " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", 8254// getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); 8255# endif 8256 enable_restore_tty_pgrp_on_exit(); 8257# if !BB_MMU 8258 free(to_free); 8259# endif 8260 close(channel[1]); 8261 return channel[0]; 8262} 8263 8264/* Return code is exit status of the process that is run. */ 8265static int process_command_subs(o_string *dest, const char *s) 8266{ 8267 FILE *fp; 8268 pid_t pid; 8269 int status, ch, eol_cnt; 8270 8271 fp = xfdopen_for_read(generate_stream_from_string(s, &pid)); 8272 8273 /* Now send results of command back into original context */ 8274 eol_cnt = 0; 8275 while ((ch = getc(fp)) != EOF) { 8276 if (ch == '\0') 8277 continue; 8278 if (ch == '\n') { 8279 eol_cnt++; 8280 continue; 8281 } 8282 while (eol_cnt) { 8283 o_addchr(dest, '\n'); 8284 eol_cnt--; 8285 } 8286 o_addQchr(dest, ch); 8287 } 8288 8289 debug_printf("done reading from `cmd` pipe, closing it\n"); 8290 fclose(fp); 8291 /* We need to extract exitcode. Test case 8292 * "true; echo `sleep 1; false` $?" 8293 * should print 1 */ 8294 safe_waitpid(pid, &status, 0); 8295 debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status)); 8296 return WEXITSTATUS(status); 8297} 8298#endif /* ENABLE_HUSH_TICK */ 8299 8300static void setup_heredoc(struct redir_struct *redir) 8301{ 8302 struct fd_pair pair; 8303 pid_t pid; 8304 int len, written; 8305 /* the _body_ of heredoc (misleading field name) */ 8306 const char *heredoc = redir->rd_filename; 8307 char *expanded; 8308#if !BB_MMU 8309 char **to_free; 8310#endif 8311 8312 expanded = NULL; 8313 if (!(redir->rd_dup & HEREDOC_QUOTED)) { 8314 expanded = encode_then_expand_string(heredoc); 8315 if (expanded) 8316 heredoc = expanded; 8317 } 8318 len = strlen(heredoc); 8319 8320 close(redir->rd_fd); /* often saves dup2+close in xmove_fd */ 8321 xpiped_pair(pair); 8322 xmove_fd(pair.rd, redir->rd_fd); 8323 8324 /* Try writing without forking. Newer kernels have 8325 * dynamically growing pipes. Must use non-blocking write! */ 8326 ndelay_on(pair.wr); 8327 while (1) { 8328 written = write(pair.wr, heredoc, len); 8329 if (written <= 0) 8330 break; 8331 len -= written; 8332 if (len == 0) { 8333 close(pair.wr); 8334 free(expanded); 8335 return; 8336 } 8337 heredoc += written; 8338 } 8339 ndelay_off(pair.wr); 8340 8341 /* Okay, pipe buffer was not big enough */ 8342 /* Note: we must not create a stray child (bastard? :) 8343 * for the unsuspecting parent process. Child creates a grandchild 8344 * and exits before parent execs the process which consumes heredoc 8345 * (that exec happens after we return from this function) */ 8346#if !BB_MMU 8347 to_free = NULL; 8348#endif 8349 pid = xvfork(); 8350 if (pid == 0) { 8351 /* child */ 8352 disable_restore_tty_pgrp_on_exit(); 8353 pid = BB_MMU ? xfork() : xvfork(); 8354 if (pid != 0) 8355 _exit(0); 8356 /* grandchild */ 8357 close(redir->rd_fd); /* read side of the pipe */ 8358#if BB_MMU 8359 full_write(pair.wr, heredoc, len); /* may loop or block */ 8360 _exit(0); 8361#else 8362 /* Delegate blocking writes to another process */ 8363 xmove_fd(pair.wr, STDOUT_FILENO); 8364 re_execute_shell(&to_free, heredoc, NULL, NULL, NULL); 8365#endif 8366 } 8367 /* parent */ 8368#if ENABLE_HUSH_FAST 8369 G.count_SIGCHLD++; 8370//bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); 8371#endif 8372 enable_restore_tty_pgrp_on_exit(); 8373#if !BB_MMU 8374 free(to_free); 8375#endif 8376 close(pair.wr); 8377 free(expanded); 8378 wait(NULL); /* wait till child has died */ 8379} 8380 8381struct squirrel { 8382 int orig_fd; 8383 int moved_to; 8384 /* moved_to = n: fd was moved to n; restore back to orig_fd after redir */ 8385 /* moved_to = -1: fd was opened by redirect; close orig_fd after redir */ 8386}; 8387 8388static struct squirrel *append_squirrel(struct squirrel *sq, int i, int orig, int moved) 8389{ 8390 sq = xrealloc(sq, (i + 2) * sizeof(sq[0])); 8391 sq[i].orig_fd = orig; 8392 sq[i].moved_to = moved; 8393 sq[i+1].orig_fd = -1; /* end marker */ 8394 return sq; 8395} 8396 8397static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd) 8398{ 8399 int moved_to; 8400 int i; 8401 8402 i = 0; 8403 if (sq) for (; sq[i].orig_fd >= 0; i++) { 8404 /* If we collide with an already moved fd... */ 8405 if (fd == sq[i].moved_to) { 8406 moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd); 8407 debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, moved_to); 8408 if (moved_to < 0) { 8409 /* "echo 2>/dev/tty 10>&9999" testcase: 8410 * We move fd 2 to 10, then discover we need to move fd 10 8411 * (and not hit 9999) and the latter fails. 8412 */ 8413 return NULL; /* fcntl failed */ 8414 } 8415 sq[i].moved_to = moved_to; 8416 return sq; 8417 } 8418 if (fd == sq[i].orig_fd) { 8419 /* Example: echo Hello >/dev/null 1>&2 */ 8420 debug_printf_redir("redirect_fd %d: already moved\n", fd); 8421 return sq; 8422 } 8423 } 8424 8425 /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */ 8426 moved_to = dup_CLOEXEC(fd, avoid_fd); 8427 debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to); 8428 if (moved_to < 0 && errno != EBADF) 8429 return NULL; /* fcntl failed (not because fd is closed) */ 8430 return append_squirrel(sq, i, fd, moved_to); 8431} 8432 8433static struct squirrel *add_squirrel_closed(struct squirrel *sq, int fd) 8434{ 8435 int i; 8436 8437 i = 0; 8438 if (sq) for (; sq[i].orig_fd >= 0; i++) { 8439 /* If we collide with an already moved fd... */ 8440 if (fd == sq[i].orig_fd) { 8441 /* Examples: 8442 * "echo 3>FILE 3>&- 3>FILE" 8443 * "echo 3>&- 3>FILE" 8444 * No need for last redirect to insert 8445 * another "need to close 3" indicator. 8446 */ 8447 debug_printf_redir("redirect_fd %d: already moved or closed\n", fd); 8448 return sq; 8449 } 8450 } 8451 8452 debug_printf_redir("redirect_fd %d: previous fd was closed\n", fd); 8453 return append_squirrel(sq, i, fd, -1); 8454} 8455 8456/* fd: redirect wants this fd to be used (e.g. 3>file). 8457 * Move all conflicting internally used fds, 8458 * and remember them so that we can restore them later. 8459 */ 8460static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp) 8461{ 8462 struct squirrel *new_squirrel; 8463 8464 if (avoid_fd < 9) /* the important case here is that it can be -1 */ 8465 avoid_fd = 9; 8466 8467#if ENABLE_HUSH_INTERACTIVE 8468 if (fd != 0 /* don't trigger for G_interactive_fd == 0 (that's "not interactive" flag) */ 8469 && fd == G_interactive_fd 8470 ) { 8471 /* Testcase: "ls -l /proc/$$/fd 255>&-" should work */ 8472 G_interactive_fd = xdup_CLOEXEC_and_close(G_interactive_fd, avoid_fd); 8473 debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G_interactive_fd); 8474 return 1; /* "we closed fd" */ 8475 } 8476#endif 8477 /* Are we called from setup_redirects(squirrel==NULL) 8478 * in redirect in a [v]forked child? 8479 */ 8480 if (sqp == NULL) { 8481 /* No need to move script fds. 8482 * For NOMMU case, it's actively wrong: we'd change ->fd 8483 * fields in memory for the parent, but parent's fds 8484 * aren't moved, it would use wrong fd! 8485 * Reproducer: "cmd 3>FILE" in script. 8486 * If we would call move_HFILEs_on_redirect(), child would: 8487 * fcntl64(3, F_DUPFD_CLOEXEC, 10) = 10 8488 * close(3) = 0 8489 * and change ->fd to 10 if fd#3 is a script fd. WRONG. 8490 */ 8491 //bb_error_msg("sqp == NULL: [v]forked child"); 8492 return 0; 8493 } 8494 8495 /* If this one of script's fds? */ 8496 if (move_HFILEs_on_redirect(fd, avoid_fd)) 8497 return 1; /* yes. "we closed fd" (actually moved it) */ 8498 8499 /* Are we called for "exec 3>FILE"? Came through 8500 * redirect_and_varexp_helper(squirrel=ERR_PTR) -> setup_redirects(ERR_PTR) 8501 * This case used to fail for this script: 8502 * exec 3>FILE 8503 * echo Ok 8504 * ...100000 more lines... 8505 * echo Ok 8506 * as follows: 8507 * read(3, "exec 3>FILE\necho Ok\necho Ok"..., 1024) = 1024 8508 * open("FILE", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4 8509 * dup2(4, 3) = 3 8510 * ^^^^^^^^ oops, we lost fd#3 opened to our script! 8511 * close(4) = 0 8512 * write(1, "Ok\n", 3) = 3 8513 * ... = 3 8514 * write(1, "Ok\n", 3) = 3 8515 * read(3, 0x94fbc08, 1024) = -1 EBADF (Bad file descriptor) 8516 * ^^^^^^^^ oops, wrong fd!!! 8517 * With this case separate from sqp == NULL and *after* move_HFILEs, 8518 * it now works: 8519 */ 8520 if (sqp == ERR_PTR) { 8521 /* Don't preserve redirected fds: exec is _meant_ to change these */ 8522 //bb_error_msg("sqp == ERR_PTR: exec >FILE"); 8523 return 0; 8524 } 8525 8526 /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */ 8527 new_squirrel = add_squirrel(*sqp, fd, avoid_fd); 8528 if (!new_squirrel) 8529 return -1; /* redirect error */ 8530 *sqp = new_squirrel; 8531 return 0; /* "we did not close fd" */ 8532} 8533 8534static void restore_redirects(struct squirrel *sq) 8535{ 8536 if (sq) { 8537 int i; 8538 for (i = 0; sq[i].orig_fd >= 0; i++) { 8539 if (sq[i].moved_to >= 0) { 8540 /* We simply die on error */ 8541 debug_printf_redir("restoring redirected fd from %d to %d\n", sq[i].moved_to, sq[i].orig_fd); 8542 xmove_fd(sq[i].moved_to, sq[i].orig_fd); 8543 } else { 8544 /* cmd1 9>FILE; cmd2_should_see_fd9_closed */ 8545 debug_printf_redir("restoring redirected fd %d: closing it\n", sq[i].orig_fd); 8546 close(sq[i].orig_fd); 8547 } 8548 } 8549 free(sq); 8550 } 8551 if (G.HFILE_stdin 8552 && G.HFILE_stdin->fd > STDIN_FILENO 8553 /* we compare > STDIN, not == STDIN, since hfgetc() 8554 * closes fd and sets ->fd to -1 if EOF is reached. 8555 * Testcase: echo 'pwd' | hush 8556 */ 8557 ) { 8558 /* Testcase: interactive "read r <FILE; echo $r; read r; echo $r". 8559 * Redirect moves ->fd to e.g. 10, 8560 * and it is not restored above (we do not restore script fds 8561 * after redirects, we just use new, "moved" fds). 8562 * However for stdin, get_user_input() -> read_line_input(), 8563 * and read builtin, depend on fd == STDIN_FILENO. 8564 */ 8565 debug_printf_redir("restoring %d to stdin\n", G.HFILE_stdin->fd); 8566 xmove_fd(G.HFILE_stdin->fd, STDIN_FILENO); 8567 G.HFILE_stdin->fd = STDIN_FILENO; 8568 } 8569 8570 /* If moved, G_interactive_fd stays on new fd, not restoring it */ 8571} 8572 8573#if ENABLE_FEATURE_SH_STANDALONE && BB_MMU 8574static void close_saved_fds_and_FILE_fds(void) 8575{ 8576 if (G_interactive_fd) 8577 close(G_interactive_fd); 8578 close_all_HFILE_list(); 8579} 8580#endif 8581 8582static int internally_opened_fd(int fd, struct squirrel *sq) 8583{ 8584 int i; 8585 8586#if ENABLE_HUSH_INTERACTIVE 8587 if (fd == G_interactive_fd) 8588 return 1; 8589#endif 8590 /* If this one of script's fds? */ 8591 if (fd_in_HFILEs(fd)) 8592 return 1; 8593 8594 if (sq) for (i = 0; sq[i].orig_fd >= 0; i++) { 8595 if (fd == sq[i].moved_to) 8596 return 1; 8597 } 8598 return 0; 8599} 8600 8601/* sqp != NULL means we squirrel away copies of stdin, stdout, 8602 * and stderr if they are redirected. 8603 * If redirection fails, return 1. This will make caller 8604 * skip command execution and restore already created redirect fds. 8605 */ 8606static int setup_redirects(struct command *prog, struct squirrel **sqp) 8607{ 8608 struct redir_struct *redir; 8609 8610 for (redir = prog->redirects; redir; redir = redir->next) { 8611 int newfd; 8612 int closed; 8613 8614 if (redir->rd_type == REDIRECT_HEREDOC2) { 8615 /* "rd_fd<<HERE" case */ 8616 if (save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp) < 0) 8617 return 1; 8618 /* for REDIRECT_HEREDOC2, rd_filename holds _contents_ 8619 * of the heredoc */ 8620 debug_printf_redir("set heredoc '%s'\n", 8621 redir->rd_filename); 8622 setup_heredoc(redir); 8623 continue; 8624 } 8625 8626 if (redir->rd_dup == REDIRFD_TO_FILE) { 8627 /* "rd_fd<*>file" case (<*> is <,>,>>,<>) */ 8628 char *p; 8629 int mode; 8630 8631 if (redir->rd_filename == NULL) { 8632 /* Examples: 8633 * "cmd >" (no filename) 8634 * "cmd > <file" (2nd redirect starts too early) 8635 */ 8636 syntax_error("invalid redirect"); 8637 return 1; 8638 } 8639 mode = redir_table[redir->rd_type].mode; 8640 p = expand_string_to_string(redir->rd_filename, 8641 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1); 8642 newfd = open_or_warn(p, mode); 8643 free(p); 8644 if (newfd < 0) { 8645 /* Error message from open_or_warn can be lost 8646 * if stderr has been redirected, but bash 8647 * and ash both lose it as well 8648 * (though zsh doesn't!) 8649 */ 8650 return 1; 8651 } 8652 if (newfd == redir->rd_fd && sqp 8653 && sqp != ERR_PTR /* not a redirect in "exec" */ 8654 ) { 8655 /* open() gave us precisely the fd we wanted. 8656 * This means that this fd was not busy 8657 * (not opened to anywhere). 8658 * Remember to close it on restore: 8659 */ 8660 *sqp = add_squirrel_closed(*sqp, newfd); 8661 debug_printf_redir("redir to previously closed fd %d\n", newfd); 8662 } 8663 } else { 8664 /* "rd_fd>&rd_dup" or "rd_fd>&-" case */ 8665 newfd = redir->rd_dup; 8666 } 8667 8668 if (newfd == redir->rd_fd) 8669 continue; 8670 8671 /* if "N>FILE": move newfd to redir->rd_fd */ 8672 /* if "N>&M": dup newfd to redir->rd_fd */ 8673 /* if "N>&-": close redir->rd_fd (newfd is REDIRFD_CLOSE) */ 8674 8675 closed = save_fd_on_redirect(redir->rd_fd, /*avoid:*/ newfd, sqp); 8676 if (closed < 0) 8677 return 1; /* error */ 8678 if (newfd == REDIRFD_CLOSE) { 8679 /* "N>&-" means "close me" */ 8680 if (!closed) { 8681 /* ^^^ optimization: saving may already 8682 * have closed it. If not... */ 8683 close(redir->rd_fd); 8684 } 8685 /* Sometimes we do another close on restore, getting EBADF. 8686 * Consider "echo 3>FILE 3>&-" 8687 * first redirect remembers "need to close 3", 8688 * and second redirect closes 3! Restore code then closes 3 again. 8689 */ 8690 } else { 8691 /* if newfd is a script fd or saved fd, do not allow to use it */ 8692 if (internally_opened_fd(newfd, sqp && sqp != ERR_PTR ? *sqp : NULL)) { 8693 bb_error_msg("fd#%d is not open", newfd); 8694 return 1; 8695 } 8696 if (dup2(newfd, redir->rd_fd) < 0) { 8697 /* "echo >&99" testcase */ 8698 bb_perror_msg("dup2(%d,%d)", newfd, redir->rd_fd); 8699 return 1; 8700 } 8701 if (redir->rd_dup == REDIRFD_TO_FILE) 8702 /* "rd_fd > FILE" */ 8703 close(newfd); 8704 /* else: "rd_fd > rd_dup" */ 8705 } 8706 } 8707 return 0; 8708} 8709 8710static char *find_in_path(const char *arg) 8711{ 8712 char *ret = NULL; 8713 const char *PATH = get_local_var_value("PATH"); 8714 8715 if (!PATH) 8716 return NULL; 8717 8718 while (1) { 8719 const char *end = strchrnul(PATH, ':'); 8720 int sz = end - PATH; /* must be int! */ 8721 8722 free(ret); 8723 if (sz != 0) { 8724 ret = xasprintf("%.*s/%s", sz, PATH, arg); 8725 } else { 8726 /* We have xxx::yyyy in $PATH, 8727 * it means "use current dir" */ 8728 ret = xstrdup(arg); 8729 } 8730 if (access(ret, F_OK) == 0) 8731 break; 8732 8733 if (*end == '\0') { 8734 free(ret); 8735 return NULL; 8736 } 8737 PATH = end + 1; 8738 } 8739 8740 return ret; 8741} 8742 8743static const struct built_in_command *find_builtin_helper(const char *name, 8744 const struct built_in_command *x, 8745 const struct built_in_command *end) 8746{ 8747 while (x != end) { 8748 if (strcmp(name, x->b_cmd) != 0) { 8749 x++; 8750 continue; 8751 } 8752 debug_printf_exec("found builtin '%s'\n", name); 8753 return x; 8754 } 8755 return NULL; 8756} 8757static const struct built_in_command *find_builtin1(const char *name) 8758{ 8759 return find_builtin_helper(name, bltins1, &bltins1[ARRAY_SIZE(bltins1)]); 8760} 8761static const struct built_in_command *find_builtin(const char *name) 8762{ 8763 const struct built_in_command *x = find_builtin1(name); 8764 if (x) 8765 return x; 8766 return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); 8767} 8768 8769#if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION 8770static const char * FAST_FUNC hush_command_name(int i) 8771{ 8772 if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { 8773 return bltins1[i].b_cmd; 8774 } 8775 i -= ARRAY_SIZE(bltins1); 8776 if (i < ARRAY_SIZE(bltins2)) { 8777 return bltins2[i].b_cmd; 8778 } 8779# if ENABLE_HUSH_FUNCTIONS 8780 { 8781 struct function *funcp; 8782 i -= ARRAY_SIZE(bltins2); 8783 for (funcp = G.top_func; funcp; funcp = funcp->next) { 8784 if (--i < 0) 8785 return funcp->name; 8786 } 8787 } 8788# endif 8789 return NULL; 8790} 8791#endif 8792#endif /* !__U_BOOT__ */ 8793 8794#ifndef __U_BOOT__ 8795static void remove_nested_vars(void) 8796{ 8797 struct variable *cur; 8798 struct variable **cur_pp; 8799 8800 cur_pp = &G.top_var; 8801 while ((cur = *cur_pp) != NULL) { 8802 if (cur->var_nest_level <= G.var_nest_level) { 8803 cur_pp = &cur->next; 8804 continue; 8805 } 8806 /* Unexport */ 8807 if (cur->flg_export) { 8808 debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level); 8809 bb_unsetenv(cur->varstr); 8810 } 8811 /* Remove from global list */ 8812 *cur_pp = cur->next; 8813 /* Free */ 8814 if (!cur->max_len) { 8815 debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level); 8816 free(cur->varstr); 8817 } 8818 free(cur); 8819 } 8820} 8821 8822static void enter_var_nest_level(void) 8823{ 8824 G.var_nest_level++; 8825 debug_printf_env("var_nest_level++ %u\n", G.var_nest_level); 8826 8827 /* Try: f() { echo -n .; f; }; f 8828 * struct variable::var_nest_level is uint16_t, 8829 * thus limiting recursion to < 2^16. 8830 * In any case, with 8 Mbyte stack SEGV happens 8831 * not too long after 2^16 recursions anyway. 8832 */ 8833 if (G.var_nest_level > 0xff00) 8834 bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level); 8835} 8836 8837static void leave_var_nest_level(void) 8838{ 8839 G.var_nest_level--; 8840 debug_printf_env("var_nest_level-- %u\n", G.var_nest_level); 8841 if (HUSH_DEBUG && (int)G.var_nest_level < 0) 8842 bb_simple_error_msg_and_die("BUG: nesting underflow"); 8843 8844 remove_nested_vars(); 8845} 8846#endif /* __U_BOOT__ */ 8847 8848#if ENABLE_HUSH_FUNCTIONS 8849static struct function **find_function_slot(const char *name) 8850{ 8851 struct function *funcp; 8852 struct function **funcpp = &G.top_func; 8853 8854 while ((funcp = *funcpp) != NULL) { 8855 if (strcmp(name, funcp->name) == 0) { 8856 debug_printf_exec("found function '%s'\n", name); 8857 break; 8858 } 8859 funcpp = &funcp->next; 8860 } 8861 return funcpp; 8862} 8863 8864static ALWAYS_INLINE const struct function *find_function(const char *name) 8865{ 8866 const struct function *funcp = *find_function_slot(name); 8867 return funcp; 8868} 8869 8870/* Note: takes ownership on name ptr */ 8871static struct function *new_function(char *name) 8872{ 8873 struct function **funcpp = find_function_slot(name); 8874 struct function *funcp = *funcpp; 8875 8876 if (funcp != NULL) { 8877 struct command *cmd = funcp->parent_cmd; 8878 debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd); 8879 if (!cmd) { 8880 debug_printf_exec("freeing & replacing function '%s'\n", funcp->name); 8881 free(funcp->name); 8882 /* Note: if !funcp->body, do not free body_as_string! 8883 * This is a special case of "-F name body" function: 8884 * body_as_string was not malloced! */ 8885 if (funcp->body) { 8886 free_pipe_list(funcp->body); 8887# if !BB_MMU 8888 free(funcp->body_as_string); 8889# endif 8890 } 8891 } else { 8892 debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp->name); 8893 cmd->argv[0] = funcp->name; 8894 cmd->group = funcp->body; 8895# if !BB_MMU 8896 cmd->group_as_string = funcp->body_as_string; 8897# endif 8898 } 8899 } else { 8900 debug_printf_exec("remembering new function '%s'\n", name); 8901 funcp = *funcpp = xzalloc(sizeof(*funcp)); 8902 /*funcp->next = NULL;*/ 8903 } 8904 8905 funcp->name = name; 8906 return funcp; 8907} 8908 8909# if ENABLE_HUSH_UNSET 8910static void unset_func(const char *name) 8911{ 8912 struct function **funcpp = find_function_slot(name); 8913 struct function *funcp = *funcpp; 8914 8915 if (funcp != NULL) { 8916 debug_printf_exec("freeing function '%s'\n", funcp->name); 8917 *funcpp = funcp->next; 8918 /* funcp is unlinked now, deleting it. 8919 * Note: if !funcp->body, the function was created by 8920 * "-F name body", do not free ->body_as_string 8921 * and ->name as they were not malloced. */ 8922 if (funcp->body) { 8923 free_pipe_list(funcp->body); 8924 free(funcp->name); 8925# if !BB_MMU 8926 free(funcp->body_as_string); 8927# endif 8928 } 8929 free(funcp); 8930 } 8931} 8932# endif 8933 8934# if BB_MMU 8935#define exec_function(to_free, funcp, argv) \ 8936 exec_function(funcp, argv) 8937# endif 8938static void exec_function(char ***to_free, 8939 const struct function *funcp, 8940 char **argv) NORETURN; 8941static void exec_function(char ***to_free, 8942 const struct function *funcp, 8943 char **argv) 8944{ 8945# if BB_MMU 8946 int n; 8947 8948 argv[0] = G.global_argv[0]; 8949 G.global_argv = argv; 8950 G.global_argc = n = 1 + string_array_len(argv + 1); 8951 8952// Example when we are here: "cmd | func" 8953// func will run with saved-redirect fds open. 8954// $ f() { echo /proc/self/fd/*; } 8955// $ true | f 8956// /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 8957// stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ DIR fd for glob 8958// Same in script: 8959// $ . ./SCRIPT 8960// /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 /proc/self/fd/4 8961// stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ opened ./SCRIPT DIR fd for glob 8962// They are CLOEXEC so external programs won't see them, but 8963// for "more correctness" we might want to close those extra fds here: 8964//? close_saved_fds_and_FILE_fds(); 8965 8966 /* "we are in a function, ok to use return" */ 8967 G_flag_return_in_progress = -1; 8968 enter_var_nest_level(); 8969 IF_HUSH_LOCAL(G.func_nest_level++;) 8970 8971 /* On MMU, funcp->body is always non-NULL */ 8972 n = run_list(funcp->body); 8973 _exit(n); 8974# else 8975//? close_saved_fds_and_FILE_fds(); 8976 8977//TODO: check whether "true | func_with_return" works 8978 8979 re_execute_shell(to_free, 8980 funcp->body_as_string, 8981 G.global_argv[0], 8982 argv + 1, 8983 NULL); 8984# endif 8985} 8986 8987static int run_function(const struct function *funcp, char **argv) 8988{ 8989 int rc; 8990 save_arg_t sv; 8991 smallint sv_flg; 8992 8993 save_and_replace_G_args(&sv, argv); 8994 8995 /* "We are in function, ok to use return" */ 8996 sv_flg = G_flag_return_in_progress; 8997 G_flag_return_in_progress = -1; 8998 8999 /* Make "local" variables properly shadow previous ones */ 9000 IF_HUSH_LOCAL(enter_var_nest_level();) 9001 IF_HUSH_LOCAL(G.func_nest_level++;) 9002 9003 /* On MMU, funcp->body is always non-NULL */ 9004# if !BB_MMU 9005 if (!funcp->body) { 9006 /* Function defined by -F */ 9007 parse_and_run_string(funcp->body_as_string); 9008 rc = G.last_exitcode; 9009 } else 9010# endif 9011 { 9012 rc = run_list(funcp->body); 9013 } 9014 9015 IF_HUSH_LOCAL(G.func_nest_level--;) 9016 IF_HUSH_LOCAL(leave_var_nest_level();) 9017 9018 G_flag_return_in_progress = sv_flg; 9019# if ENABLE_HUSH_TRAP 9020 debug_printf_exec("G.return_exitcode=-1\n"); 9021 G.return_exitcode = -1; /* invalidate stashed return value */ 9022# endif 9023 9024 restore_G_args(&sv, argv); 9025 9026 return rc; 9027} 9028#endif /* ENABLE_HUSH_FUNCTIONS */ 9029 9030#ifndef __U_BOOT__ 9031#if BB_MMU 9032#define exec_builtin(to_free, x, argv) \ 9033 exec_builtin(x, argv) 9034#else 9035#define exec_builtin(to_free, x, argv) \ 9036 exec_builtin(to_free, argv) 9037#endif 9038static void exec_builtin(char ***to_free, 9039 const struct built_in_command *x, 9040 char **argv) NORETURN; 9041static void exec_builtin(char ***to_free, 9042 const struct built_in_command *x, 9043 char **argv) 9044{ 9045#if BB_MMU 9046 int rcode; 9047//? close_saved_fds_and_FILE_fds(); 9048 rcode = x->b_function(argv); 9049 fflush_all(); 9050 _exit(rcode); 9051#else 9052 fflush_all(); 9053 /* On NOMMU, we must never block! 9054 * Example: { sleep 99 | read line; } & echo Ok 9055 */ 9056 re_execute_shell(to_free, 9057 argv[0], 9058 G.global_argv[0], 9059 G.global_argv + 1, 9060 argv); 9061#endif 9062} 9063#endif /* !__U_BOOT__ */ 9064 9065#ifndef __U_BOOT__ 9066static void execvp_or_die(char **argv) NORETURN; 9067static void execvp_or_die(char **argv) 9068{ 9069 int e; 9070 debug_printf_exec("execing '%s'\n", argv[0]); 9071 /* Don't propagate SIG_IGN to the child */ 9072 if (SPECIAL_JOBSTOP_SIGS != 0) 9073 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); 9074 execvp(argv[0], argv); 9075 e = 2; 9076 if (errno == EACCES) e = 126; 9077 if (errno == ENOENT) e = 127; 9078 bb_perror_msg("can't execute '%s'", argv[0]); 9079 _exit(e); 9080} 9081 9082#if ENABLE_HUSH_MODE_X 9083static void x_mode_print_optionally_squoted(const char *str) 9084{ 9085 unsigned len; 9086 const char *cp; 9087 9088 cp = str; 9089 9090 /* the set of chars which-cause-string-to-be-squoted mimics bash */ 9091 /* test a char with: bash -c 'set -x; echo "CH"' */ 9092 if (str[strcspn(str, "\\\"'`$(){}[]<>;#&|~*?!^" 9093 " " "\001\002\003\004\005\006\007" 9094 "\010\011\012\013\014\015\016\017" 9095 "\020\021\022\023\024\025\026\027" 9096 "\030\031\032\033\034\035\036\037" 9097 ) 9098 ] == '\0' 9099 ) { 9100 /* string has no special chars */ 9101 x_mode_addstr(str); 9102 return; 9103 } 9104 9105 cp = str; 9106 for (;;) { 9107 /* print '....' up to EOL or first squote */ 9108 len = (int)(strchrnul(cp, '\'') - cp); 9109 if (len != 0) { 9110 x_mode_addchr('\''); 9111 x_mode_addblock(cp, len); 9112 x_mode_addchr('\''); 9113 cp += len; 9114 } 9115 if (*cp == '\0') 9116 break; 9117 /* string contains squote(s), print them as \' */ 9118 x_mode_addchr('\\'); 9119 x_mode_addchr('\''); 9120 cp++; 9121 } 9122} 9123static void dump_cmd_in_x_mode(char **argv) 9124{ 9125 if (G_x_mode && argv) { 9126 unsigned n; 9127 9128 /* "+[+++...][ cmd...]\n\0" */ 9129 x_mode_prefix(); 9130 n = 0; 9131 while (argv[n]) { 9132 x_mode_addchr(' '); 9133 if (argv[n][0] == '\0') { 9134 x_mode_addchr('\''); 9135 x_mode_addchr('\''); 9136 } else { 9137 x_mode_print_optionally_squoted(argv[n]); 9138 } 9139 n++; 9140 } 9141 x_mode_flush(); 9142 } 9143} 9144#else 9145# define dump_cmd_in_x_mode(argv) ((void)0) 9146#endif 9147#endif /* !__U_BOOT__ */ 9148 9149#ifndef __U_BOOT__ 9150#if ENABLE_HUSH_COMMAND 9151static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *explanation) 9152{ 9153 char *to_free; 9154 9155 if (!opt_vV) 9156 return; 9157 9158 to_free = NULL; 9159 if (!explanation) { 9160 char *path = getenv("PATH"); 9161 explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */ 9162 if (!explanation) 9163 _exit(1); /* PROG was not found */ 9164 if (opt_vV != 'V') 9165 cmd = to_free; /* -v PROG prints "/path/to/PROG" */ 9166 } 9167 printf((opt_vV == 'V') ? "%s is %s\n" : "%s\n", cmd, explanation); 9168 free(to_free); 9169 fflush_all(); 9170 _exit(0); 9171} 9172#else 9173# define if_command_vV_print_and_exit(a,b,c) ((void)0) 9174#endif 9175#endif /* !__U_BOOT__ */ 9176 9177#if BB_MMU 9178#define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ 9179 pseudo_exec_argv(argv, assignment_cnt, argv_expanded) 9180#define pseudo_exec(nommu_save, command, argv_expanded) \ 9181 pseudo_exec(command, argv_expanded) 9182#endif 9183 9184#ifndef __U_BOOT__ 9185/* Called after [v]fork() in run_pipe, or from builtin_exec. 9186 * Never returns. 9187 * Don't exit() here. If you don't exec, use _exit instead. 9188 * The at_exit handlers apparently confuse the calling process, 9189 * in particular stdin handling. Not sure why? -- because of vfork! (vda) 9190 */ 9191static void pseudo_exec_argv(nommu_save_t *nommu_save, 9192 char **argv, int assignment_cnt, 9193 char **argv_expanded) NORETURN; 9194static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, 9195 char **argv, int assignment_cnt, 9196 char **argv_expanded) 9197{ 9198 const struct built_in_command *x; 9199 struct variable **sv_shadowed; 9200 char **new_env; 9201 IF_HUSH_COMMAND(char opt_vV = 0;) 9202 IF_HUSH_FUNCTIONS(const struct function *funcp;) 9203 9204 new_env = expand_assignments(argv, assignment_cnt); 9205 dump_cmd_in_x_mode(new_env); 9206 9207 if (!argv[assignment_cnt]) { 9208 /* Case when we are here: ... | var=val | ... 9209 * (note that we do not exit early, i.e., do not optimize out 9210 * expand_assignments(): think about ... | var=`sleep 1` | ... 9211 */ 9212 free_strings(new_env); 9213 _exit_SUCCESS(); 9214 } 9215 9216 sv_shadowed = G.shadowed_vars_pp; 9217#if BB_MMU 9218 G.shadowed_vars_pp = NULL; /* "don't save, free them instead" */ 9219#else 9220 G.shadowed_vars_pp = &nommu_save->old_vars; 9221 G.var_nest_level++; 9222#endif 9223 set_vars_and_save_old(new_env); 9224 G.shadowed_vars_pp = sv_shadowed; 9225 9226 if (argv_expanded) { 9227 argv = argv_expanded; 9228 } else { 9229 argv = expand_strvec_to_strvec(argv + assignment_cnt); 9230#if !BB_MMU 9231 nommu_save->argv = argv; 9232#endif 9233 } 9234 dump_cmd_in_x_mode(argv); 9235 9236#if ENABLE_FEATURE_SH_STANDALONE || BB_MMU 9237 if (strchr(argv[0], '/') != NULL) 9238 goto skip; 9239#endif 9240 9241#if ENABLE_HUSH_FUNCTIONS 9242 /* Check if the command matches any functions (this goes before bltins) */ 9243 funcp = find_function(argv[0]); 9244 if (funcp) 9245 exec_function(&nommu_save->argv_from_re_execing, funcp, argv); 9246#endif 9247 9248#if ENABLE_HUSH_COMMAND 9249 /* "command BAR": run BAR without looking it up among functions 9250 * "command -v BAR": print "BAR" or "/path/to/BAR"; or exit 1 9251 * "command -V BAR": print "BAR is {a function,a shell builtin,/path/to/BAR}" 9252 */ 9253 while (strcmp(argv[0], "command") == 0 && argv[1]) { 9254 char *p; 9255 9256 argv++; 9257 p = *argv; 9258 if (p[0] != '-' || !p[1]) 9259 continue; /* bash allows "command command command [-OPT] BAR" */ 9260 9261 for (;;) { 9262 p++; 9263 switch (*p) { 9264 case '\0': 9265 argv++; 9266 p = *argv; 9267 if (p[0] != '-' || !p[1]) 9268 goto after_opts; 9269 continue; /* next arg is also -opts, process it too */ 9270 case 'v': 9271 case 'V': 9272 opt_vV = *p; 9273 continue; 9274 default: 9275 bb_error_msg_and_die("%s: %s: invalid option", "command", argv[0]); 9276 } 9277 } 9278 } 9279 after_opts: 9280# if ENABLE_HUSH_FUNCTIONS 9281 if (opt_vV && find_function(argv[0])) 9282 if_command_vV_print_and_exit(opt_vV, argv[0], "a function"); 9283# endif 9284#endif 9285 9286 /* Check if the command matches any of the builtins. 9287 * Depending on context, this might be redundant. But it's 9288 * easier to waste a few CPU cycles than it is to figure out 9289 * if this is one of those cases. 9290 */ 9291 /* Why "BB_MMU ? :" difference in logic? - 9292 * On NOMMU, it is more expensive to re-execute shell 9293 * just in order to run echo or test builtin. 9294 * It's better to skip it here and run corresponding 9295 * non-builtin later. */ 9296 x = BB_MMU ? find_builtin(argv[0]) : find_builtin1(argv[0]); 9297 if (x) { 9298 if_command_vV_print_and_exit(opt_vV, argv[0], "a shell builtin"); 9299 exec_builtin(&nommu_save->argv_from_re_execing, x, argv); 9300 } 9301 9302#if ENABLE_FEATURE_SH_STANDALONE 9303 /* Check if the command matches any busybox applets */ 9304 { 9305 int a = find_applet_by_name(argv[0]); 9306 if (a >= 0) { 9307 if_command_vV_print_and_exit(opt_vV, argv[0], "an applet"); 9308# if BB_MMU /* see above why on NOMMU it is not allowed */ 9309 if (APPLET_IS_NOEXEC(a)) { 9310 /* Do not leak open fds from opened script files etc. 9311 * Testcase: interactive "ls -l /proc/self/fd" 9312 * should not show tty fd open. 9313 */ 9314 close_saved_fds_and_FILE_fds(); 9315//FIXME: should also close saved redir fds 9316//This casuses test failures in 9317//redir_children_should_not_see_saved_fd_2.tests 9318//redir_children_should_not_see_saved_fd_3.tests 9319//if you replace "busybox find" with just "find" in them 9320 /* Without this, "rm -i FILE" can't be ^C'ed: */ 9321 switch_off_special_sigs(G.special_sig_mask); 9322 debug_printf_exec("running applet '%s'\n", argv[0]); 9323 run_noexec_applet_and_exit(a, argv[0], argv); 9324 } 9325# endif 9326 /* Re-exec ourselves */ 9327 debug_printf_exec("re-execing applet '%s'\n", argv[0]); 9328 /* Don't propagate SIG_IGN to the child */ 9329 if (SPECIAL_JOBSTOP_SIGS != 0) 9330 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); 9331 execv(bb_busybox_exec_path, argv); 9332 /* If they called chroot or otherwise made the binary no longer 9333 * executable, fall through */ 9334 } 9335 } 9336#endif 9337 9338#if ENABLE_FEATURE_SH_STANDALONE || BB_MMU 9339 skip: 9340#endif 9341 if_command_vV_print_and_exit(opt_vV, argv[0], NULL); 9342 execvp_or_die(argv); 9343} 9344 9345/* Called after [v]fork() in run_pipe 9346 */ 9347static void pseudo_exec(nommu_save_t *nommu_save, 9348 struct command *command, 9349 char **argv_expanded) NORETURN; 9350static void pseudo_exec(nommu_save_t *nommu_save, 9351 struct command *command, 9352 char **argv_expanded) 9353{ 9354#if ENABLE_HUSH_FUNCTIONS 9355 if (command->cmd_type == CMD_FUNCDEF) { 9356 /* Ignore funcdefs in pipes: 9357 * true | f() { cmd } 9358 */ 9359 _exit(0); 9360 } 9361#endif 9362 9363 if (command->argv) { 9364 pseudo_exec_argv(nommu_save, command->argv, 9365 command->assignment_cnt, argv_expanded); 9366 } 9367 9368 if (command->group) { 9369 /* Cases when we are here: 9370 * ( list ) 9371 * { list } & 9372 * ... | ( list ) | ... 9373 * ... | { list } | ... 9374 */ 9375#if BB_MMU 9376 int rcode; 9377 debug_printf_exec("pseudo_exec: run_list\n"); 9378 reset_traps_to_defaults(); 9379 rcode = run_list(command->group); 9380 /* OK to leak memory by not calling free_pipe_list, 9381 * since this process is about to exit */ 9382 _exit(rcode); 9383#else 9384 re_execute_shell(&nommu_save->argv_from_re_execing, 9385 command->group_as_string, 9386 G.global_argv[0], 9387 G.global_argv + 1, 9388 NULL); 9389#endif 9390 } 9391 9392 /* Case when we are here: ... | >file */ 9393 debug_printf_exec("pseudo_exec'ed null command\n"); 9394 _exit_SUCCESS(); 9395} 9396 9397#if ENABLE_HUSH_JOB 9398static const char *get_cmdtext(struct pipe *pi) 9399{ 9400 char **argv; 9401 char *p; 9402 int len; 9403 9404 /* This is subtle. ->cmdtext is created only on first backgrounding. 9405 * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...) 9406 * On subsequent bg argv is trashed, but we won't use it */ 9407 if (pi->cmdtext) 9408 return pi->cmdtext; 9409 9410 argv = pi->cmds[0].argv; 9411 if (!argv) { 9412 pi->cmdtext = xzalloc(1); 9413 return pi->cmdtext; 9414 } 9415 len = 0; 9416 do { 9417 len += strlen(*argv) + 1; 9418 } while (*++argv); 9419 p = xmalloc(len); 9420 pi->cmdtext = p; 9421 argv = pi->cmds[0].argv; 9422 do { 9423 p = stpcpy(p, *argv); 9424 *p++ = ' '; 9425 } while (*++argv); 9426 p[-1] = '\0'; 9427 return pi->cmdtext; 9428} 9429 9430static void remove_job_from_table(struct pipe *pi) 9431{ 9432 struct pipe *prev_pipe; 9433 9434 if (pi == G.job_list) { 9435 G.job_list = pi->next; 9436 } else { 9437 prev_pipe = G.job_list; 9438 while (prev_pipe->next != pi) 9439 prev_pipe = prev_pipe->next; 9440 prev_pipe->next = pi->next; 9441 } 9442 G.last_jobid = 0; 9443 if (G.job_list) 9444 G.last_jobid = G.job_list->jobid; 9445} 9446 9447static void delete_finished_job(struct pipe *pi) 9448{ 9449 remove_job_from_table(pi); 9450 free_pipe(pi); 9451} 9452 9453static void clean_up_last_dead_job(void) 9454{ 9455 if (G.job_list && !G.job_list->alive_cmds) 9456 delete_finished_job(G.job_list); 9457} 9458 9459static void insert_job_into_table(struct pipe *pi) 9460{ 9461 struct pipe *job, **jobp; 9462 int i; 9463 9464 clean_up_last_dead_job(); 9465 9466 /* Find the end of the list, and find next job ID to use */ 9467 i = 0; 9468 jobp = &G.job_list; 9469 while ((job = *jobp) != NULL) { 9470 if (job->jobid > i) 9471 i = job->jobid; 9472 jobp = &job->next; 9473 } 9474 pi->jobid = i + 1; 9475 9476 /* Create a new job struct at the end */ 9477 job = *jobp = xmemdup(pi, sizeof(*pi)); 9478 job->next = NULL; 9479 job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds); 9480 /* Cannot copy entire pi->cmds[] vector! This causes double frees */ 9481 for (i = 0; i < pi->num_cmds; i++) { 9482 job->cmds[i].pid = pi->cmds[i].pid; 9483 /* all other fields are not used and stay zero */ 9484 } 9485 job->cmdtext = xstrdup(get_cmdtext(pi)); 9486 9487 if (G_interactive_fd) 9488 printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext); 9489 G.last_jobid = job->jobid; 9490} 9491#endif /* JOB */ 9492 9493static int job_exited_or_stopped(struct pipe *pi) 9494{ 9495 int rcode, i; 9496 9497 if (pi->alive_cmds != pi->stopped_cmds) 9498 return -1; 9499 9500 /* All processes in fg pipe have exited or stopped */ 9501 rcode = 0; 9502 i = pi->num_cmds; 9503 while (--i >= 0) { 9504 rcode = pi->cmds[i].cmd_exitcode; 9505 /* usually last process gives overall exitstatus, 9506 * but with "set -o pipefail", last *failed* process does */ 9507 if (G.o_opt[OPT_O_PIPEFAIL] == 0 || rcode != 0) 9508 break; 9509 } 9510 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) 9511 return rcode; 9512} 9513 9514static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) 9515{ 9516#if ENABLE_HUSH_JOB 9517 struct pipe *pi; 9518#endif 9519 int i, dead; 9520 9521 dead = WIFEXITED(status) || WIFSIGNALED(status); 9522 9523#if DEBUG_JOBS 9524 if (WIFSTOPPED(status)) 9525 debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n", 9526 childpid, WSTOPSIG(status), WEXITSTATUS(status)); 9527 if (WIFSIGNALED(status)) 9528 debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n", 9529 childpid, WTERMSIG(status), WEXITSTATUS(status)); 9530 if (WIFEXITED(status)) 9531 debug_printf_jobs("pid %d exited, exitcode %d\n", 9532 childpid, WEXITSTATUS(status)); 9533#endif 9534 /* Were we asked to wait for a fg pipe? */ 9535 if (fg_pipe) { 9536 i = fg_pipe->num_cmds; 9537 9538 while (--i >= 0) { 9539 int rcode; 9540 9541 debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid); 9542 if (fg_pipe->cmds[i].pid != childpid) 9543 continue; 9544 if (dead) { 9545 int ex; 9546 fg_pipe->cmds[i].pid = 0; 9547 fg_pipe->alive_cmds--; 9548 ex = WEXITSTATUS(status); 9549 /* bash prints killer signal's name for *last* 9550 * process in pipe (prints just newline for SIGINT/SIGPIPE). 9551 * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT) 9552 */ 9553 if (WIFSIGNALED(status)) { 9554 int sig = WTERMSIG(status); 9555#if ENABLE_HUSH_JOB 9556 if (G.run_list_level == 1 9557 /* ^^^^^ Do not print in nested contexts, example: 9558 * echo `sleep 1; sh -c 'kill -9 $$'` - prints "137", NOT "Killed 137" 9559 */ 9560 && i == fg_pipe->num_cmds-1 9561 ) { 9562 /* strsignal() is for bash compat. ~600 bloat versus bbox's get_signame() */ 9563 puts(sig == SIGINT || sig == SIGPIPE ? "" : strsignal(sig)); 9564 } 9565#endif 9566 /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ 9567 /* MIPS has 128 sigs (1..128), if sig==128, 9568 * 128 + sig would result in exitcode 256 -> 0! 9569 */ 9570 ex = 128 | sig; 9571 } 9572 fg_pipe->cmds[i].cmd_exitcode = ex; 9573 } else { 9574 fg_pipe->stopped_cmds++; 9575 } 9576 debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n", 9577 fg_pipe->alive_cmds, fg_pipe->stopped_cmds); 9578 rcode = job_exited_or_stopped(fg_pipe); 9579 if (rcode >= 0) { 9580/* Note: *non-interactive* bash does not continue if all processes in fg pipe 9581 * are stopped. Testcase: "cat | cat" in a script (not on command line!) 9582 * and "killall -STOP cat" */ 9583 if (G_interactive_fd) { 9584#if ENABLE_HUSH_JOB 9585 if (fg_pipe->alive_cmds != 0) 9586 insert_job_into_table(fg_pipe); 9587#endif 9588 return rcode; 9589 } 9590 if (fg_pipe->alive_cmds == 0) 9591 return rcode; 9592 } 9593 /* There are still running processes in the fg_pipe */ 9594 return -1; 9595 } 9596 /* It wasn't in fg_pipe, look for process in bg pipes */ 9597 } 9598 9599#if ENABLE_HUSH_JOB 9600 /* We were asked to wait for bg or orphaned children */ 9601 /* No need to remember exitcode in this case */ 9602 for (pi = G.job_list; pi; pi = pi->next) { 9603 for (i = 0; i < pi->num_cmds; i++) { 9604 if (pi->cmds[i].pid == childpid) 9605 goto found_pi_and_prognum; 9606 } 9607 } 9608 /* Happens when shell is used as init process (init=/bin/sh) */ 9609 debug_printf("checkjobs: pid %d was not in our list!\n", childpid); 9610 return -1; /* this wasn't a process from fg_pipe */ 9611 9612 found_pi_and_prognum: 9613 if (dead) { 9614 /* child exited */ 9615 int rcode = WEXITSTATUS(status); 9616 if (WIFSIGNALED(status)) 9617 /* NB: not 128 + sig, MIPS has sig 128 */ 9618 rcode = 128 | WTERMSIG(status); 9619 pi->cmds[i].cmd_exitcode = rcode; 9620 if (G.last_bg_pid == pi->cmds[i].pid) 9621 G.last_bg_pid_exitcode = rcode; 9622 pi->cmds[i].pid = 0; 9623 pi->alive_cmds--; 9624 if (!pi->alive_cmds) { 9625# if ENABLE_HUSH_BASH_COMPAT 9626 G.dead_job_exitcode = job_exited_or_stopped(pi); 9627# endif 9628 if (G_interactive_fd) { 9629 printf(JOB_STATUS_FORMAT, pi->jobid, 9630 "Done", pi->cmdtext); 9631 delete_finished_job(pi); 9632 } else { 9633/* 9634 * bash deletes finished jobs from job table only in interactive mode, 9635 * after "jobs" cmd, or if pid of a new process matches one of the old ones 9636 * (see cleanup_dead_jobs(), delete_old_job(), J_NOTIFIED in bash source). 9637 * Testcase script: "(exit 3) & sleep 1; wait %1; echo $?" prints 3 in bash. 9638 * We only retain one "dead" job, if it's the single job on the list. 9639 * This covers most of real-world scenarios where this is useful. 9640 */ 9641 if (pi != G.job_list) 9642 delete_finished_job(pi); 9643 } 9644 } 9645 } else { 9646 /* child stopped */ 9647 pi->stopped_cmds++; 9648 } 9649#endif 9650 return -1; /* this wasn't a process from fg_pipe */ 9651} 9652 9653/* Check to see if any processes have exited -- if they have, 9654 * figure out why and see if a job has completed. 9655 * 9656 * If non-NULL fg_pipe: wait for its completion or stop. 9657 * Return its exitcode or zero if stopped. 9658 * 9659 * Alternatively (fg_pipe == NULL, waitfor_pid != 0): 9660 * waitpid(WNOHANG), if waitfor_pid exits or stops, return exitcode+1, 9661 * else return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for) 9662 * or 0 if no children changed status. 9663 * 9664 * Alternatively (fg_pipe == NULL, waitfor_pid == 0), 9665 * return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for) 9666 * or 0 if no children changed status. 9667 */ 9668static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid) 9669{ 9670 int attributes; 9671 int status; 9672 int rcode = 0; 9673 9674 debug_printf_jobs("checkjobs %p\n", fg_pipe); 9675 9676 attributes = WUNTRACED; 9677 if (fg_pipe == NULL) 9678 attributes |= WNOHANG; 9679 9680 errno = 0; 9681#if ENABLE_HUSH_FAST 9682 if (G.handled_SIGCHLD == G.count_SIGCHLD) { 9683//bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p", 9684//getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe); 9685 /* There was neither fork nor SIGCHLD since last waitpid */ 9686 /* Avoid doing waitpid syscall if possible */ 9687 if (!G.we_have_children) { 9688 errno = ECHILD; 9689 return -1; 9690 } 9691 if (fg_pipe == NULL) { /* is WNOHANG set? */ 9692 /* We have children, but they did not exit 9693 * or stop yet (we saw no SIGCHLD) */ 9694 return 0; 9695 } 9696 /* else: !WNOHANG, waitpid will block, can't short-circuit */ 9697 } 9698#endif 9699 9700/* Do we do this right? 9701 * bash-3.00# sleep 20 | false 9702 * <ctrl-Z pressed> 9703 * [3]+ Stopped sleep 20 | false 9704 * bash-3.00# echo $? 9705 * 1 <========== bg pipe is not fully done, but exitcode is already known! 9706 * [hush 1.14.0: yes we do it right] 9707 */ 9708 while (1) { 9709 pid_t childpid; 9710#if ENABLE_HUSH_FAST 9711 int i; 9712 i = G.count_SIGCHLD; 9713#endif 9714 childpid = waitpid(-1, &status, attributes); 9715 if (childpid <= 0) { 9716 if (childpid && errno != ECHILD) 9717 bb_simple_perror_msg("waitpid"); 9718#if ENABLE_HUSH_FAST 9719 else { /* Until next SIGCHLD, waitpid's are useless */ 9720 G.we_have_children = (childpid == 0); 9721 G.handled_SIGCHLD = i; 9722//bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); 9723 } 9724#endif 9725 /* ECHILD (no children), or 0 (no change in children status) */ 9726 rcode = childpid; 9727 break; 9728 } 9729 rcode = process_wait_result(fg_pipe, childpid, status); 9730 if (rcode >= 0) { 9731 /* fg_pipe exited or stopped */ 9732 break; 9733 } 9734 if (childpid == waitfor_pid) { /* "wait PID" */ 9735 debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status); 9736 rcode = WEXITSTATUS(status); 9737 if (WIFSIGNALED(status)) 9738 rcode = 128 | WTERMSIG(status); 9739 if (WIFSTOPPED(status)) 9740 /* bash: "cmd & wait $!" and cmd stops: $? = 128 | stopsig */ 9741 rcode = 128 | WSTOPSIG(status); 9742 rcode++; 9743 break; /* "wait PID" called us, give it exitcode+1 */ 9744 } 9745#if ENABLE_HUSH_BASH_COMPAT 9746 if (-1 == waitfor_pid /* "wait -n" (wait for any one job) */ 9747 && G.dead_job_exitcode >= 0 /* some job did finish */ 9748 ) { 9749 debug_printf_exec("waitfor_pid:-1\n"); 9750 rcode = G.dead_job_exitcode + 1; 9751 break; 9752 } 9753#endif 9754 /* This wasn't one of our processes, or */ 9755 /* fg_pipe still has running processes, do waitpid again */ 9756 } /* while (waitpid succeeds)... */ 9757 9758 return rcode; 9759} 9760 9761#if ENABLE_HUSH_JOB 9762static int checkjobs_and_fg_shell(struct pipe *fg_pipe) 9763{ 9764 pid_t p; 9765 int rcode = checkjobs(fg_pipe, 0 /*(no pid to wait for)*/); 9766 if (G_saved_tty_pgrp) { 9767 /* Job finished, move the shell to the foreground */ 9768 p = getpgrp(); /* our process group id */ 9769 debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p); 9770 tcsetpgrp(G_interactive_fd, p); 9771 } 9772 return rcode; 9773} 9774#endif 9775#endif /* !__U_BOOT__ */ 9776 9777/* Start all the jobs, but don't wait for anything to finish. 9778 * See checkjobs(). 9779 * 9780 * Return code is normally -1, when the caller has to wait for children 9781 * to finish to determine the exit status of the pipe. If the pipe 9782 * is a simple builtin command, however, the action is done by the 9783 * time run_pipe returns, and the exit code is provided as the 9784 * return value. 9785 * 9786 * Returns -1 only if started some children. IOW: we have to 9787 * mask out retvals of builtins etc with 0xff! 9788 * 9789 * The only case when we do not need to [v]fork is when the pipe 9790 * is single, non-backgrounded, non-subshell command. Examples: 9791 * cmd ; ... { list } ; ... 9792 * cmd && ... { list } && ... 9793 * cmd || ... { list } || ... 9794 * If it is, then we can run cmd as a builtin, NOFORK, 9795 * or (if SH_STANDALONE) an applet, and we can run the { list } 9796 * with run_list. If it isn't one of these, we fork and exec cmd. 9797 * 9798 * Cases when we must fork: 9799 * non-single: cmd | cmd 9800 * backgrounded: cmd & { list } & 9801 * subshell: ( list ) [&] 9802 */ 9803static void set_G_ifs(void) 9804{ 9805 /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*" 9806 * Result should be 3 lines: q w e, qwe, q w e 9807 */ 9808 if (G.ifs_whitespace != G.ifs) 9809 free(G.ifs_whitespace); 9810 G.ifs = get_local_var_value("IFS"); 9811 if (G.ifs) { 9812 char *p; 9813 G.ifs_whitespace = (char*)G.ifs; 9814 p = skip_whitespace(G.ifs); 9815 if (*p) { 9816 /* Not all $IFS is whitespace */ 9817 char *d; 9818 int len = p - G.ifs; 9819 p = skip_non_whitespace(p); 9820 G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */ 9821 d = mempcpy(G.ifs_whitespace, G.ifs, len); 9822 while (*p) { 9823 if (isspace(*p)) 9824 *d++ = *p; 9825 p++; 9826 } 9827 *d = '\0'; 9828 } 9829 } else { 9830 G.ifs = defifs; 9831 G.ifs_whitespace = (char*)G.ifs; 9832 } 9833} 9834#ifndef __U_BOOT__ 9835#if !ENABLE_HUSH_MODE_X 9836#define redirect_and_varexp_helper(command, sqp, argv_expanded) \ 9837 redirect_and_varexp_helper(command, sqp) 9838#endif 9839static int redirect_and_varexp_helper( 9840 struct command *command, 9841 struct squirrel **sqp, 9842 char **argv_expanded) 9843{ 9844 /* Assignments occur before redirects. Try: 9845 * a=`sleep 1` sleep 2 3>/qwe/rty 9846 */ 9847 9848 char **new_env = expand_assignments(command->argv, command->assignment_cnt); 9849 dump_cmd_in_x_mode(new_env); 9850 dump_cmd_in_x_mode(argv_expanded); 9851 /* this takes ownership of new_env[i] elements, and frees new_env: */ 9852 set_vars_and_save_old(new_env); 9853 9854 return setup_redirects(command, sqp); 9855} 9856#endif /* !__U_BOOT__ */ 9857 9858static NOINLINE int run_pipe(struct pipe *pi) 9859{ 9860 static const char *const null_ptr = NULL; 9861 9862 int cmd_no; 9863#ifndef __U_BOOT__ 9864 int next_infd; 9865#endif /* !__U_BOOT__ */ 9866 struct command *command; 9867 char **argv_expanded; 9868 char **argv; 9869#ifndef __U_BOOT__ 9870 struct squirrel *squirrel = NULL; 9871#endif /* !__U_BOOT__ */ 9872 int rcode; 9873 9874#ifdef __U_BOOT__ 9875 /* 9876 * Set rcode here to avoid returning a garbage value in the middle of 9877 * the function. 9878 * Also, if an error occurs, rcode value would be changed and last 9879 * return will signal the error. 9880 */ 9881 rcode = 0; 9882#endif /* __U_BOOT__ */ 9883 9884 debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds); 9885 debug_enter(); 9886 9887 set_G_ifs(); 9888 9889#ifndef __U_BOOT__ 9890 IF_HUSH_JOB(pi->pgrp = -1;) 9891 pi->stopped_cmds = 0; 9892#endif /* !__U_BOOT__ */ 9893 command = &pi->cmds[0]; 9894 argv_expanded = NULL; 9895 9896#ifndef __U_BOOT__ 9897 if (pi->num_cmds != 1 9898 || pi->followup == PIPE_BG 9899 || command->cmd_type == CMD_SUBSHELL 9900 ) { 9901 goto must_fork; 9902 } 9903 9904 pi->alive_cmds = 1; 9905#endif /* !__U_BOOT__ */ 9906 9907 debug_printf_exec(": group:%p argv:'%s'\n", 9908 command->group, command->argv ? command->argv[0] : "NONE"); 9909 9910 if (command->group) { 9911#if ENABLE_HUSH_FUNCTIONS 9912 if (command->cmd_type == CMD_FUNCDEF) { 9913 /* "executing" func () { list } */ 9914 struct function *funcp; 9915 9916 funcp = new_function(command->argv[0]); 9917 /* funcp->name is already set to argv[0] */ 9918 funcp->body = command->group; 9919# if !BB_MMU 9920 funcp->body_as_string = command->group_as_string; 9921 command->group_as_string = NULL; 9922# endif 9923 command->group = NULL; 9924 command->argv[0] = NULL; 9925 debug_printf_exec("cmd %p has child func at %p\n", command, funcp); 9926 funcp->parent_cmd = command; 9927 command->child_func = funcp; 9928 9929 debug_printf_exec("run_pipe: return EXIT_SUCCESS\n"); 9930 debug_leave(); 9931 return EXIT_SUCCESS; 9932 } 9933#endif 9934 /* { list } */ 9935 debug_printf_exec("non-subshell group\n"); 9936 rcode = 1; /* exitcode if redir failed */ 9937#ifndef __U_BOOT__ 9938 if (setup_redirects(command, &squirrel) == 0) { 9939#endif /* !__U_BOOT__ */ 9940 debug_printf_exec(": run_list\n"); 9941//FIXME: we need to pass squirrel down into run_list() 9942//for SH_STANDALONE case, or else this construct: 9943// { find /proc/self/fd; true; } >FILE; cmd2 9944//has no way of closing saved fd#1 for "find", 9945//and in SH_STANDALONE mode, "find" is not execed, 9946//therefore CLOEXEC on saved fd does not help. 9947 rcode = run_list(command->group) & 0xff; 9948#ifndef __U_BOOT__ 9949 } 9950 restore_redirects(squirrel); 9951#endif /* !__U_BOOT__ */ 9952 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) 9953 debug_leave(); 9954 debug_printf_exec("run_pipe: return %d\n", rcode); 9955 return rcode; 9956 } 9957 9958 argv = command->argv ? command->argv : (char **) &null_ptr; 9959 { 9960#ifndef __U_BOOT__ 9961 const struct built_in_command *x; 9962 IF_HUSH_FUNCTIONS(const struct function *funcp;) 9963 IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };) 9964 struct variable **sv_shadowed; 9965#endif /* !__U_BOOT__ */ 9966 struct variable *old_vars; 9967 9968#if ENABLE_HUSH_LINENO_VAR 9969 G.execute_lineno = command->lineno; 9970#endif 9971 9972 if (argv[command->assignment_cnt] == NULL) { 9973 /* Assignments, but no command. 9974 * Ensure redirects take effect (that is, create files). 9975 * Try "a=t >file" 9976 */ 9977 unsigned i; 9978 G.expand_exitcode = 0; 9979 only_assignments: 9980#ifndef __U_BOOT__ 9981 rcode = setup_redirects(command, &squirrel); 9982 restore_redirects(squirrel); 9983#endif /* !__U_BOOT__ */ 9984 9985 /* Set shell variables */ 9986 i = 0; 9987 while (i < command->assignment_cnt) { 9988 char *p = expand_string_to_string(argv[i], 9989 EXP_FLAG_ESC_GLOB_CHARS, 9990 /*unbackslash:*/ 1 9991 ); 9992#if ENABLE_HUSH_MODE_X 9993 if (G_x_mode) { 9994 char *eq; 9995 if (i == 0) 9996 x_mode_prefix(); 9997 x_mode_addchr(' '); 9998 eq = strchrnul(p, '='); 9999 if (*eq) eq++; 10000 x_mode_addblock(p, (eq - p)); 10001 x_mode_print_optionally_squoted(eq); 10002 x_mode_flush(); 10003 } 10004#endif 10005 debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); 10006#ifndef __U_BOOT__ 10007 if (set_local_var0(p)) { 10008#else /* __U_BOOT__ */ 10009 if (set_local_var_modern(p, /*flag:*/ 0)) { 10010#endif 10011 /* assignment to readonly var / putenv error? */ 10012 rcode = 1; 10013 } 10014 i++; 10015 } 10016 /* Redirect error sets $? to 1. Otherwise, 10017 * if evaluating assignment value set $?, retain it. 10018 * Else, clear $?: 10019 * false; q=`exit 2`; echo $? - should print 2 10020 * false; x=1; echo $? - should print 0 10021 * Because of the 2nd case, we can't just use G.last_exitcode. 10022 */ 10023 if (rcode == 0) 10024 rcode = G.expand_exitcode; 10025 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) 10026 debug_leave(); 10027 debug_printf_exec("run_pipe: return %d\n", rcode); 10028 return rcode; 10029 } 10030 10031 /* Expand the rest into (possibly) many strings each */ 10032#if defined(CMD_TEST2_SINGLEWORD_NOGLOB) 10033 if (command->cmd_type == CMD_TEST2_SINGLEWORD_NOGLOB) 10034 argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); 10035 else 10036#endif 10037#if defined(CMD_SINGLEWORD_NOGLOB) 10038 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) 10039 argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); 10040 else 10041#endif 10042 argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt); 10043 10044 /* If someone gives us an empty string: `cmd with empty output` */ 10045 if (!argv_expanded[0]) { 10046 free(argv_expanded); 10047 /* `false` still has to set exitcode 1 */ 10048 G.expand_exitcode = G.last_exitcode; 10049 goto only_assignments; 10050 } 10051 10052 old_vars = NULL; 10053#ifndef __U_BOOT__ 10054 sv_shadowed = G.shadowed_vars_pp; 10055 10056 /* Check if argv[0] matches any functions (this goes before bltins) */ 10057 IF_HUSH_FUNCTIONS(funcp = find_function(argv_expanded[0]);) 10058 IF_HUSH_FUNCTIONS(x = NULL;) 10059 IF_HUSH_FUNCTIONS(if (!funcp)) 10060 x = find_builtin(argv_expanded[0]); 10061 if (x || funcp) { 10062 if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) { 10063 debug_printf("exec with redirects only\n"); 10064 /* 10065 * Variable assignments are executed, but then "forgotten": 10066 * a=`sleep 1;echo A` exec 3>&-; echo $a 10067 * sleeps, but prints nothing. 10068 */ 10069 enter_var_nest_level(); 10070 G.shadowed_vars_pp = &old_vars; 10071 rcode = redirect_and_varexp_helper(command, 10072 /*squirrel:*/ ERR_PTR, 10073 argv_expanded 10074 ); 10075 G.shadowed_vars_pp = sv_shadowed; 10076 /* rcode=1 can be if redir file can't be opened */ 10077 10078 goto clean_up_and_ret1; 10079 } 10080 10081 /* Bump var nesting, or this will leak exported $a: 10082 * a=b true; env | grep ^a= 10083 */ 10084 enter_var_nest_level(); 10085 /* Collect all variables "shadowed" by helper 10086 * (IOW: old vars overridden by "var1=val1 var2=val2 cmd..." syntax) 10087 * into old_vars list: 10088 */ 10089 G.shadowed_vars_pp = &old_vars; 10090 rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded); 10091 if (rcode == 0) { 10092 if (!funcp) { 10093 /* Do not collect *to old_vars list* vars shadowed 10094 * by e.g. "local VAR" builtin (collect them 10095 * in the previously nested list instead): 10096 * don't want them to be restored immediately 10097 * after "local" completes. 10098 */ 10099 G.shadowed_vars_pp = sv_shadowed; 10100 10101 debug_printf_exec(": builtin '%s' '%s'...\n", 10102 x->b_cmd, argv_expanded[1]); 10103 fflush_all(); 10104 rcode = x->b_function(argv_expanded) & 0xff; 10105 fflush_all(); 10106 } 10107#if ENABLE_HUSH_FUNCTIONS 10108 else { 10109 debug_printf_exec(": function '%s' '%s'...\n", 10110 funcp->name, argv_expanded[1]); 10111 rcode = run_function(funcp, argv_expanded) & 0xff; 10112 /* 10113 * But do collect *to old_vars list* vars shadowed 10114 * within function execution. To that end, restore 10115 * this pointer _after_ function run: 10116 */ 10117 G.shadowed_vars_pp = sv_shadowed; 10118 } 10119#endif 10120 } 10121 } else 10122 if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) { 10123 int n = find_applet_by_name(argv_expanded[0]); 10124 if (n < 0 || !APPLET_IS_NOFORK(n)) 10125 goto must_fork; 10126 10127 enter_var_nest_level(); 10128 /* Collect all variables "shadowed" by helper into old_vars list */ 10129 G.shadowed_vars_pp = &old_vars; 10130 rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded); 10131 G.shadowed_vars_pp = sv_shadowed; 10132 10133 if (rcode == 0) { 10134 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", 10135 argv_expanded[0], argv_expanded[1]); 10136 /* 10137 * Note: signals (^C) can't interrupt here. 10138 * We remember them and they will be acted upon 10139 * after applet returns. 10140 * This makes applets which can run for a long time 10141 * and/or wait for user input ineligible for NOFORK: 10142 * for example, "yes" or "rm" (rm -i waits for input). 10143 */ 10144 rcode = run_nofork_applet(n, argv_expanded); 10145 } 10146 } else 10147 goto must_fork; 10148 10149 restore_redirects(squirrel); 10150 clean_up_and_ret1: 10151 leave_var_nest_level(); 10152 add_vars(old_vars); 10153 10154 /* 10155 * Try "usleep 99999999" + ^C + "echo $?" 10156 * with FEATURE_SH_NOFORK=y. 10157 */ 10158 if (!funcp) { 10159 /* It was builtin or nofork. 10160 * if this would be a real fork/execed program, 10161 * it should have died if a fatal sig was received. 10162 * But OTOH, there was no separate process, 10163 * the sig was sent to _shell_, not to non-existing 10164 * child. 10165 * Let's just handle ^C only, this one is obvious: 10166 * we aren't ok with exitcode 0 when ^C was pressed 10167 * during builtin/nofork. 10168 */ 10169 if (sigismember(&G.pending_set, SIGINT)) 10170 rcode = 128 | SIGINT; 10171 } 10172 free(argv_expanded); 10173 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) 10174 debug_leave(); 10175 debug_printf_exec("run_pipe return %d\n", rcode); 10176 return rcode; 10177#endif /* !__U_BOOT__ */ 10178 } 10179 10180#ifndef __U_BOOT__ 10181 must_fork: 10182 /* NB: argv_expanded may already be created, and that 10183 * might include `cmd` runs! Do not rerun it! We *must* 10184 * use argv_expanded if it's non-NULL */ 10185 10186 /* Going to fork a child per each pipe member */ 10187 pi->alive_cmds = 0; 10188 next_infd = 0; 10189#endif /* !__U_BOOT__ */ 10190 10191 cmd_no = 0; 10192 while (cmd_no < pi->num_cmds) { 10193#ifndef __U_BOOT__ 10194 struct fd_pair pipefds; 10195#if !BB_MMU 10196 int sv_var_nest_level = G.var_nest_level; 10197 volatile nommu_save_t nommu_save; 10198 nommu_save.old_vars = NULL; 10199 nommu_save.argv = NULL; 10200 nommu_save.argv_from_re_execing = NULL; 10201#endif 10202#endif /* !__U_BOOT__ */ 10203 command = &pi->cmds[cmd_no]; 10204 cmd_no++; 10205 10206#ifdef __U_BOOT__ 10207 /* Replace argv and argc by expanded if it exists. */ 10208 if (argv_expanded) { 10209 /* 10210 * We need to save a pointer to argv, we will restore it 10211 * later, so it will be freed when pipe is freed. 10212 */ 10213 argv = command->argv; 10214 10215 /* 10216 * After expansion, there can be more or less argument, so we need to 10217 * update argc, for example: 10218 * - More arguments: 10219 * foo='bar quuz' 10220 * echo $foo 10221 * - Less arguments: 10222 * echo $foo (if foo was never set) 10223 */ 10224 command->argc = list_size(argv_expanded); 10225 command->argv = argv_expanded; 10226 } 10227#endif /* __U_BOOT__ */ 10228 if (command->argv) { 10229 debug_printf_exec(": pipe member '%s' '%s'...\n", 10230 command->argv[0], command->argv[1]); 10231 } else { 10232 debug_printf_exec(": pipe member with no argv\n"); 10233 } 10234 10235#ifndef __U_BOOT__ 10236 /* pipes are inserted between pairs of commands */ 10237 pipefds.rd = 0; 10238 pipefds.wr = 1; 10239 if (cmd_no < pi->num_cmds) 10240 xpiped_pair(pipefds); 10241 10242#if ENABLE_HUSH_LINENO_VAR 10243 G.execute_lineno = command->lineno; 10244#endif 10245 10246 command->pid = BB_MMU ? fork() : vfork(); 10247 if (!command->pid) { /* child */ 10248#if ENABLE_HUSH_JOB 10249 disable_restore_tty_pgrp_on_exit(); 10250 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ 10251 10252 /* Every child adds itself to new process group 10253 * with pgid == pid_of_first_child_in_pipe */ 10254 if (G.run_list_level == 1 && G_interactive_fd) { 10255 pid_t pgrp; 10256 pgrp = pi->pgrp; 10257 if (pgrp < 0) /* true for 1st process only */ 10258 pgrp = getpid(); 10259 if (setpgid(0, pgrp) == 0 10260 && pi->followup != PIPE_BG 10261 && G_saved_tty_pgrp /* we have ctty */ 10262 ) { 10263 /* We do it in *every* child, not just first, 10264 * to avoid races */ 10265 tcsetpgrp(G_interactive_fd, pgrp); 10266 } 10267 } 10268#endif 10269 if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) { 10270 /* 1st cmd in backgrounded pipe 10271 * should have its stdin /dev/null'ed */ 10272 close(0); 10273 if (open(bb_dev_null, O_RDONLY)) 10274 xopen("/", O_RDONLY); 10275 } else { 10276 xmove_fd(next_infd, 0); 10277 } 10278 xmove_fd(pipefds.wr, 1); 10279 if (pipefds.rd > 1) 10280 close(pipefds.rd); 10281 /* Like bash, explicit redirects override pipes, 10282 * and the pipe fd (fd#1) is available for dup'ing: 10283 * "cmd1 2>&1 | cmd2": fd#1 is duped to fd#2, thus stderr 10284 * of cmd1 goes into pipe. 10285 */ 10286 if (setup_redirects(command, NULL)) { 10287 /* Happens when redir file can't be opened: 10288 * $ hush -c 'echo FOO >&2 | echo BAR 3>/qwe/rty; echo BAZ' 10289 * FOO 10290 * hush: can't open '/qwe/rty': No such file or directory 10291 * BAZ 10292 * (echo BAR is not executed, it hits _exit(1) below) 10293 */ 10294 _exit(1); 10295 } 10296 10297 /* Stores to nommu_save list of env vars putenv'ed 10298 * (NOMMU, on MMU we don't need that) */ 10299 /* cast away volatility... */ 10300 pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded); 10301 /* pseudo_exec() does not return */ 10302 } 10303 10304 /* parent or error */ 10305#if ENABLE_HUSH_FAST 10306 G.count_SIGCHLD++; 10307//bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); 10308#endif 10309 enable_restore_tty_pgrp_on_exit(); 10310#if !BB_MMU 10311 /* Clean up after vforked child */ 10312 free(nommu_save.argv); 10313 free(nommu_save.argv_from_re_execing); 10314 G.var_nest_level = sv_var_nest_level; 10315 remove_nested_vars(); 10316 add_vars(nommu_save.old_vars); 10317#endif 10318 free(argv_expanded); 10319 argv_expanded = NULL; 10320 if (command->pid < 0) { /* [v]fork failed */ 10321 /* Clearly indicate, was it fork or vfork */ 10322 bb_simple_perror_msg(BB_MMU ? "vfork"+1 : "vfork"); 10323 } else { 10324 pi->alive_cmds++; 10325#if ENABLE_HUSH_JOB 10326 /* Second and next children need to know pid of first one */ 10327 if (pi->pgrp < 0) 10328 pi->pgrp = command->pid; 10329#endif 10330 } 10331 10332 if (cmd_no > 1) 10333 close(next_infd); 10334 if (cmd_no < pi->num_cmds) 10335 close(pipefds.wr); 10336 /* Pass read (output) pipe end to next iteration */ 10337 next_infd = pipefds.rd; 10338#else /* __U_BOOT__ */ 10339 /* Process the command */ 10340 rcode = cmd_process(G.do_repeat ? CMD_FLAG_REPEAT : 0, 10341 command->argc, command->argv, 10342 &(G.flag_repeat), NULL); 10343 10344 if (argv_expanded) { 10345 /* 10346 * expand_strvec_to_strvec() allocates memory to expand 10347 * argv, we need to free it. 10348 */ 10349 free(argv_expanded); 10350 10351 /* 10352 * We also restore command->argv to its original value 10353 * so no memory leak happens. 10354 */ 10355 command->argv = argv; 10356 10357 /* 10358 * NOTE argc exists only in U-Boot, so argv freeing does 10359 * not rely on it as this code exists in BusyBox. 10360 */ 10361 } 10362#endif /* __U_BOOT__ */ 10363 } 10364 10365#ifndef __U_BOOT__ 10366 if (!pi->alive_cmds) { 10367 debug_leave(); 10368 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n"); 10369 return 1; 10370 } 10371#endif /* __U_BOOT__ */ 10372 10373 debug_leave(); 10374#ifndef __U_BOOT__ 10375 debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds); 10376 return -1; 10377#else /* __U_BOOT__ */ 10378 debug_printf_exec("run_pipe return %d\n", rcode); 10379 return rcode; 10380#endif /* __U_BOOT__ */ 10381} 10382 10383/* NB: called by pseudo_exec, and therefore must not modify any 10384 * global data until exec/_exit (we can be a child after vfork!) */ 10385static int run_list(struct pipe *pi) 10386{ 10387#if ENABLE_HUSH_CASE 10388 char *case_word = NULL; 10389#endif 10390#if ENABLE_HUSH_LOOPS 10391 struct pipe *loop_top = NULL; 10392 char **for_lcur = NULL; 10393 char **for_list = NULL; 10394#endif 10395 smallint last_followup; 10396 smalluint rcode; 10397#if ENABLE_HUSH_IF || ENABLE_HUSH_CASE 10398 smalluint cond_code = 0; 10399#else 10400 enum { cond_code = 0 }; 10401#endif 10402#if HAS_KEYWORDS 10403 smallint rword; /* RES_foo */ 10404 smallint last_rword; /* ditto */ 10405#endif 10406 10407#ifndef __U_BOOT__ 10408 debug_printf_exec("run_list lvl %d start\n", G.run_list_level); 10409 debug_enter(); 10410#endif /* !__U_BOOT__ */ 10411 10412 set_G_ifs(); 10413 10414#if ENABLE_HUSH_LOOPS 10415 /* Check syntax for "for" */ 10416 { 10417 struct pipe *cpipe; 10418 for (cpipe = pi; cpipe; cpipe = cpipe->next) { 10419 if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN) 10420 continue; 10421 /* current word is FOR or IN (BOLD in comments below) */ 10422 if (cpipe->next == NULL) { 10423 syntax_error("malformed for"); 10424 debug_leave(); 10425 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level); 10426 return 1; 10427 } 10428 /* "FOR v; do ..." and "for v IN a b; do..." are ok */ 10429 if (cpipe->next->res_word == RES_DO) 10430 continue; 10431 /* next word is not "do". It must be "in" then ("FOR v in ...") */ 10432 if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */ 10433 || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */ 10434 ) { 10435 syntax_error("malformed for"); 10436 debug_leave(); 10437 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level); 10438 return 1; 10439 } 10440 } 10441 } 10442#endif 10443 10444 /* Past this point, all code paths should jump to ret: label 10445 * in order to return, no direct "return" statements please. 10446 * This helps to ensure that no memory is leaked. */ 10447 10448#if ENABLE_HUSH_JOB 10449 G.run_list_level++; 10450#endif 10451 10452#if HAS_KEYWORDS 10453 rword = RES_NONE; 10454 last_rword = RES_XXXX; 10455#endif 10456 last_followup = PIPE_SEQ; 10457 rcode = G.last_exitcode; 10458 10459 /* Go through list of pipes, (maybe) executing them. */ 10460#ifndef __U_BOOT__ 10461 for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) { 10462#else /* __U_BOOT__ */ 10463 for (; pi; pi = rword == RES_DONE ? loop_top : pi->next) { 10464#endif /* __U_BOOT__ */ 10465 int r; 10466 int sv_errexit_depth; 10467 10468#ifndef __U_BOOT__ 10469 if (G.flag_SIGINT) 10470 break; 10471 if (G_flag_return_in_progress == 1) 10472 break; 10473#endif /* !__U_BOOT__ */ 10474 10475 IF_HAS_KEYWORDS(rword = pi->res_word;) 10476 debug_printf_exec(": rword:%d cond_code:%d last_rword:%d\n", 10477 rword, cond_code, last_rword); 10478 10479 sv_errexit_depth = G.errexit_depth; 10480 if ( 10481#if ENABLE_HUSH_IF 10482 rword == RES_IF || rword == RES_ELIF || 10483#endif 10484 pi->followup != PIPE_SEQ 10485 ) { 10486 G.errexit_depth++; 10487 } 10488#if ENABLE_HUSH_LOOPS 10489 if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) 10490 && loop_top == NULL /* avoid bumping G.depth_of_loop twice */ 10491 ) { 10492 /* start of a loop: remember where loop starts */ 10493 loop_top = pi; 10494 G.depth_of_loop++; 10495 } 10496#endif 10497 /* Still in the same "if...", "then..." or "do..." branch? */ 10498 if (IF_HAS_KEYWORDS(rword == last_rword &&) 1) { 10499 if ((rcode == 0 && last_followup == PIPE_OR) 10500 || (rcode != 0 && last_followup == PIPE_AND) 10501 ) { 10502 /* It is "<true> || CMD" or "<false> && CMD" 10503 * and we should not execute CMD */ 10504 debug_printf_exec("skipped cmd because of || or &&\n"); 10505 last_followup = pi->followup; 10506 goto dont_check_jobs_but_continue; 10507 } 10508 } 10509 last_followup = pi->followup; 10510#if ENABLE_HUSH_IF 10511 if (cond_code != 0) { 10512 if (rword == RES_THEN) { 10513 /* if false; then ... fi has exitcode 0! */ 10514 G.last_exitcode = rcode = EXIT_SUCCESS; 10515 /* "if <false> THEN cmd": skip cmd */ 10516 debug_printf_exec("skipped THEN cmd because IF condition was false\n"); 10517 last_rword = rword; 10518 continue; 10519 } 10520 } else { 10521 if (rword == RES_ELSE 10522 || (rword == RES_ELIF && last_rword != RES_ELIF) 10523 ) { 10524 /* "if <true> then ... ELSE/ELIF cmd": 10525 * skip cmd and all following ones */ 10526 debug_printf_exec("skipped ELSE/ELIF branch because IF condition was true\n"); 10527 break; 10528 } 10529 //if (rword == RES_THEN): "if <true> THEN cmd", run cmd (fall through) 10530 } 10531#endif 10532 IF_HAS_KEYWORDS(last_rword = rword;) 10533#if ENABLE_HUSH_LOOPS 10534 if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */ 10535 if (!for_lcur) { 10536 /* first loop through for */ 10537 10538 static const char encoded_dollar_at[] ALIGN1 = { 10539 SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0' 10540 }; /* encoded representation of "$@" */ 10541 static const char *const encoded_dollar_at_argv[] ALIGN_PTR = { 10542 encoded_dollar_at, NULL 10543 }; /* argv list with one element: "$@" */ 10544 char **vals; 10545 10546 G.last_exitcode = rcode = EXIT_SUCCESS; 10547 vals = (char**)encoded_dollar_at_argv; 10548 if (pi->next->res_word == RES_IN) { 10549 /* if no variable values after "in" we skip "for" */ 10550 if (!pi->next->cmds[0].argv) { 10551 debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n"); 10552 break; 10553 } 10554 vals = pi->next->cmds[0].argv; 10555 } /* else: "for var; do..." -> assume "$@" list */ 10556 /* create list of variable values */ 10557 debug_print_strings("for_list made from", vals); 10558 for_list = expand_strvec_to_strvec(vals); 10559 for_lcur = for_list; 10560 debug_print_strings("for_list", for_list); 10561 } 10562 if (!*for_lcur) { 10563 /* "for" loop is over, clean up */ 10564 free(for_list); 10565 for_list = NULL; 10566 for_lcur = NULL; 10567 break; 10568 } 10569 /* Insert next value from for_lcur */ 10570 /* note: *for_lcur already has quotes removed, $var expanded, etc */ 10571#ifndef __U_BOOT__ 10572 set_local_var_from_halves(pi->cmds[0].argv[0], *for_lcur++); 10573#else /* __U_BOOT__ */ 10574 /* We cannot use xasprintf, so we emulate it. */ 10575 char *full_var; 10576 char *var = pi->cmds[0].argv[0]; 10577 char *val = *for_lcur++; 10578 10579 /* + 1 to take into account =. */ 10580 full_var = xmalloc(strlen(var) + strlen(val) + 1); 10581 sprintf(full_var, "%s=%s", var, val); 10582 10583 set_local_var_modern(full_var, /*flag:*/ 0); 10584#endif /* __U_BOOT__ */ 10585 continue; 10586 } 10587 if (rword == RES_IN) { 10588 continue; /* "for v IN list;..." - "in" has no cmds anyway */ 10589 } 10590 if (rword == RES_DONE) { 10591 continue; /* "done" has no cmds too */ 10592 } 10593#endif 10594#if ENABLE_HUSH_CASE 10595 if (rword == RES_CASE) { 10596 debug_printf_exec("CASE cond_code:%d\n", cond_code); 10597 case_word = expand_string_to_string(pi->cmds->argv[0], 10598 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1); 10599 debug_printf_exec("CASE word1:'%s'\n", case_word); 10600 //unbackslash(case_word); 10601 //debug_printf_exec("CASE word2:'%s'\n", case_word); 10602 continue; 10603 } 10604 if (rword == RES_MATCH) { 10605 char **argv; 10606 10607 debug_printf_exec("MATCH cond_code:%d\n", cond_code); 10608 if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */ 10609 break; 10610 /* all prev words didn't match, does this one match? */ 10611 argv = pi->cmds->argv; 10612 while (*argv) { 10613 char *pattern; 10614 debug_printf_exec("expand_string_to_string('%s')\n", *argv); 10615 pattern = expand_string_to_string(*argv, 10616 EXP_FLAG_ESC_GLOB_CHARS, 10617 /*unbackslash:*/ 0 10618 ); 10619 /* TODO: which FNM_xxx flags to use? */ 10620 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); 10621 debug_printf_exec("cond_code=fnmatch(pattern:'%s',str:'%s'):%d\n", 10622 pattern, case_word, cond_code); 10623 free(pattern); 10624 if (cond_code == 0) { 10625 /* match! we will execute this branch */ 10626 free(case_word); 10627 case_word = NULL; /* make future "word)" stop */ 10628 break; 10629 } 10630 argv++; 10631 } 10632 continue; 10633 } 10634 if (rword == RES_CASE_BODY) { /* inside of a case branch */ 10635 debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code); 10636 if (cond_code != 0) 10637 continue; /* not matched yet, skip this pipe */ 10638 } 10639 if (rword == RES_ESAC) { 10640 debug_printf_exec("ESAC cond_code:%d\n", cond_code); 10641 if (case_word) { 10642 /* "case" did not match anything: still set $? (to 0) */ 10643 G.last_exitcode = rcode = EXIT_SUCCESS; 10644 } 10645 } 10646#endif 10647 /* Just pressing <enter> in shell should check for jobs. 10648 * OTOH, in non-interactive shell this is useless 10649 * and only leads to extra job checks */ 10650 if (pi->num_cmds == 0) { 10651#ifndef __U_BOOT__ 10652 if (G_interactive_fd) 10653 goto check_jobs_and_continue; 10654#endif /* !__U_BOOT__ */ 10655 continue; 10656 } 10657 10658 /* After analyzing all keywords and conditions, we decided 10659 * to execute this pipe. NB: have to do checkjobs(NULL) 10660 * after run_pipe to collect any background children, 10661 * even if list execution is to be stopped. */ 10662 debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds); 10663#ifndef __U_BOOT__ 10664#if ENABLE_HUSH_LOOPS 10665 G.flag_break_continue = 0; 10666#endif 10667#endif /* !__U_BOOT__ */ 10668#ifndef __U_BOOT__ 10669 rcode = r = G.o_opt[OPT_O_NOEXEC] ? 0 : run_pipe(pi); 10670 /* NB: rcode is a smalluint, r is int */ 10671#else /* __U_BOOT__ */ 10672 rcode = r = run_pipe(pi); /* NB: rcode is a smalluint, r is int */ 10673 if (r <= EXIT_RET_CODE) { 10674 int previous_rcode = G.last_exitcode; 10675 /* 10676 * This magic is to get the exit code given by the user. 10677 * Contrary to old shell code, we use + EXIT_RET_CODE as EXIT_RET_CODE 10678 * equals -2. 10679 */ 10680 G.last_exitcode = -r + EXIT_RET_CODE; 10681 10682 /* 10683 * This case deals with the following: 10684 * => setenv inner 'echo entry inner; exit; echo inner done' 10685 * => setenv outer 'echo entry outer; run inner; echo outer done' 10686 * => run outer 10687 * So, if we are in inner, we need to break and not run the other 10688 * commands. 10689 * Otherwise, we just continue in outer. 10690 * As return code are propagated, we use the previous value to check if 10691 * exit was just called or was propagated. 10692 */ 10693 if (previous_rcode != r) { 10694 /* 10695 * If run from run_command, run_command_flags will be set, so we check 10696 * this to know if we are in main input shell. 10697 */ 10698 if (!G.run_command_flags) 10699 printf("exit not allowed from main input shell.\n"); 10700 10701 break; 10702 } 10703 continue; 10704 } 10705#endif /* __U_BOOT__ */ 10706 if (r != -1) { 10707 /* We ran a builtin, function, or group. 10708 * rcode is already known 10709 * and we don't need to wait for anything. */ 10710 debug_printf_exec(": builtin/func exitcode %d\n", rcode); 10711 G.last_exitcode = rcode; 10712#ifndef __U_BOOT__ 10713 check_and_run_traps(); 10714#endif /* !__U_BOOT__ */ 10715#if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS 10716 rcode = G.last_exitcode; /* "return" in trap can change it, read back */ 10717#endif 10718#ifndef __U_BOOT__ 10719#if ENABLE_HUSH_LOOPS 10720 /* Was it "break" or "continue"? */ 10721 if (G.flag_break_continue) { 10722 smallint fbc = G.flag_break_continue; 10723 /* We might fall into outer *loop*, 10724 * don't want to break it too */ 10725 if (loop_top) { 10726 G.depth_break_continue--; 10727 if (G.depth_break_continue == 0) 10728 G.flag_break_continue = 0; 10729 /* else: e.g. "continue 2" should *break* once, *then* continue */ 10730 } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */ 10731 if (G.depth_break_continue != 0 || fbc == BC_BREAK) { 10732 checkjobs(NULL, 0 /*(no pid to wait for)*/); 10733 break; 10734 } 10735 /* "continue": simulate end of loop */ 10736 rword = RES_DONE; 10737 continue; 10738 } 10739#endif 10740 if (G_flag_return_in_progress == 1) { 10741 checkjobs(NULL, 0 /*(no pid to wait for)*/); 10742 break; 10743 } 10744 10745 } else if (pi->followup == PIPE_BG) { 10746 /* What does bash do with attempts to background builtins? */ 10747 /* even bash 3.2 doesn't do that well with nested bg: 10748 * try "{ { sleep 10; echo DEEP; } & echo HERE; } &". 10749 * I'm NOT treating inner &'s as jobs */ 10750#if ENABLE_HUSH_JOB 10751 if (G.run_list_level == 1) 10752 insert_job_into_table(pi); 10753#endif 10754 /* Last command's pid goes to $! */ 10755 G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid; 10756 G.last_bg_pid_exitcode = 0; 10757 debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n"); 10758/* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash say 0 */ 10759 rcode = EXIT_SUCCESS; 10760 goto check_traps; 10761 } else { 10762#if ENABLE_HUSH_JOB 10763 if (G.run_list_level == 1 && G_interactive_fd) { 10764 /* Waits for completion, then fg's main shell */ 10765 rcode = checkjobs_and_fg_shell(pi); 10766 debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode); 10767 goto check_traps; 10768 } 10769#endif 10770 /* This one just waits for completion */ 10771 rcode = checkjobs(pi, 0 /*(no pid to wait for)*/); 10772 debug_printf_exec(": checkjobs exitcode %d\n", rcode); 10773 check_traps: 10774 G.last_exitcode = rcode; 10775 check_and_run_traps(); 10776#if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS 10777 rcode = G.last_exitcode; /* "return" in trap can change it, read back */ 10778#endif 10779 } 10780#endif /* !__U_BOOT__ */ 10781 10782#ifndef __U_BOOT__ 10783 /* Handle "set -e" */ 10784 if (rcode != 0 && G.o_opt[OPT_O_ERREXIT]) { 10785 debug_printf_exec("ERREXIT:1 errexit_depth:%d\n", G.errexit_depth); 10786 if (G.errexit_depth == 0) 10787 hush_exit(rcode); 10788 } 10789#else /* __U_BOOT__ */ 10790 } /* if (r != -1) */ 10791#endif /* __U_BOOT__ */ 10792 G.errexit_depth = sv_errexit_depth; 10793 10794 /* Analyze how result affects subsequent commands */ 10795#if ENABLE_HUSH_IF 10796 if (rword == RES_IF || rword == RES_ELIF) { 10797 debug_printf_exec("cond_code=rcode:%d\n", rcode); 10798 cond_code = rcode; 10799 } 10800#endif 10801#ifndef __U_BOOT__ 10802 check_jobs_and_continue: 10803 checkjobs(NULL, 0 /*(no pid to wait for)*/); 10804#endif /* !__U_BOOT__ */ 10805 dont_check_jobs_but_continue: ; 10806#if ENABLE_HUSH_LOOPS 10807 /* Beware of "while false; true; do ..."! */ 10808 if (pi->next 10809 && (pi->next->res_word == RES_DO || pi->next->res_word == RES_DONE) 10810 /* check for RES_DONE is needed for "while ...; do \n done" case */ 10811 ) { 10812 if (rword == RES_WHILE) { 10813 if (rcode) { 10814 /* "while false; do...done" - exitcode 0 */ 10815 G.last_exitcode = rcode = EXIT_SUCCESS; 10816 debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n"); 10817 break; 10818 } 10819 } 10820 if (rword == RES_UNTIL) { 10821 if (!rcode) { 10822 debug_printf_exec(": until expr is true: breaking\n"); 10823 break; 10824 } 10825 } 10826 } 10827#endif 10828 } /* for (pi) */ 10829 10830#if ENABLE_HUSH_JOB 10831 G.run_list_level--; 10832#endif 10833#if ENABLE_HUSH_LOOPS 10834 if (loop_top) 10835 G.depth_of_loop--; 10836 free(for_list); 10837#endif 10838#if ENABLE_HUSH_CASE 10839 free(case_word); 10840#endif 10841#ifndef __U_BOOT__ 10842 debug_leave(); 10843 debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level, rcode); 10844#endif /* !__U_BOOT__ */ 10845 return rcode; 10846} 10847 10848/* Select which version we will use */ 10849static int run_and_free_list(struct pipe *pi) 10850{ 10851 int rcode = 0; 10852 debug_printf_exec("run_and_free_list entered\n"); 10853#ifndef __U_BOOT__ 10854 if (!G.o_opt[OPT_O_NOEXEC]) { 10855#endif /* !__U_BOOT__ */ 10856 debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds); 10857 rcode = run_list(pi); 10858#ifndef __U_BOOT__ 10859 } 10860#endif /* !__U_BOOT__ */ 10861 /* free_pipe_list has the side effect of clearing memory. 10862 * In the long run that function can be merged with run_list, 10863 * but doing that now would hobble the debugging effort. */ 10864 free_pipe_list(pi); 10865 debug_printf_exec("run_and_free_list return %d\n", rcode); 10866 return rcode; 10867} 10868 10869#ifndef __U_BOOT__ 10870static void install_sighandlers(unsigned mask) 10871{ 10872 sighandler_t old_handler; 10873 unsigned sig = 0; 10874 while ((mask >>= 1) != 0) { 10875 sig++; 10876 if (!(mask & 1)) 10877 continue; 10878 old_handler = install_sighandler(sig, pick_sighandler(sig)); 10879 /* POSIX allows shell to re-enable SIGCHLD 10880 * even if it was SIG_IGN on entry. 10881 * Therefore we skip IGN check for it: 10882 */ 10883 if (sig == SIGCHLD) 10884 continue; 10885 /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry. 10886 * Try: 10887 * trap '' hup; bash; echo RET # type "kill -hup $$", see SIGHUP having effect 10888 * trap '' hup; bash -c 'kill -hup $$; echo ALIVE' # here SIGHUP is SIG_IGNed 10889 */ 10890 if (sig == SIGHUP && G_interactive_fd) 10891 continue; 10892 /* Unless one of the above signals, is it SIG_IGN? */ 10893 if (old_handler == SIG_IGN) { 10894 /* oops... restore back to IGN, and record this fact */ 10895 install_sighandler(sig, old_handler); 10896#if ENABLE_HUSH_TRAP 10897 if (!G_traps) 10898 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG); 10899 free(G_traps[sig]); 10900 G_traps[sig] = xzalloc(1); /* == xstrdup(""); */ 10901#endif 10902 } 10903 } 10904} 10905 10906/* Called a few times only (or even once if "sh -c") */ 10907static void install_special_sighandlers(void) 10908{ 10909 unsigned mask; 10910 10911 /* Which signals are shell-special? */ 10912 mask = (1 << SIGQUIT) | (1 << SIGCHLD); 10913 if (G_interactive_fd) { 10914 mask |= SPECIAL_INTERACTIVE_SIGS; 10915 if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */ 10916 mask |= SPECIAL_JOBSTOP_SIGS; 10917 } 10918 /* Careful, do not re-install handlers we already installed */ 10919 if (G.special_sig_mask != mask) { 10920 unsigned diff = mask & ~G.special_sig_mask; 10921 G.special_sig_mask = mask; 10922 install_sighandlers(diff); 10923 } 10924} 10925 10926#if ENABLE_HUSH_JOB 10927/* helper */ 10928/* Set handlers to restore tty pgrp and exit */ 10929static void install_fatal_sighandlers(void) 10930{ 10931 unsigned mask; 10932 10933 /* We will restore tty pgrp on these signals */ 10934 mask = 0 10935 /*+ (1 << SIGILL ) * HUSH_DEBUG*/ 10936 /*+ (1 << SIGFPE ) * HUSH_DEBUG*/ 10937 + (1 << SIGBUS ) * HUSH_DEBUG 10938 + (1 << SIGSEGV) * HUSH_DEBUG 10939 /*+ (1 << SIGTRAP) * HUSH_DEBUG*/ 10940 + (1 << SIGABRT) 10941 /* bash 3.2 seems to handle these just like 'fatal' ones */ 10942 + (1 << SIGPIPE) 10943 + (1 << SIGALRM) 10944 /* if we are interactive, SIGHUP, SIGTERM and SIGINT are special sigs. 10945 * if we aren't interactive... but in this case 10946 * we never want to restore pgrp on exit, and this fn is not called 10947 */ 10948 /*+ (1 << SIGHUP )*/ 10949 /*+ (1 << SIGTERM)*/ 10950 /*+ (1 << SIGINT )*/ 10951 ; 10952 G_fatal_sig_mask = mask; 10953 10954 install_sighandlers(mask); 10955} 10956#endif 10957 10958static int set_mode(int state, char mode, const char *o_opt) 10959{ 10960 int idx; 10961 switch (mode) { 10962 case 'n': 10963 /* set -n has no effect in interactive shell */ 10964 /* Try: while set -n; do echo $-; done */ 10965 if (!G_interactive_fd) 10966 G.o_opt[OPT_O_NOEXEC] = state; 10967 break; 10968 case 'x': 10969 IF_HUSH_MODE_X(G_x_mode = state;) 10970 IF_HUSH_MODE_X(if (G.x_mode_fd <= 0) G.x_mode_fd = dup_CLOEXEC(2, 10);) 10971 break; 10972 case 'e': 10973 G.o_opt[OPT_O_ERREXIT] = state; 10974 break; 10975 case 'o': 10976 if (!o_opt) { 10977 /* "set -o" or "set +o" without parameter. 10978 * in bash, set -o produces this output: 10979 * pipefail off 10980 * and set +o: 10981 * set +o pipefail 10982 * We always use the second form. 10983 */ 10984 const char *p = o_opt_strings; 10985 idx = 0; 10986 while (*p) { 10987 printf("set %co %s\n", (G.o_opt[idx] ? '-' : '+'), p); 10988 idx++; 10989 p += strlen(p) + 1; 10990 } 10991 break; 10992 } 10993 idx = index_in_strings(o_opt_strings, o_opt); 10994 if (idx >= 0) { 10995 G.o_opt[idx] = state; 10996 break; 10997 } 10998 /* fall through to error */ 10999 default: 11000 return EXIT_FAILURE; 11001 } 11002 return EXIT_SUCCESS; 11003} 11004 11005int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 11006int hush_main(int argc, char **argv) 11007{ 11008 pid_t cached_getpid; 11009 enum { 11010 OPT_login = (1 << 0), 11011 }; 11012 unsigned flags; 11013#if !BB_MMU 11014 unsigned builtin_argc = 0; 11015#endif 11016 char **e; 11017 struct variable *cur_var; 11018 struct variable *shell_ver; 11019 11020 INIT_G(); 11021 if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */ 11022 G.last_exitcode = EXIT_SUCCESS; 11023#if !BB_MMU 11024 /* "Big heredoc" support via "sh -< STRING" invocation. 11025 * Check it first (do not bother to run the usual init code, 11026 * it is not needed for this case). 11027 */ 11028 if (argv[1] 11029 && argv[1][0] == '-' && argv[1][1] == '<' /*&& !argv[1][2]*/ 11030 /*&& argv[2] && !argv[3] - we don't check some conditions */ 11031 ) { 11032 full_write1_str(argv[2]); 11033 _exit(0); 11034 } 11035 G.argv0_for_re_execing = argv[0]; 11036#endif 11037#if ENABLE_HUSH_TRAP 11038# if ENABLE_HUSH_FUNCTIONS 11039 G.return_exitcode = -1; 11040# endif 11041 G.pre_trap_exitcode = -1; 11042#endif 11043 11044#if ENABLE_HUSH_FAST 11045 G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */ 11046#endif 11047 11048 cached_getpid = getpid(); /* for tcsetpgrp() during init */ 11049 G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ 11050 G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */ 11051 11052 /* Deal with HUSH_VERSION */ 11053 debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); 11054 unsetenv("HUSH_VERSION"); /* in case it exists in initial env */ 11055 shell_ver = xzalloc(sizeof(*shell_ver)); 11056 shell_ver->flg_export = 1; 11057 shell_ver->flg_read_only = 1; 11058 /* Code which handles ${var<op>...} needs writable values for all variables, 11059 * therefore we xstrdup: */ 11060 shell_ver->varstr = xstrdup(hush_version_str); 11061 11062 /* Create shell local variables from the values 11063 * currently living in the environment */ 11064 G.top_var = shell_ver; 11065 cur_var = G.top_var; 11066 e = environ; 11067 if (e) while (*e) { 11068 char *value = strchr(*e, '='); 11069 if (value) { /* paranoia */ 11070 cur_var->next = xzalloc(sizeof(*cur_var)); 11071 cur_var = cur_var->next; 11072 cur_var->varstr = *e; 11073 cur_var->max_len = strlen(*e); 11074 cur_var->flg_export = 1; 11075 } 11076 e++; 11077 } 11078 /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */ 11079 debug_printf_env("putenv '%s'\n", shell_ver->varstr); 11080 putenv(shell_ver->varstr); 11081 11082 /* Export PWD */ 11083 set_pwd_var(SETFLAG_EXPORT); 11084 11085#if BASH_HOSTNAME_VAR 11086 /* Set (but not export) HOSTNAME unless already set */ 11087 if (!get_local_var_value("HOSTNAME")) { 11088 struct utsname uts; 11089 uname(&uts); 11090 set_local_var_from_halves("HOSTNAME", uts.nodename); 11091 } 11092#endif 11093 /* IFS is not inherited from the parent environment */ 11094 set_local_var_from_halves("IFS", defifs); 11095 11096 if (!get_local_var_value("PATH")) 11097 set_local_var_from_halves("PATH", bb_default_root_path); 11098 11099 /* PS1/PS2 are set later, if we determine that we are interactive */ 11100 11101 /* bash also exports SHLVL and _, 11102 * and sets (but doesn't export) the following variables: 11103 * BASH=/bin/bash 11104 * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu") 11105 * BASH_VERSION='3.2.0(1)-release' 11106 * HOSTTYPE=i386 11107 * MACHTYPE=i386-pc-linux-gnu 11108 * OSTYPE=linux-gnu 11109 * PPID=<NNNNN> - we also do it elsewhere 11110 * EUID=<NNNNN> 11111 * UID=<NNNNN> 11112 * GROUPS=() 11113 * LINES=<NNN> 11114 * COLUMNS=<NNN> 11115 * BASH_ARGC=() 11116 * BASH_ARGV=() 11117 * BASH_LINENO=() 11118 * BASH_SOURCE=() 11119 * DIRSTACK=() 11120 * PIPESTATUS=([0]="0") 11121 * HISTFILE=/<xxx>/.bash_history 11122 * HISTFILESIZE=500 11123 * HISTSIZE=500 11124 * MAILCHECK=60 11125 * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:. 11126 * SHELL=/bin/bash 11127 * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor 11128 * TERM=dumb 11129 * OPTERR=1 11130 * OPTIND=1 11131 * PS4='+ ' 11132 */ 11133 11134#if NUM_SCRIPTS > 0 11135 if (argc < 0) { 11136 char *script = get_script_content(-argc - 1); 11137 G.global_argv = argv; 11138 G.global_argc = string_array_len(argv); 11139 //install_special_sighandlers(); - needed? 11140 parse_and_run_string(script); 11141 goto final_return; 11142 } 11143#endif 11144 11145 /* Initialize some more globals to non-zero values */ 11146 die_func = restore_ttypgrp_and__exit; 11147 11148 /* Shell is non-interactive at first. We need to call 11149 * install_special_sighandlers() if we are going to execute "sh <script>", 11150 * "sh -c <cmds>" or login shell's /etc/profile and friends. 11151 * If we later decide that we are interactive, we run install_special_sighandlers() 11152 * in order to intercept (more) signals. 11153 */ 11154 11155 /* Parse options */ 11156 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */ 11157 flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0; 11158 while (1) { 11159 int opt = getopt(argc, argv, "+" /* stop at 1st non-option */ 11160 "cexinsl" 11161#if !BB_MMU 11162 "$:R:V:" 11163# if ENABLE_HUSH_LINENO_VAR 11164 "L:" 11165# endif 11166# if ENABLE_HUSH_FUNCTIONS 11167 "F:" 11168# endif 11169#endif 11170 ); 11171 if (opt <= 0) 11172 break; 11173 switch (opt) { 11174 case 'c': 11175 /* Note: -c is not an option with param! 11176 * "hush -c -l SCRIPT" is valid. "hush -cSCRIPT" is not. 11177 */ 11178 G.opt_c = 1; 11179 break; 11180 case 'i': 11181 /* Well, we cannot just declare interactiveness, 11182 * we have to have some stuff (ctty, etc) */ 11183 /* G_interactive_fd++; */ 11184//There are a few cases where bash -i -c 'SCRIPT' 11185//has visible effect (differs from bash -c 'SCRIPT'): 11186//it ignores TERM: 11187// bash -i -c 'kill $$; echo ALIVE' 11188// ALIVE 11189//it resets SIG_IGNed HUP to SIG_DFL: 11190// trap '' hup; bash -i -c 'kill -hup $$; echo ALIVE' 11191// Hangup [the message is not printed by bash, it's the shell which started it] 11192//is talkative about jobs and exiting: 11193// bash -i -c 'sleep 1 & exit' 11194// [1] 16170 11195// exit 11196//includes $ENV file (only if run as "sh"): 11197// echo last >/tmp/ENV; ENV=/tmp/ENV sh -i -c 'echo HERE' 11198// last: cannot open /var/log/wtmp: No such file or directory 11199// HERE 11200//(under "bash", it's the opposite: it runs $BASH_ENV file only *without* -i). 11201// 11202//ash -i -c 'sleep 3; sleep 3', on ^C, drops into a prompt instead of exiting 11203//(this may be a bug, bash does not do this). 11204//(ash -i -c 'sleep 3' won't show this, the last command gets auto-"exec"ed) 11205// 11206//None of the above feel like useful features people would rely on. 11207 break; 11208 case 's': 11209 G.opt_s = 1; 11210 break; 11211 case 'l': 11212 flags |= OPT_login; 11213 break; 11214#if !BB_MMU 11215 case '$': { 11216 unsigned long long empty_trap_mask; 11217 11218 G.root_pid = bb_strtou(optarg, &optarg, 16); 11219 optarg++; 11220 G.root_ppid = bb_strtou(optarg, &optarg, 16); 11221 optarg++; 11222 G.last_bg_pid = bb_strtou(optarg, &optarg, 16); 11223 optarg++; 11224 G.last_exitcode = bb_strtou(optarg, &optarg, 16); 11225 optarg++; 11226 builtin_argc = bb_strtou(optarg, &optarg, 16); 11227 optarg++; 11228 empty_trap_mask = bb_strtoull(optarg, &optarg, 16); 11229 if (empty_trap_mask != 0) { 11230 IF_HUSH_TRAP(int sig;) 11231 install_special_sighandlers(); 11232# if ENABLE_HUSH_TRAP 11233 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG); 11234 for (sig = 1; sig < NSIG; sig++) { 11235 if (empty_trap_mask & (1LL << sig)) { 11236 G_traps[sig] = xzalloc(1); /* == xstrdup(""); */ 11237 install_sighandler(sig, SIG_IGN); 11238 } 11239 } 11240# endif 11241 } 11242# if ENABLE_HUSH_LOOPS 11243 optarg++; 11244 G.depth_of_loop = bb_strtou(optarg, &optarg, 16); 11245# endif 11246 /* Suppress "killed by signal" message, -$ hack is used 11247 * for subshells: echo `sh -c 'kill -9 $$'` 11248 * should be silent. 11249 */ 11250 IF_HUSH_JOB(G.run_list_level = 1;) 11251# if ENABLE_HUSH_FUNCTIONS 11252 /* nommu uses re-exec trick for "... | func | ...", 11253 * should allow "return". 11254 * This accidentally allows returns in subshells. 11255 */ 11256 G_flag_return_in_progress = -1; 11257# endif 11258 break; 11259 } 11260 case 'R': 11261 case 'V': 11262 set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0); 11263 break; 11264# if ENABLE_HUSH_LINENO_VAR 11265 case 'L': 11266 G.parse_lineno = xatou(optarg); 11267 break; 11268# endif 11269# if ENABLE_HUSH_FUNCTIONS 11270 case 'F': { 11271 struct function *funcp = new_function(optarg); 11272 /* funcp->name is already set to optarg */ 11273 /* funcp->body is set to NULL. It's a special case. */ 11274 funcp->body_as_string = argv[optind]; 11275 optind++; 11276 break; 11277 } 11278# endif 11279#endif 11280 /*case '?': invalid option encountered (set_mode('?') will fail) */ 11281 /*case 'n':*/ 11282 /*case 'x':*/ 11283 /*case 'e':*/ 11284 default: 11285 if (set_mode(1, opt, NULL) == 0) /* no error */ 11286 break; 11287 bb_show_usage(); 11288 } 11289 } /* option parsing loop */ 11290 11291 /* Skip options. Try "hush -l": $1 should not be "-l"! */ 11292 G.global_argc = argc - (optind - 1); 11293 G.global_argv = argv + (optind - 1); 11294 G.global_argv[0] = argv[0]; 11295 11296 /* If we are login shell... */ 11297 if (flags & OPT_login) { 11298 const char *hp = NULL; 11299 HFILE *input; 11300 11301 debug_printf("sourcing /etc/profile\n"); 11302 input = hfopen("/etc/profile"); 11303 run_profile: 11304 if (input != NULL) { 11305 install_special_sighandlers(); 11306 parse_and_run_file(input); 11307 hfclose(input); 11308 } 11309 /* bash: after sourcing /etc/profile, 11310 * tries to source (in the given order): 11311 * ~/.bash_profile, ~/.bash_login, ~/.profile, 11312 * stopping on first found. --noprofile turns this off. 11313 * bash also sources ~/.bash_logout on exit. 11314 * If called as sh, skips .bash_XXX files. 11315 */ 11316 if (!hp) { /* unless we looped on the "goto" already */ 11317 hp = get_local_var_value("HOME"); 11318 if (hp && hp[0]) { 11319 debug_printf("sourcing ~/.profile\n"); 11320 hp = concat_path_file(hp, ".profile"); 11321 input = hfopen(hp); 11322 free((char*)hp); 11323 goto run_profile; 11324 } 11325 } 11326 } 11327 11328#ifndef __U_BOOT__ 11329 /* -c takes effect *after* -l */ 11330 if (G.opt_c) { 11331 /* Possibilities: 11332 * sh ... -c 'script' 11333 * sh ... -c 'script' ARG0 [ARG1...] 11334 * On NOMMU, if builtin_argc != 0, 11335 * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...] 11336 * "" needs to be replaced with NULL 11337 * and BARGV vector fed to builtin function. 11338 * Note: the form without ARG0 never happens: 11339 * sh ... -c 'builtin' BARGV... "" 11340 */ 11341 char *script; 11342 11343 install_special_sighandlers(); 11344 11345 G.global_argc--; 11346 G.global_argv++; 11347#if !BB_MMU 11348 if (builtin_argc) { 11349 /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */ 11350 const struct built_in_command *x; 11351 x = find_builtin(G.global_argv[0]); 11352 if (x) { /* paranoia */ 11353 argv = G.global_argv; 11354 G.global_argc -= builtin_argc + 1; /* skip [BARGV...] "" */ 11355 G.global_argv += builtin_argc + 1; 11356 G.global_argv[-1] = NULL; /* replace "" */ 11357 G.last_exitcode = x->b_function(argv); 11358 } 11359 goto final_return; 11360 } 11361#endif 11362 11363 script = G.global_argv[0]; 11364 if (!script) 11365 bb_error_msg_and_die(bb_msg_requires_arg, "-c"); 11366 if (!G.global_argv[1]) { 11367 /* -c 'script' (no params): prevent empty $0 */ 11368 G.global_argv[0] = argv[0]; 11369 } else { /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ 11370 G.global_argc--; 11371 G.global_argv++; 11372 } 11373 parse_and_run_string(script); 11374 goto final_return; 11375 } 11376 11377 /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ 11378 if (!G.opt_s && G.global_argv[1]) { 11379 HFILE *input; 11380 /* 11381 * "bash <script>" (which is never interactive (unless -i?)) 11382 * sources $BASH_ENV here (without scanning $PATH). 11383 * If called as sh, does the same but with $ENV. 11384 * Also NB, per POSIX, $ENV should undergo parameter expansion. 11385 */ 11386 G.global_argc--; 11387 G.global_argv++; 11388 debug_printf("running script '%s'\n", G.global_argv[0]); 11389 xfunc_error_retval = 127; /* for "hush /does/not/exist" case */ 11390 input = hfopen(G.global_argv[0]); 11391 if (!input) { 11392 bb_simple_perror_msg_and_die(G.global_argv[0]); 11393 } 11394 xfunc_error_retval = 1; 11395 install_special_sighandlers(); 11396 parse_and_run_file(input); 11397#if ENABLE_FEATURE_CLEAN_UP 11398 hfclose(input); 11399#endif 11400 goto final_return; 11401 } 11402 /* "implicit" -s: bare interactive hush shows 's' in $- */ 11403 G.opt_s = 1; 11404 11405#endif /* __U_BOOT__ */ 11406 /* Up to here, shell was non-interactive. Now it may become one. 11407 * NB: don't forget to (re)run install_special_sighandlers() as needed. 11408 */ 11409 11410 /* A shell is interactive if the '-i' flag was given, 11411 * or if all of the following conditions are met: 11412 * no -c command 11413 * no arguments remaining or the -s flag given 11414 * standard input is a terminal 11415 * standard output is a terminal 11416 * Refer to Posix.2, the description of the 'sh' utility. 11417 */ 11418#if ENABLE_HUSH_JOB 11419 if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { 11420 G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO); 11421 debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp); 11422 if (G_saved_tty_pgrp < 0) 11423 G_saved_tty_pgrp = 0; 11424 11425 /* try to dup stdin to high fd#, >= 255 */ 11426 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254); 11427 if (G_interactive_fd < 0) { 11428 /* try to dup to any fd */ 11429 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1); 11430 if (G_interactive_fd < 0) { 11431 /* give up */ 11432 G_interactive_fd = 0; 11433 G_saved_tty_pgrp = 0; 11434 } 11435 } 11436 } 11437 debug_printf("interactive_fd:%d\n", G_interactive_fd); 11438 if (G_interactive_fd) { 11439 if (G_saved_tty_pgrp) { 11440 /* If we were run as 'hush &', sleep until we are 11441 * in the foreground (tty pgrp == our pgrp). 11442 * If we get started under a job aware app (like bash), 11443 * make sure we are now in charge so we don't fight over 11444 * who gets the foreground */ 11445 while (1) { 11446 pid_t shell_pgrp = getpgrp(); 11447 G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd); 11448 if (G_saved_tty_pgrp == shell_pgrp) 11449 break; 11450 /* send TTIN to ourself (should stop us) */ 11451 kill(- shell_pgrp, SIGTTIN); 11452 } 11453 } 11454 11455 /* Install more signal handlers */ 11456 install_special_sighandlers(); 11457 11458 if (G_saved_tty_pgrp) { 11459 /* Set other signals to restore saved_tty_pgrp */ 11460 install_fatal_sighandlers(); 11461 /* Put ourselves in our own process group 11462 * (bash, too, does this only if ctty is available) */ 11463 bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */ 11464 /* Grab control of the terminal */ 11465 tcsetpgrp(G_interactive_fd, cached_getpid); 11466 } 11467 enable_restore_tty_pgrp_on_exit(); 11468 11469# if ENABLE_FEATURE_EDITING 11470 G.line_input_state = new_line_input_t(FOR_SHELL); 11471# if ENABLE_FEATURE_TAB_COMPLETION 11472 G.line_input_state->get_exe_name = hush_command_name; 11473# endif 11474# if EDITING_HAS_sh_get_var 11475 G.line_input_state->sh_get_var = get_local_var_value; 11476# endif 11477# endif 11478# if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 11479 { 11480 const char *hp = get_local_var_value("HISTFILE"); 11481 if (!hp) { 11482 hp = get_local_var_value("HOME"); 11483 if (hp) 11484 hp = concat_path_file(hp, ".hush_history"); 11485 } else { 11486 hp = xstrdup(hp); 11487 } 11488 if (hp) { 11489 G.line_input_state->hist_file = hp; 11490 //set_local_var(xasprintf("HISTFILE=%s", ...)); 11491 } 11492# if ENABLE_FEATURE_SH_HISTFILESIZE 11493 hp = get_local_var_value("HISTFILESIZE"); 11494 G.line_input_state->max_history = size_from_HISTFILESIZE(hp); 11495# endif 11496 } 11497# endif 11498 } else { 11499 install_special_sighandlers(); 11500 } 11501#elif ENABLE_HUSH_INTERACTIVE 11502 /* No job control compiled in, only prompt/line editing */ 11503 if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { 11504 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254); 11505 if (G_interactive_fd < 0) { 11506 /* try to dup to any fd */ 11507 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1); 11508 if (G_interactive_fd < 0) 11509 /* give up */ 11510 G_interactive_fd = 0; 11511 } 11512 } 11513 install_special_sighandlers(); 11514#else 11515 /* We have interactiveness code disabled */ 11516 install_special_sighandlers(); 11517#endif 11518 /* bash: 11519 * if interactive but not a login shell, sources ~/.bashrc 11520 * (--norc turns this off, --rcfile <file> overrides) 11521 */ 11522 11523 if (G_interactive_fd) { 11524#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT 11525 /* Set (but not export) PS1/2 unless already set */ 11526 if (!get_local_var_value("PS1")) 11527 set_local_var_from_halves("PS1", "\\w \\$ "); 11528 if (!get_local_var_value("PS2")) 11529 set_local_var_from_halves("PS2", "> "); 11530#endif 11531 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) { 11532 /* note: ash and hush share this string */ 11533 printf("\n\n%s %s\n" 11534 IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n") 11535 "\n", 11536 bb_banner, 11537 "hush - the humble shell" 11538 ); 11539 } 11540 } 11541 11542 parse_and_run_file(hfopen(NULL)); /* stdin */ 11543 11544 final_return: 11545 hush_exit(G.last_exitcode); 11546} 11547 11548/* 11549 * Built-ins 11550 */ 11551static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM) 11552{ 11553 return 0; 11554} 11555 11556static int FAST_FUNC builtin_false(char **argv UNUSED_PARAM) 11557{ 11558 return 1; 11559} 11560 11561#if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL 11562static NOINLINE int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv)) 11563{ 11564 int argc = string_array_len(argv); 11565 return applet_main_func(argc, argv); 11566} 11567#endif 11568#if ENABLE_HUSH_TEST || BASH_TEST2 11569static int FAST_FUNC builtin_test(char **argv) 11570{ 11571 return run_applet_main(argv, test_main); 11572} 11573#endif 11574#if ENABLE_HUSH_ECHO 11575static int FAST_FUNC builtin_echo(char **argv) 11576{ 11577 return run_applet_main(argv, echo_main); 11578} 11579#endif 11580#if ENABLE_HUSH_PRINTF 11581static int FAST_FUNC builtin_printf(char **argv) 11582{ 11583 return run_applet_main(argv, printf_main); 11584} 11585#endif 11586 11587#if ENABLE_HUSH_HELP 11588static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM) 11589{ 11590 const struct built_in_command *x; 11591 11592 printf( 11593 "Built-in commands:\n" 11594 "------------------\n"); 11595 for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) { 11596 if (x->b_descr) 11597 printf("%-10s%s\n", x->b_cmd, x->b_descr); 11598 } 11599 return EXIT_SUCCESS; 11600} 11601#endif 11602 11603#if MAX_HISTORY && ENABLE_FEATURE_EDITING 11604static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM) 11605{ 11606 show_history(G.line_input_state); 11607 return EXIT_SUCCESS; 11608} 11609#endif 11610 11611static int FAST_FUNC builtin_cd(char **argv) 11612{ 11613 const char *newdir; 11614 11615 argv = skip_dash_dash(argv); 11616 newdir = argv[0]; 11617 if (newdir == NULL) { 11618 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset, 11619 * bash says "bash: cd: HOME not set" and does nothing 11620 * (exitcode 1) 11621 */ 11622 const char *home = get_local_var_value("HOME"); 11623 newdir = home ? home : "/"; 11624 } 11625 if (chdir(newdir)) { 11626 /* Mimic bash message exactly */ 11627 bb_perror_msg("cd: %s", newdir); 11628 return EXIT_FAILURE; 11629 } 11630 /* Read current dir (get_cwd(1) is inside) and set PWD. 11631 * Note: do not enforce exporting. If PWD was unset or unexported, 11632 * set it again, but do not export. bash does the same. 11633 */ 11634 set_pwd_var(/*flag:*/ 0); 11635 return EXIT_SUCCESS; 11636} 11637 11638static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM) 11639{ 11640 puts(get_cwd(0)); 11641 return EXIT_SUCCESS; 11642} 11643 11644static int FAST_FUNC builtin_eval(char **argv) 11645{ 11646 argv = skip_dash_dash(argv); 11647 11648 if (!argv[0]) 11649 return EXIT_SUCCESS; 11650 11651 IF_HUSH_MODE_X(G.x_mode_depth++;) 11652 //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); 11653 if (!argv[1]) { 11654 /* bash: 11655 * eval "echo Hi; done" ("done" is syntax error): 11656 * "echo Hi" will not execute too. 11657 */ 11658 parse_and_run_string(argv[0]); 11659 } else { 11660 /* "The eval utility shall construct a command by 11661 * concatenating arguments together, separating 11662 * each with a <space> character." 11663 */ 11664 char *str, *p; 11665 unsigned len = 0; 11666 char **pp = argv; 11667 do 11668 len += strlen(*pp) + 1; 11669 while (*++pp); 11670 str = p = xmalloc(len); 11671 pp = argv; 11672 for (;;) { 11673 p = stpcpy(p, *pp); 11674 pp++; 11675 if (!*pp) 11676 break; 11677 *p++ = ' '; 11678 } 11679 parse_and_run_string(str); 11680 free(str); 11681 } 11682 IF_HUSH_MODE_X(G.x_mode_depth--;) 11683 //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth); 11684 return G.last_exitcode; 11685} 11686 11687static int FAST_FUNC builtin_exec(char **argv) 11688{ 11689 argv = skip_dash_dash(argv); 11690 if (argv[0] == NULL) 11691 return EXIT_SUCCESS; /* bash does this */ 11692 11693 /* Careful: we can end up here after [v]fork. Do not restore 11694 * tty pgrp then, only top-level shell process does that */ 11695 if (G_saved_tty_pgrp && getpid() == G.root_pid) 11696 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp); 11697 11698 /* Saved-redirect fds, script fds and G_interactive_fd are still 11699 * open here. However, they are all CLOEXEC, and execv below 11700 * closes them. Try interactive "exec ls -l /proc/self/fd", 11701 * it should show no extra open fds in the "ls" process. 11702 * If we'd try to run builtins/NOEXECs, this would need improving. 11703 */ 11704 //close_saved_fds_and_FILE_fds(); 11705 11706 /* TODO: if exec fails, bash does NOT exit! We do. 11707 * We'll need to undo trap cleanup (it's inside execvp_or_die) 11708 * and tcsetpgrp, and this is inherently racy. 11709 */ 11710 execvp_or_die(argv); 11711} 11712 11713static int FAST_FUNC builtin_exit(char **argv) 11714{ 11715 debug_printf_exec("%s()\n", __func__); 11716 11717 /* interactive bash: 11718 * # trap "echo EEE" EXIT 11719 * # exit 11720 * exit 11721 * There are stopped jobs. 11722 * (if there are _stopped_ jobs, running ones don't count) 11723 * # exit 11724 * exit 11725 * EEE (then bash exits) 11726 * 11727 * TODO: we can use G.exiting = -1 as indicator "last cmd was exit" 11728 */ 11729 11730 /* note: EXIT trap is run by hush_exit */ 11731 argv = skip_dash_dash(argv); 11732 if (argv[0] == NULL) { 11733#if ENABLE_HUSH_TRAP 11734 if (G.pre_trap_exitcode >= 0) /* "exit" in trap uses $? from before the trap */ 11735 hush_exit(G.pre_trap_exitcode); 11736#endif 11737 hush_exit(G.last_exitcode); 11738 } 11739 /* mimic bash: exit 123abc == exit 255 + error msg */ 11740 xfunc_error_retval = 255; 11741 /* bash: exit -2 == exit 254, no error msg */ 11742 hush_exit(xatoi(argv[0]) & 0xff); 11743} 11744 11745#if ENABLE_HUSH_TYPE 11746/* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */ 11747static int FAST_FUNC builtin_type(char **argv) 11748{ 11749 int ret = EXIT_SUCCESS; 11750 11751 while (*++argv) { 11752 const char *type; 11753 char *path = NULL; 11754 11755 if (0) {} /* make conditional compile easier below */ 11756 /*else if (find_alias(*argv)) 11757 type = "an alias";*/ 11758# if ENABLE_HUSH_FUNCTIONS 11759 else if (find_function(*argv)) 11760 type = "a function"; 11761# endif 11762 else if (find_builtin(*argv)) 11763 type = "a shell builtin"; 11764 else if ((path = find_in_path(*argv)) != NULL) 11765 type = path; 11766 else { 11767 bb_error_msg("type: %s: not found", *argv); 11768 ret = EXIT_FAILURE; 11769 continue; 11770 } 11771 11772 printf("%s is %s\n", *argv, type); 11773 free(path); 11774 } 11775 11776 return ret; 11777} 11778#endif 11779 11780#if ENABLE_HUSH_READ 11781/* Interruptibility of read builtin in bash 11782 * (tested on bash-4.2.8 by sending signals (not by ^C)): 11783 * 11784 * Empty trap makes read ignore corresponding signal, for any signal. 11785 * 11786 * SIGINT: 11787 * - terminates non-interactive shell; 11788 * - interrupts read in interactive shell; 11789 * if it has non-empty trap: 11790 * - executes trap and returns to command prompt in interactive shell; 11791 * - executes trap and returns to read in non-interactive shell; 11792 * SIGTERM: 11793 * - is ignored (does not interrupt) read in interactive shell; 11794 * - terminates non-interactive shell; 11795 * if it has non-empty trap: 11796 * - executes trap and returns to read; 11797 * SIGHUP: 11798 * - terminates shell (regardless of interactivity); 11799 * if it has non-empty trap: 11800 * - executes trap and returns to read; 11801 * SIGCHLD from children: 11802 * - does not interrupt read regardless of interactivity: 11803 * try: sleep 1 & read x; echo $x 11804 */ 11805static int FAST_FUNC builtin_read(char **argv) 11806{ 11807 const char *r; 11808 struct builtin_read_params params; 11809 11810 memset(&params, 0, sizeof(params)); 11811 11812 /* "!": do not abort on errors. 11813 * Option string must start with "sr" to match BUILTIN_READ_xxx 11814 */ 11815 params.read_flags = getopt32(argv, 11816# if BASH_READ_D 11817 IF_NOT_HUSH_BASH_COMPAT("^") 11818 "!srn:p:t:u:d:" IF_NOT_HUSH_BASH_COMPAT("\0" "-1"/*min 1 arg*/), 11819 &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u, &params.opt_d 11820# else 11821 IF_NOT_HUSH_BASH_COMPAT("^") 11822 "!srn:p:t:u:" IF_NOT_HUSH_BASH_COMPAT("\0" "-1"/*min 1 arg*/), 11823 &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u 11824# endif 11825//TODO: print "read: need variable name" 11826//for the case of !BASH "read" with no args (now it fails silently) 11827//(or maybe extend getopt32() to emit a message if "-1" fails) 11828 ); 11829 if ((uint32_t)params.read_flags == (uint32_t)-1) 11830 return EXIT_FAILURE; 11831 argv += optind; 11832 params.argv = argv; 11833 params.setvar = set_local_var_from_halves; 11834 params.ifs = get_local_var_value("IFS"); /* can be NULL */ 11835 11836 again: 11837 r = shell_builtin_read(&params); 11838 11839 if ((uintptr_t)r == 1 && errno == EINTR) { 11840 unsigned sig = check_and_run_traps(); 11841 if (sig != SIGINT) 11842 goto again; 11843 } 11844 11845 if ((uintptr_t)r > 1) { 11846 bb_simple_error_msg(r); 11847 r = (char*)(uintptr_t)1; 11848 } 11849 11850 return (uintptr_t)r; 11851} 11852#endif 11853 11854#if ENABLE_HUSH_UMASK 11855static int FAST_FUNC builtin_umask(char **argv) 11856{ 11857 int rc; 11858 mode_t mask; 11859 11860 rc = 1; 11861 mask = umask(0); 11862 argv = skip_dash_dash(argv); 11863 if (argv[0]) { 11864 mode_t old_mask = mask; 11865 11866 /* numeric umasks are taken as-is */ 11867 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ 11868 if (!isdigit(argv[0][0])) 11869 mask ^= 0777; 11870 mask = bb_parse_mode(argv[0], mask); 11871 if (!isdigit(argv[0][0])) 11872 mask ^= 0777; 11873 if ((unsigned)mask > 0777) { 11874 mask = old_mask; 11875 /* bash messages: 11876 * bash: umask: 'q': invalid symbolic mode operator 11877 * bash: umask: 999: octal number out of range 11878 */ 11879 bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); 11880 rc = 0; 11881 } 11882 } else { 11883 /* Mimic bash */ 11884 printf("%04o\n", (unsigned) mask); 11885 /* fall through and restore mask which we set to 0 */ 11886 } 11887 umask(mask); 11888 11889 return !rc; /* rc != 0 - success */ 11890} 11891#endif 11892 11893#if ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY || ENABLE_HUSH_SET || ENABLE_HUSH_TRAP 11894static void print_escaped(const char *s) 11895{ 11896//TODO? bash "set" does not quote variables which contain only alnums and "%+,-./:=@_~", 11897// (but "export" quotes all variables, even with only these chars). 11898// I think quoting strings with %+,=~ looks better 11899// (example: "set" printing var== instead of var='=' looks strange) 11900// IOW: do not quote "-./:@_": / is used in pathnames, : in PATH, -._ often in file names, @ in emails 11901 11902 if (*s == '\'') 11903 goto squote; 11904 do { 11905 const char *p = strchrnul(s, '\''); 11906 /* print 'xxxx', possibly just '' */ 11907 printf("'%.*s'", (int)(p - s), s); 11908 if (*p == '\0') 11909 break; 11910 s = p; 11911 squote: 11912 /* s points to '; print "'''...'''" */ 11913 putchar('"'); 11914 do putchar('\''); while (*++s == '\''); 11915 putchar('"'); 11916 } while (*s); 11917} 11918#endif 11919 11920#if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY 11921static int helper_export_local(char **argv, unsigned flags) 11922{ 11923 do { 11924 char *name = *argv; 11925 const char *name_end = endofname(name); 11926 11927 if (*name_end == '\0') { 11928 struct variable *var, **vpp; 11929 11930 vpp = get_ptr_to_local_var(name); 11931 var = vpp ? *vpp : NULL; 11932 11933 if (flags & SETFLAG_UNEXPORT) { 11934 /* export -n NAME (without =VALUE) */ 11935 if (var) { 11936 var->flg_export = 0; 11937 debug_printf_env("%s: unsetenv '%s'\n", __func__, name); 11938 unsetenv(name); 11939 } /* else: export -n NOT_EXISTING_VAR: no-op */ 11940 continue; 11941 } 11942 if (flags & SETFLAG_EXPORT) { 11943 /* export NAME (without =VALUE) */ 11944 if (var) { 11945 var->flg_export = 1; 11946 debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr); 11947 putenv(var->varstr); 11948 continue; 11949 } 11950 } 11951 if (flags & SETFLAG_MAKE_RO) { 11952 /* readonly NAME (without =VALUE) */ 11953 if (var) { 11954 var->flg_read_only = 1; 11955 continue; 11956 } 11957 } 11958# if ENABLE_HUSH_LOCAL 11959 /* Is this "local" bltin? */ 11960 if (!(flags & (SETFLAG_EXPORT|SETFLAG_UNEXPORT|SETFLAG_MAKE_RO))) { 11961 unsigned lvl = flags >> SETFLAG_VARLVL_SHIFT; 11962 if (var && var->var_nest_level == lvl) { 11963 /* "local x=abc; ...; local x" - ignore second local decl */ 11964 continue; 11965 } 11966 } 11967# endif 11968 /* Exporting non-existing variable. 11969 * bash does not put it in environment, 11970 * but remembers that it is exported, 11971 * and does put it in env when it is set later. 11972 * We just set it to "" and export. 11973 */ 11974 /* Or, it's "local NAME" (without =VALUE). 11975 * bash sets the value to "". 11976 */ 11977 /* Or, it's "readonly NAME" (without =VALUE). 11978 * bash remembers NAME and disallows its creation 11979 * in the future. 11980 */ 11981 name = xasprintf("%s=", name); 11982 } else { 11983 if (*name_end != '=') { 11984 bb_error_msg("'%s': bad variable name", name); 11985 /* do not parse following argv[]s: */ 11986 return 1; 11987 } 11988 /* (Un)exporting/making local NAME=VALUE */ 11989 name = xstrdup(name); 11990 /* Testcase: export PS1='\w \$ ' */ 11991 unbackslash(name); 11992 } 11993 debug_printf_env("%s: set_local_var('%s')\n", __func__, name); 11994 if (set_local_var(name, flags)) 11995 return EXIT_FAILURE; 11996 } while (*++argv); 11997 return EXIT_SUCCESS; 11998} 11999#endif 12000 12001#if ENABLE_HUSH_EXPORT 12002static int FAST_FUNC builtin_export(char **argv) 12003{ 12004 unsigned opt_unexport; 12005 12006# if ENABLE_HUSH_EXPORT_N 12007 /* "!": do not abort on errors */ 12008 opt_unexport = getopt32(argv, "!n"); 12009 if (opt_unexport == (uint32_t)-1) 12010 return EXIT_FAILURE; 12011 argv += optind; 12012# else 12013 opt_unexport = 0; 12014 argv++; 12015# endif 12016 12017 if (argv[0] == NULL) { 12018 char **e = environ; 12019 if (e) { 12020 while (*e) { 12021# if 0 12022 puts(*e++); 12023# else 12024 /* ash emits: export VAR='VAL' 12025 * bash: declare -x VAR="VAL" 12026 * we follow ash example */ 12027 const char *s = *e++; 12028 const char *p = strchr(s, '='); 12029 12030 if (!p) /* wtf? take next variable */ 12031 continue; 12032 /* "export VAR=" */ 12033 printf("%s %.*s", "export", (int)(p - s) + 1, s); 12034 print_escaped(p + 1); 12035 putchar('\n'); 12036# endif 12037 } 12038 /*fflush_all(); - done after each builtin anyway */ 12039 } 12040 return EXIT_SUCCESS; 12041 } 12042 12043 return helper_export_local(argv, opt_unexport ? SETFLAG_UNEXPORT : SETFLAG_EXPORT); 12044} 12045#endif 12046 12047#if ENABLE_HUSH_LOCAL 12048static int FAST_FUNC builtin_local(char **argv) 12049{ 12050 if (G.func_nest_level == 0) { 12051 bb_error_msg("%s: not in a function", argv[0]); 12052 return EXIT_FAILURE; /* bash compat */ 12053 } 12054//TODO? ash and bash support "local -" special form, 12055//which saves/restores $- around function call (including async returns, such as ^C) 12056//(IOW: it makes "set +/-..." effects local) 12057 argv++; 12058 /* Since all builtins run in a nested variable level, 12059 * need to use level - 1 here. Or else the variable will be removed at once 12060 * after builtin returns. 12061 */ 12062 return helper_export_local(argv, (G.var_nest_level - 1) << SETFLAG_VARLVL_SHIFT); 12063} 12064#endif 12065 12066#if ENABLE_HUSH_READONLY 12067static int FAST_FUNC builtin_readonly(char **argv) 12068{ 12069 argv++; 12070 if (*argv == NULL) { 12071 /* bash: readonly [-p]: list all readonly VARs 12072 * (-p has no effect in bash) 12073 */ 12074 struct variable *e; 12075 for (e = G.top_var; e; e = e->next) { 12076 if (e->flg_read_only) { 12077 const char *s = e->varstr; 12078 const char *p = strchr(s, '='); 12079 12080 if (!p) /* wtf? take next variable */ 12081 continue; 12082 /* "readonly VAR=" */ 12083 printf("%s %.*s", "readonly", (int)(p - s) + 1, s); 12084 print_escaped(p + 1); 12085 putchar('\n'); 12086 } 12087 } 12088 return EXIT_SUCCESS; 12089 } 12090 return helper_export_local(argv, SETFLAG_MAKE_RO); 12091} 12092#endif 12093 12094#if ENABLE_HUSH_UNSET 12095/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */ 12096static int FAST_FUNC builtin_unset(char **argv) 12097{ 12098 int ret; 12099 unsigned opts; 12100 12101 /* "!": do not abort on errors */ 12102 /* "+": stop at 1st non-option */ 12103 opts = getopt32(argv, "!+vf"); 12104 if (opts == (unsigned)-1) 12105 return EXIT_FAILURE; 12106 if (opts == 3) { 12107 bb_simple_error_msg("unset: -v and -f are exclusive"); 12108 return EXIT_FAILURE; 12109 } 12110 argv += optind; 12111 12112 ret = EXIT_SUCCESS; 12113 while (*argv) { 12114 if (!(opts & 2)) { /* not -f */ 12115 if (unset_local_var(*argv)) { 12116 /* unset <nonexistent_var> doesn't fail. 12117 * Error is when one tries to unset RO var. 12118 * Message was printed by unset_local_var. */ 12119 ret = EXIT_FAILURE; 12120 } 12121 } 12122# if ENABLE_HUSH_FUNCTIONS 12123 else { 12124 unset_func(*argv); 12125 } 12126# endif 12127 argv++; 12128 } 12129 return ret; 12130} 12131#endif 12132 12133#if ENABLE_HUSH_SET 12134/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set 12135 * built-in 'set' handler 12136 * SUSv3 says: 12137 * set [-abCefhmnuvx] [-o option] [argument...] 12138 * set [+abCefhmnuvx] [+o option] [argument...] 12139 * set -- [argument...] 12140 * set -o 12141 * set +o 12142 * Implementations shall support the options in both their hyphen and 12143 * plus-sign forms. These options can also be specified as options to sh. 12144 * Examples: 12145 * Write out all variables and their values: set 12146 * Set $1, $2, and $3 and set "$#" to 3: set c a b 12147 * Turn on the -x and -v options: set -xv 12148 * Unset all positional parameters: set -- 12149 * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x" 12150 * Set the positional parameters to the expansion of x, even if x expands 12151 * with a leading '-' or '+': set -- $x 12152 * 12153 * So far, we only support "set -- [argument...]" and some of the short names. 12154 */ 12155static int FAST_FUNC builtin_set(char **argv) 12156{ 12157 int n; 12158 char **pp, **g_argv; 12159 char *arg = *++argv; 12160 12161 if (arg == NULL) { 12162 struct variable *e; 12163 for (e = G.top_var; e; e = e->next) { 12164 const char *s = e->varstr; 12165 const char *p = strchr(s, '='); 12166 12167 if (!p) /* wtf? take next variable */ 12168 continue; 12169 /* var= */ 12170 printf("%.*s", (int)(p - s) + 1, s); 12171 print_escaped(p + 1); 12172 putchar('\n'); 12173 } 12174 return EXIT_SUCCESS; 12175 } 12176 12177 do { 12178 if (strcmp(arg, "--") == 0) { 12179 ++argv; 12180 goto set_argv; 12181 } 12182 if (arg[0] != '+' && arg[0] != '-') 12183 break; 12184 for (n = 1; arg[n]; ++n) { 12185 if (set_mode((arg[0] == '-'), arg[n], argv[1])) { 12186 bb_error_msg("%s: %s: invalid option", "set", arg); 12187 return EXIT_FAILURE; 12188 } 12189 if (arg[n] == 'o' && argv[1]) 12190 argv++; 12191 } 12192 } while ((arg = *++argv) != NULL); 12193 /* Now argv[0] is 1st argument */ 12194 12195 if (arg == NULL) 12196 return EXIT_SUCCESS; 12197 set_argv: 12198 12199 /* NB: G.global_argv[0] ($0) is never freed/changed */ 12200 g_argv = G.global_argv; 12201 if (G.global_args_malloced) { 12202 pp = g_argv; 12203 while (*++pp) 12204 free(*pp); 12205 g_argv[1] = NULL; 12206 } else { 12207 G.global_args_malloced = 1; 12208 pp = xzalloc(sizeof(pp[0]) * 2); 12209 pp[0] = g_argv[0]; /* retain $0 */ 12210 g_argv = pp; 12211 } 12212 /* This realloc's G.global_argv */ 12213 G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1); 12214 12215 G.global_argc = 1 + string_array_len(pp + 1); 12216 12217 return EXIT_SUCCESS; 12218} 12219#endif 12220 12221static int FAST_FUNC builtin_shift(char **argv) 12222{ 12223 int n = 1; 12224 argv = skip_dash_dash(argv); 12225 if (argv[0]) { 12226 n = bb_strtou(argv[0], NULL, 10); 12227 if (errno || n < 0) { 12228 /* shared string with ash.c */ 12229 bb_error_msg("Illegal number: %s", argv[0]); 12230 /* 12231 * ash aborts in this case. 12232 * bash prints error message and set $? to 1. 12233 * Interestingly, for "shift 99999" bash does not 12234 * print error message, but does set $? to 1 12235 * (and does no shifting at all). 12236 */ 12237 } 12238 } 12239 if (n >= 0 && n < G.global_argc) { 12240 if (G_global_args_malloced) { 12241 int m = 1; 12242 while (m <= n) 12243 free(G.global_argv[m++]); 12244 } 12245 G.global_argc -= n; 12246 memmove(&G.global_argv[1], &G.global_argv[n+1], 12247 G.global_argc * sizeof(G.global_argv[0])); 12248 return EXIT_SUCCESS; 12249 } 12250 return EXIT_FAILURE; 12251} 12252 12253#if ENABLE_HUSH_GETOPTS 12254static int FAST_FUNC builtin_getopts(char **argv) 12255{ 12256/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html 12257 12258TODO: 12259If a required argument is not found, and getopts is not silent, 12260a question mark (?) is placed in VAR, OPTARG is unset, and a 12261diagnostic message is printed. If getopts is silent, then a 12262colon (:) is placed in VAR and OPTARG is set to the option 12263character found. 12264 12265Test that VAR is a valid variable name? 12266 12267"Whenever the shell is invoked, OPTIND shall be initialized to 1" 12268*/ 12269 char cbuf[2]; 12270 const char *cp, *optstring, *var; 12271 int c, n, exitcode, my_opterr; 12272 unsigned count; 12273 12274 optstring = *++argv; 12275 if (!optstring || !(var = *++argv)) { 12276 bb_simple_error_msg("usage: getopts OPTSTRING VAR [ARGS]"); 12277 return EXIT_FAILURE; 12278 } 12279 12280 if (argv[1]) 12281 argv[0] = G.global_argv[0]; /* for error messages in getopt() */ 12282 else 12283 argv = G.global_argv; 12284 cbuf[1] = '\0'; 12285 12286 my_opterr = 0; 12287 if (optstring[0] != ':') { 12288 cp = get_local_var_value("OPTERR"); 12289 /* 0 if "OPTERR=0", 1 otherwise */ 12290 my_opterr = (!cp || NOT_LONE_CHAR(cp, '0')); 12291 } 12292 12293 /* getopts stops on first non-option. Add "+" to force that */ 12294 /*if (optstring[0] != '+')*/ { 12295 char *s = alloca(strlen(optstring) + 2); 12296 sprintf(s, "+%s", optstring); 12297 optstring = s; 12298 } 12299 12300 /* Naively, now we should just 12301 * cp = get_local_var_value("OPTIND"); 12302 * optind = cp ? atoi(cp) : 0; 12303 * optarg = NULL; 12304 * opterr = my_opterr; 12305 * c = getopt(string_array_len(argv), argv, optstring); 12306 * and be done? Not so fast... 12307 * Unlike normal getopt() usage in C programs, here 12308 * each successive call will (usually) have the same argv[] CONTENTS, 12309 * but not the ADDRESSES. Worse yet, it's possible that between 12310 * invocations of "getopts", there will be calls to shell builtins 12311 * which use getopt() internally. Example: 12312 * while getopts "abc" RES -a -bc -abc de; do 12313 * unset -ff func 12314 * done 12315 * This would not work correctly: getopt() call inside "unset" 12316 * modifies internal libc state which is tracking position in 12317 * multi-option strings ("-abc"). At best, it can skip options 12318 * or return the same option infinitely. With glibc implementation 12319 * of getopt(), it would use outright invalid pointers and return 12320 * garbage even _without_ "unset" mangling internal state. 12321 * 12322 * We resort to resetting getopt() state and calling it N times, 12323 * until we get Nth result (or failure). 12324 * (N == G.getopt_count is reset to 0 whenever OPTIND is [un]set). 12325 */ 12326 GETOPT_RESET(); 12327 count = 0; 12328 n = string_array_len(argv); 12329 do { 12330 optarg = NULL; 12331 opterr = (count < G.getopt_count) ? 0 : my_opterr; 12332 c = getopt(n, argv, optstring); 12333 if (c < 0) 12334 break; 12335 count++; 12336 } while (count <= G.getopt_count); 12337 12338 /* Set OPTIND. Prevent resetting of the magic counter! */ 12339 set_local_var_from_halves("OPTIND", utoa(optind)); 12340 G.getopt_count = count; /* "next time, give me N+1'th result" */ 12341 GETOPT_RESET(); /* just in case */ 12342 12343 /* Set OPTARG */ 12344 /* Always set or unset, never left as-is, even on exit/error: 12345 * "If no option was found, or if the option that was found 12346 * does not have an option-argument, OPTARG shall be unset." 12347 */ 12348 cp = optarg; 12349 if (c == '?') { 12350 /* If ":optstring" and unknown option is seen, 12351 * it is stored to OPTARG. 12352 */ 12353 if (optstring[1] == ':') { 12354 cbuf[0] = optopt; 12355 cp = cbuf; 12356 } 12357 } 12358 if (cp) 12359 set_local_var_from_halves("OPTARG", cp); 12360 else 12361 unset_local_var("OPTARG"); 12362 12363 /* Convert -1 to "?" */ 12364 exitcode = EXIT_SUCCESS; 12365 if (c < 0) { /* -1: end of options */ 12366 exitcode = EXIT_FAILURE; 12367 c = '?'; 12368 } 12369 12370 /* Set VAR */ 12371 cbuf[0] = c; 12372 set_local_var_from_halves(var, cbuf); 12373 12374 return exitcode; 12375} 12376#endif 12377 12378static int FAST_FUNC builtin_source(char **argv) 12379{ 12380 char *arg_path, *filename; 12381 HFILE *input; 12382 save_arg_t sv; 12383 char *args_need_save; 12384#if ENABLE_HUSH_FUNCTIONS 12385 smallint sv_flg; 12386#endif 12387 12388 argv = skip_dash_dash(argv); 12389 filename = argv[0]; 12390 if (!filename) { 12391 /* bash says: "bash: .: filename argument required" */ 12392 return 2; /* bash compat */ 12393 } 12394 arg_path = NULL; 12395 if (!strchr(filename, '/')) { 12396 arg_path = find_in_path(filename); 12397 if (arg_path) 12398 filename = arg_path; 12399 else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) { 12400 errno = ENOENT; 12401 bb_simple_perror_msg(filename); 12402 return EXIT_FAILURE; 12403 } 12404 } 12405 input = hfopen(filename); 12406 free(arg_path); 12407 if (!input) { 12408 bb_perror_msg("%s", filename); 12409 /* POSIX: non-interactive shell should abort here, 12410 * not merely fail. So far no one complained :) 12411 */ 12412 return EXIT_FAILURE; 12413 } 12414 12415#if ENABLE_HUSH_FUNCTIONS 12416 sv_flg = G_flag_return_in_progress; 12417 /* "we are inside sourced file, ok to use return" */ 12418 G_flag_return_in_progress = -1; 12419#endif 12420 args_need_save = argv[1]; /* used as a boolean variable */ 12421 if (args_need_save) 12422 save_and_replace_G_args(&sv, argv); 12423 12424 /* "false; . ./empty_line; echo Zero:$?" should print 0 */ 12425 G.last_exitcode = 0; 12426 parse_and_run_file(input); 12427 hfclose(input); 12428 12429 if (args_need_save) /* can't use argv[1] instead: "shift" can mangle it */ 12430 restore_G_args(&sv, argv); 12431#if ENABLE_HUSH_FUNCTIONS 12432 G_flag_return_in_progress = sv_flg; 12433#endif 12434 12435 return G.last_exitcode; 12436} 12437 12438#if ENABLE_HUSH_TRAP 12439static int FAST_FUNC builtin_trap(char **argv) 12440{ 12441 int sig; 12442 char *new_cmd; 12443 12444 if (!G_traps) 12445 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG); 12446 12447 argv++; 12448 if (!*argv) { 12449 int i; 12450 /* No args: print all trapped */ 12451 for (i = 0; i < NSIG; ++i) { 12452 if (G_traps[i]) { 12453 printf("trap -- "); 12454 print_escaped(G_traps[i]); 12455 /* note: bash adds "SIG", but only if invoked 12456 * as "bash". If called as "sh", or if set -o posix, 12457 * then it prints short signal names. 12458 * We are printing short names: */ 12459 printf(" %s\n", get_signame(i)); 12460 } 12461 } 12462 /*fflush_all(); - done after each builtin anyway */ 12463 return EXIT_SUCCESS; 12464 } 12465 12466 new_cmd = NULL; 12467 /* If first arg is a number: reset all specified signals */ 12468 sig = bb_strtou(*argv, NULL, 10); 12469 if (errno == 0) { 12470 int ret; 12471 process_sig_list: 12472 ret = EXIT_SUCCESS; 12473 while (*argv) { 12474 sighandler_t handler; 12475 12476 sig = get_signum(*argv++); 12477 if (sig < 0) { 12478 ret = EXIT_FAILURE; 12479 /* Mimic bash message exactly */ 12480 bb_error_msg("trap: %s: invalid signal specification", argv[-1]); 12481 continue; 12482 } 12483 12484 free(G_traps[sig]); 12485 G_traps[sig] = xstrdup(new_cmd); 12486 12487 debug_printf("trap: setting SIG%s (%i) to '%s'\n", 12488 get_signame(sig), sig, G_traps[sig]); 12489 12490 /* There is no signal for 0 (EXIT) */ 12491 if (sig == 0) 12492 continue; 12493 12494 if (new_cmd) 12495 handler = (new_cmd[0] ? record_pending_signo : SIG_IGN); 12496 else 12497 /* We are removing trap handler */ 12498 handler = pick_sighandler(sig); 12499 install_sighandler(sig, handler); 12500 } 12501 return ret; 12502 } 12503 12504 if (!argv[1]) { /* no second arg */ 12505 bb_simple_error_msg("trap: invalid arguments"); 12506 return EXIT_FAILURE; 12507 } 12508 12509 /* First arg is "-": reset all specified to default */ 12510 /* First arg is "--": skip it, the rest is "handler SIGs..." */ 12511 /* Everything else: set arg as signal handler 12512 * (includes "" case, which ignores signal) */ 12513 if (argv[0][0] == '-') { 12514 if (argv[0][1] == '\0') { /* "-" */ 12515 /* new_cmd remains NULL: "reset these sigs" */ 12516 goto reset_traps; 12517 } 12518 if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */ 12519 argv++; 12520 } 12521 /* else: "-something", no special meaning */ 12522 } 12523 new_cmd = *argv; 12524 reset_traps: 12525 argv++; 12526 goto process_sig_list; 12527} 12528#endif 12529 12530#if ENABLE_HUSH_JOB 12531static struct pipe *parse_jobspec(const char *str) 12532{ 12533 struct pipe *pi; 12534 unsigned jobnum; 12535 12536 if (sscanf(str, "%%%u", &jobnum) != 1) { 12537 if (str[0] != '%' 12538 || (str[1] != '%' && str[1] != '+' && str[1] != '\0') 12539 ) { 12540 bb_error_msg("bad argument '%s'", str); 12541 return NULL; 12542 } 12543 /* It is "%%", "%+" or "%" - current job */ 12544 jobnum = G.last_jobid; 12545 if (jobnum == 0) { 12546 bb_simple_error_msg("no current job"); 12547 return NULL; 12548 } 12549 } 12550 for (pi = G.job_list; pi; pi = pi->next) { 12551 if (pi->jobid == jobnum) { 12552 return pi; 12553 } 12554 } 12555 bb_error_msg("%u: no such job", jobnum); 12556 return NULL; 12557} 12558 12559static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM) 12560{ 12561 struct pipe *job; 12562 const char *status_string; 12563 12564 checkjobs(NULL, 0 /*(no pid to wait for)*/); 12565 for (job = G.job_list; job; job = job->next) { 12566 if (job->alive_cmds == job->stopped_cmds) 12567 status_string = "Stopped"; 12568 else 12569 status_string = "Running"; 12570 12571 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext); 12572 } 12573 12574 clean_up_last_dead_job(); 12575 12576 return EXIT_SUCCESS; 12577} 12578 12579/* built-in 'fg' and 'bg' handler */ 12580static int FAST_FUNC builtin_fg_bg(char **argv) 12581{ 12582 int i; 12583 struct pipe *pi; 12584 12585 if (!G_interactive_fd) 12586 return EXIT_FAILURE; 12587 12588 /* If they gave us no args, assume they want the last backgrounded task */ 12589 if (!argv[1]) { 12590 for (pi = G.job_list; pi; pi = pi->next) { 12591 if (pi->jobid == G.last_jobid) { 12592 goto found; 12593 } 12594 } 12595 bb_error_msg("%s: no current job", argv[0]); 12596 return EXIT_FAILURE; 12597 } 12598 12599 pi = parse_jobspec(argv[1]); 12600 if (!pi) 12601 return EXIT_FAILURE; 12602 found: 12603 /* TODO: bash prints a string representation 12604 * of job being foregrounded (like "sleep 1 | cat") */ 12605 if (argv[0][0] == 'f' && G_saved_tty_pgrp) { 12606 /* Put the job into the foreground. */ 12607 tcsetpgrp(G_interactive_fd, pi->pgrp); 12608 } 12609 12610 /* Restart the processes in the job */ 12611 debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp); 12612 for (i = 0; i < pi->num_cmds; i++) { 12613 debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid); 12614 } 12615 pi->stopped_cmds = 0; 12616 12617 i = kill(- pi->pgrp, SIGCONT); 12618 if (i < 0) { 12619 if (errno == ESRCH) { 12620 delete_finished_job(pi); 12621 return EXIT_SUCCESS; 12622 } 12623 bb_simple_perror_msg("kill (SIGCONT)"); 12624 } 12625 12626 if (argv[0][0] == 'f') { 12627 remove_job_from_table(pi); /* FG job shouldn't be in job table */ 12628 return checkjobs_and_fg_shell(pi); 12629 } 12630 return EXIT_SUCCESS; 12631} 12632#endif 12633 12634#if ENABLE_HUSH_KILL 12635static int FAST_FUNC builtin_kill(char **argv) 12636{ 12637 int ret = 0; 12638 12639# if ENABLE_HUSH_JOB 12640 if (argv[1] && strcmp(argv[1], "-l") != 0) { 12641 int i = 1; 12642 12643 do { 12644 struct pipe *pi; 12645 char *dst; 12646 int j, n; 12647 12648 if (argv[i][0] != '%') 12649 continue; 12650 /* 12651 * "kill %N" - job kill 12652 * Converting to pgrp / pid kill 12653 */ 12654 pi = parse_jobspec(argv[i]); 12655 if (!pi) { 12656 /* Eat bad jobspec */ 12657 j = i; 12658 do { 12659 j++; 12660 argv[j - 1] = argv[j]; 12661 } while (argv[j]); 12662 ret = 1; 12663 i--; 12664 continue; 12665 } 12666 /* 12667 * In jobs started under job control, we signal 12668 * entire process group by kill -PGRP_ID. 12669 * This happens, f.e., in interactive shell. 12670 * 12671 * Otherwise, we signal each child via 12672 * kill PID1 PID2 PID3. 12673 * Testcases: 12674 * sh -c 'sleep 1|sleep 1 & kill %1' 12675 * sh -c 'true|sleep 2 & sleep 1; kill %1' 12676 * sh -c 'true|sleep 1 & sleep 2; kill %1' 12677 */ 12678 n = G_interactive_fd ? 1 : pi->num_cmds; 12679 dst = alloca(n * sizeof(int)*4); 12680 argv[i] = dst; 12681 if (G_interactive_fd) 12682 dst += sprintf(dst, " -%u", (int)pi->pgrp); 12683 else for (j = 0; j < n; j++) { 12684 struct command *cmd = &pi->cmds[j]; 12685 /* Skip exited members of the job */ 12686 if (cmd->pid == 0) 12687 continue; 12688 /* 12689 * kill_main has matching code to expect 12690 * leading space. Needed to not confuse 12691 * negative pids with "kill -SIGNAL_NO" syntax 12692 */ 12693 dst += sprintf(dst, " %u", (int)cmd->pid); 12694 } 12695 *dst = '\0'; 12696 } while (argv[++i]); 12697 } 12698# endif 12699 12700 if (argv[1] || ret == 0) { 12701 ret = run_applet_main(argv, kill_main); 12702 } 12703 /* else: ret = 1, "kill %bad_jobspec" case */ 12704 return ret; 12705} 12706#endif 12707 12708#if ENABLE_HUSH_WAIT 12709/* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */ 12710# if !ENABLE_HUSH_JOB 12711# define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid) 12712# endif 12713static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid) 12714{ 12715 int ret = 0; 12716 for (;;) { 12717 int sig; 12718 sigset_t oldset; 12719 12720 if (!sigisemptyset(&G.pending_set)) 12721 goto check_sig; 12722 12723 /* waitpid is not interruptible by SA_RESTARTed 12724 * signals which we use. Thus, this ugly dance: 12725 */ 12726 12727 /* Make sure possible SIGCHLD is stored in kernel's 12728 * pending signal mask before we call waitpid. 12729 * Or else we may race with SIGCHLD, lose it, 12730 * and get stuck in sigsuspend... 12731 */ 12732 sigfillset(&oldset); /* block all signals, remember old set */ 12733 sigprocmask2(SIG_SETMASK, &oldset); 12734 12735 if (!sigisemptyset(&G.pending_set)) { 12736 /* Crap! we raced with some signal! */ 12737 goto restore; 12738 } 12739 12740 /*errno = 0; - checkjobs does this */ 12741/* Can't pass waitfor_pipe into checkjobs(): it won't be interruptible */ 12742 ret = checkjobs(NULL, waitfor_pid); /* waitpid(WNOHANG) inside */ 12743 debug_printf_exec("checkjobs:%d\n", ret); 12744# if ENABLE_HUSH_JOB 12745 if (waitfor_pipe) { 12746 int rcode = job_exited_or_stopped(waitfor_pipe); 12747 debug_printf_exec("job_exited_or_stopped:%d\n", rcode); 12748 if (rcode >= 0) { 12749 ret = rcode; 12750 sigprocmask(SIG_SETMASK, &oldset, NULL); 12751 break; 12752 } 12753 } 12754# endif 12755 /* if ECHILD, there are no children (ret is -1 or 0) */ 12756 /* if ret == 0, no children changed state */ 12757 /* if ret != 0, it's exitcode+1 of exited waitfor_pid child */ 12758 if (errno == ECHILD || ret) { 12759 ret--; 12760 if (ret < 0) /* if ECHILD, may need to fix "ret" */ 12761 ret = 0; 12762# if ENABLE_HUSH_BASH_COMPAT 12763 if (waitfor_pid == -1 && errno == ECHILD) { 12764 /* exitcode of "wait -n" with no children is 127, not 0 */ 12765 ret = 127; 12766 } 12767# endif 12768 sigprocmask(SIG_SETMASK, &oldset, NULL); 12769 break; 12770 } 12771 /* Wait for SIGCHLD or any other signal */ 12772 /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */ 12773 /* Note: sigsuspend invokes signal handler */ 12774 sigsuspend(&oldset); 12775 /* ^^^ add "sigdelset(&oldset, SIGCHLD)" before sigsuspend 12776 * to make sure SIGCHLD is not masked off? 12777 * It was reported that this: 12778 * fn() { : | return; } 12779 * shopt -s lastpipe 12780 * fn 12781 * exec hush SCRIPT 12782 * under bash 4.4.23 runs SCRIPT with SIGCHLD masked, 12783 * making "wait" commands in SCRIPT block forever. 12784 */ 12785 restore: 12786 sigprocmask(SIG_SETMASK, &oldset, NULL); 12787 check_sig: 12788 /* So, did we get a signal? */ 12789 sig = check_and_run_traps(); 12790 if (sig /*&& sig != SIGCHLD - always true */) { 12791 /* Do this for any (non-ignored) signal, not only for ^C */ 12792 ret = 128 | sig; 12793 break; 12794 } 12795 /* SIGCHLD, or no signal, or ignored one, such as SIGQUIT. Repeat */ 12796 } 12797 return ret; 12798} 12799 12800static int FAST_FUNC builtin_wait(char **argv) 12801{ 12802 int ret; 12803 int status; 12804 12805 argv = skip_dash_dash(argv); 12806# if ENABLE_HUSH_BASH_COMPAT 12807 if (argv[0] && strcmp(argv[0], "-n") == 0) { 12808 /* wait -n */ 12809 /* (bash accepts "wait -n PID" too and ignores PID) */ 12810 G.dead_job_exitcode = -1; 12811 return wait_for_child_or_signal(NULL, -1 /*no job, wait for one job*/); 12812 } 12813# endif 12814 if (argv[0] == NULL) { 12815 /* Don't care about wait results */ 12816 /* Note 1: must wait until there are no more children */ 12817 /* Note 2: must be interruptible */ 12818 /* Examples: 12819 * $ sleep 3 & sleep 6 & wait 12820 * [1] 30934 sleep 3 12821 * [2] 30935 sleep 6 12822 * [1] Done sleep 3 12823 * [2] Done sleep 6 12824 * $ sleep 3 & sleep 6 & wait 12825 * [1] 30936 sleep 3 12826 * [2] 30937 sleep 6 12827 * [1] Done sleep 3 12828 * ^C <-- after ~4 sec from keyboard 12829 * $ 12830 */ 12831 return wait_for_child_or_signal(NULL, 0 /*no job and no pid to wait for*/); 12832 } 12833 12834 do { 12835 pid_t pid = bb_strtou(*argv, NULL, 10); 12836 if (errno || pid <= 0) { 12837# if ENABLE_HUSH_JOB 12838 if (argv[0][0] == '%') { 12839 struct pipe *wait_pipe; 12840 ret = 127; /* bash compat for bad jobspecs */ 12841 wait_pipe = parse_jobspec(*argv); 12842 if (wait_pipe) { 12843 ret = job_exited_or_stopped(wait_pipe); 12844 if (ret < 0) { 12845 ret = wait_for_child_or_signal(wait_pipe, 0); 12846 } else { 12847 /* waiting on "last dead job" removes it */ 12848 clean_up_last_dead_job(); 12849 } 12850 } 12851 /* else: parse_jobspec() already emitted error msg */ 12852 continue; 12853 } 12854# endif 12855 /* mimic bash message */ 12856 bb_error_msg("wait: '%s': not a pid or valid job spec", *argv); 12857 ret = EXIT_FAILURE; 12858 continue; /* bash checks all argv[] */ 12859 } 12860 12861 /* Do we have such child? */ 12862 ret = waitpid(pid, &status, WNOHANG); 12863 if (ret < 0) { 12864 /* No */ 12865 ret = 127; 12866 if (errno == ECHILD) { 12867 if (pid == G.last_bg_pid) { 12868 /* "wait $!" but last bg task has already exited. Try: 12869 * (sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $? 12870 * In bash it prints exitcode 0, then 3. 12871 * In dash, it is 127. 12872 */ 12873 ret = G.last_bg_pid_exitcode; 12874 } else { 12875 /* Example: "wait 1". mimic bash message */ 12876 bb_error_msg("wait: pid %u is not a child of this shell", (unsigned)pid); 12877 } 12878 } else { 12879 /* ??? */ 12880 bb_perror_msg("wait %s", *argv); 12881 } 12882 continue; /* bash checks all argv[] */ 12883 } 12884 if (ret == 0) { 12885 /* Yes, and it still runs */ 12886 ret = wait_for_child_or_signal(NULL, pid); 12887 } else { 12888 /* Yes, and it just exited */ 12889 process_wait_result(NULL, pid, status); 12890 ret = WEXITSTATUS(status); 12891 if (WIFSIGNALED(status)) 12892 ret = 128 | WTERMSIG(status); 12893 } 12894 } while (*++argv); 12895 12896 return ret; 12897} 12898#endif 12899 12900#if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS 12901static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min) 12902{ 12903 if (argv[1]) { 12904 def = bb_strtou(argv[1], NULL, 10); 12905 if (errno || def < def_min || argv[2]) { 12906 bb_error_msg("%s: bad arguments", argv[0]); 12907 def = UINT_MAX; 12908 } 12909 } 12910 return def; 12911} 12912#endif 12913 12914#if ENABLE_HUSH_LOOPS 12915static int FAST_FUNC builtin_break(char **argv) 12916{ 12917 unsigned depth; 12918 if (G.depth_of_loop == 0) { 12919 bb_error_msg("%s: only meaningful in a loop", argv[0]); 12920 /* if we came from builtin_continue(), need to undo "= 1" */ 12921 G.flag_break_continue = 0; 12922 return EXIT_SUCCESS; /* bash compat */ 12923 } 12924 G.flag_break_continue++; /* BC_BREAK = 1, or BC_CONTINUE = 2 */ 12925 12926 G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1); 12927 if (depth == UINT_MAX) 12928 G.flag_break_continue = BC_BREAK; 12929 if (G.depth_of_loop < depth) 12930 G.depth_break_continue = G.depth_of_loop; 12931 12932 return EXIT_SUCCESS; 12933} 12934 12935static int FAST_FUNC builtin_continue(char **argv) 12936{ 12937 G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */ 12938 return builtin_break(argv); 12939} 12940#endif 12941 12942#if ENABLE_HUSH_FUNCTIONS 12943static int FAST_FUNC builtin_return(char **argv) 12944{ 12945 int rc; 12946 12947 if (G_flag_return_in_progress != -1) { 12948 bb_error_msg("%s: not in a function or sourced script", argv[0]); 12949 return EXIT_FAILURE; /* bash compat */ 12950 } 12951 12952 G_flag_return_in_progress = 1; 12953 12954 /* bash: 12955 * out of range: wraps around at 256, does not error out 12956 * non-numeric param: 12957 * f() { false; return qwe; }; f; echo $? 12958 * bash: return: qwe: numeric argument required <== we do this 12959 * 255 <== we also do this 12960 */ 12961 rc = parse_numeric_argv1(argv, G.last_exitcode, 0); 12962# if ENABLE_HUSH_TRAP 12963 if (argv[1]) { /* "return ARG" inside a running trap sets $? */ 12964 debug_printf_exec("G.return_exitcode=%d\n", rc); 12965 G.return_exitcode = rc; 12966 } 12967# endif 12968 return rc; 12969} 12970#endif 12971 12972#if ENABLE_HUSH_TIMES 12973static int FAST_FUNC builtin_times(char **argv UNUSED_PARAM) 12974{ 12975 static const uint8_t times_tbl[] ALIGN1 = { 12976 ' ', offsetof(struct tms, tms_utime), 12977 '\n', offsetof(struct tms, tms_stime), 12978 ' ', offsetof(struct tms, tms_cutime), 12979 '\n', offsetof(struct tms, tms_cstime), 12980 0 12981 }; 12982 const uint8_t *p; 12983 unsigned clk_tck; 12984 struct tms buf; 12985 12986 clk_tck = bb_clk_tck(); 12987 12988 times(&buf); 12989 p = times_tbl; 12990 do { 12991 unsigned sec, frac; 12992 unsigned long t; 12993 t = *(clock_t *)(((char *) &buf) + p[1]); 12994 sec = t / clk_tck; 12995 frac = t % clk_tck; 12996 printf("%um%u.%03us%c", 12997 sec / 60, sec % 60, 12998 (frac * 1000) / clk_tck, 12999 p[0]); 13000 p += 2; 13001 } while (*p); 13002 13003 return EXIT_SUCCESS; 13004} 13005#endif 13006 13007#if ENABLE_HUSH_MEMLEAK 13008static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM) 13009{ 13010 void *p; 13011 unsigned long l; 13012 13013# ifdef M_TRIM_THRESHOLD 13014 /* Optional. Reduces probability of false positives */ 13015 malloc_trim(0); 13016# endif 13017 /* Crude attempt to find where "free memory" starts, 13018 * sans fragmentation. */ 13019 p = malloc(240); 13020 l = (unsigned long)p; 13021 free(p); 13022 p = malloc(3400); 13023 if (l < (unsigned long)p) l = (unsigned long)p; 13024 free(p); 13025 13026# if 0 /* debug */ 13027 { 13028 struct mallinfo mi = mallinfo(); 13029 printf("top alloc:0x%lx malloced:%d+%d=%d\n", l, 13030 mi.arena, mi.hblkhd, mi.arena + mi.hblkhd); 13031 } 13032# endif 13033 13034 if (!G.memleak_value) 13035 G.memleak_value = l; 13036 13037 l -= G.memleak_value; 13038 if ((long)l < 0) 13039 l = 0; 13040 l /= 1024; 13041 if (l > 127) 13042 l = 127; 13043 13044 /* Exitcode is "how many kilobytes we leaked since 1st call" */ 13045 return l; 13046} 13047#endif 13048#endif /* !__U_BOOT__ */