busybox/shell/hush.c
<<
>>
Prefs
   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 *      =~: regex operator
  67 *      let EXPR [EXPR...]
  68 *          Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION)
  69 *          If the last arg evaluates to 0, let returns 1; 0 otherwise.
  70 *          NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used)
  71 *      ((EXPR))
  72 *          The EXPR is evaluated according to ARITHMETIC EVALUATION.
  73 *          This is exactly equivalent to let "EXPR".
  74 *      $[EXPR]: synonym for $((EXPR))
  75 *      indirect expansion: ${!VAR}
  76 *      substring op on @: ${@:n:m}
  77 *
  78 * Won't do:
  79 *      Some builtins mandated by standards:
  80 *          newgrp [GRP]: not a builtin in bash but a suid binary
  81 *              which spawns a new shell with new group ID
  82 *
  83 * Status of [[ support:
  84 * [[ args ]] are CMD_SINGLEWORD_NOGLOB:
  85 *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
  86 *   [[ /bin/n* ]]; echo 0:$?
  87 * TODO:
  88 * &&/|| are AND/OR ops, -a/-o are not
  89 * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
  90 * = is glob match operator, not equality operator: STR = GLOB
  91 * (in GLOB, quoting is significant on char-by-char basis: a*cd"*")
  92 * == same as =
  93 * add =~ regex match operator: STR =~ REGEX
  94 */
  95//config:config HUSH
  96//config:       bool "hush (64 kb)"
  97//config:       default y
  98//config:       help
  99//config:       hush is a small shell. It handles the normal flow control
 100//config:       constructs such as if/then/elif/else/fi, for/in/do/done, while loops,
 101//config:       case/esac. Redirections, here documents, $((arithmetic))
 102//config:       and functions are supported.
 103//config:
 104//config:       It will compile and work on no-mmu systems.
 105//config:
 106//config:       It does not handle select, aliases, tilde expansion,
 107//config:       &>file and >&file redirection of stdout+stderr.
 108//config:
 109//config:config HUSH_BASH_COMPAT
 110//config:       bool "bash-compatible extensions"
 111//config:       default y
 112//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 113//config:
 114//config:config HUSH_BRACE_EXPANSION
 115//config:       bool "Brace expansion"
 116//config:       default y
 117//config:       depends on HUSH_BASH_COMPAT
 118//config:       help
 119//config:       Enable {abc,def} extension.
 120//config:
 121//config:config HUSH_LINENO_VAR
 122//config:       bool "$LINENO variable"
 123//config:       default y
 124//config:       depends on HUSH_BASH_COMPAT
 125//config:
 126//config:config HUSH_BASH_SOURCE_CURDIR
 127//config:       bool "'source' and '.' builtins search current directory after $PATH"
 128//config:       default n   # do not encourage non-standard behavior
 129//config:       depends on HUSH_BASH_COMPAT
 130//config:       help
 131//config:       This is not compliant with standards. Avoid if possible.
 132//config:
 133//config:config HUSH_INTERACTIVE
 134//config:       bool "Interactive mode"
 135//config:       default y
 136//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 137//config:       help
 138//config:       Enable interactive mode (prompt and command editing).
 139//config:       Without this, hush simply reads and executes commands
 140//config:       from stdin just like a shell script from a file.
 141//config:       No prompt, no PS1/PS2 magic shell variables.
 142//config:
 143//config:config HUSH_SAVEHISTORY
 144//config:       bool "Save command history to .hush_history"
 145//config:       default y
 146//config:       depends on HUSH_INTERACTIVE && FEATURE_EDITING_SAVEHISTORY
 147//config:
 148//config:config HUSH_JOB
 149//config:       bool "Job control"
 150//config:       default y
 151//config:       depends on HUSH_INTERACTIVE
 152//config:       help
 153//config:       Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current
 154//config:       command (not entire shell), fg/bg builtins work. Without this option,
 155//config:       "cmd &" still works by simply spawning a process and immediately
 156//config:       prompting for next command (or executing next command in a script),
 157//config:       but no separate process group is formed.
 158//config:
 159//config:config HUSH_TICK
 160//config:       bool "Support process substitution"
 161//config:       default y
 162//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 163//config:       help
 164//config:       Enable `command` and $(command).
 165//config:
 166//config:config HUSH_IF
 167//config:       bool "Support if/then/elif/else/fi"
 168//config:       default y
 169//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 170//config:
 171//config:config HUSH_LOOPS
 172//config:       bool "Support for, while and until loops"
 173//config:       default y
 174//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 175//config:
 176//config:config HUSH_CASE
 177//config:       bool "Support case ... esac statement"
 178//config:       default y
 179//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 180//config:       help
 181//config:       Enable case ... esac statement. +400 bytes.
 182//config:
 183//config:config HUSH_FUNCTIONS
 184//config:       bool "Support funcname() { commands; } syntax"
 185//config:       default y
 186//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 187//config:       help
 188//config:       Enable support for shell functions. +800 bytes.
 189//config:
 190//config:config HUSH_LOCAL
 191//config:       bool "local builtin"
 192//config:       default y
 193//config:       depends on HUSH_FUNCTIONS
 194//config:       help
 195//config:       Enable support for local variables in functions.
 196//config:
 197//config:config HUSH_RANDOM_SUPPORT
 198//config:       bool "Pseudorandom generator and $RANDOM variable"
 199//config:       default y
 200//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 201//config:       help
 202//config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
 203//config:       Each read of "$RANDOM" will generate a new pseudorandom value.
 204//config:
 205//config:config HUSH_MODE_X
 206//config:       bool "Support 'hush -x' option and 'set -x' command"
 207//config:       default y
 208//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 209//config:       help
 210//config:       This instructs hush to print commands before execution.
 211//config:       Adds ~300 bytes.
 212//config:
 213//config:config HUSH_ECHO
 214//config:       bool "echo builtin"
 215//config:       default y
 216//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 217//config:
 218//config:config HUSH_PRINTF
 219//config:       bool "printf builtin"
 220//config:       default y
 221//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 222//config:
 223//config:config HUSH_TEST
 224//config:       bool "test builtin"
 225//config:       default y
 226//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 227//config:
 228//config:config HUSH_HELP
 229//config:       bool "help builtin"
 230//config:       default y
 231//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 232//config:
 233//config:config HUSH_EXPORT
 234//config:       bool "export builtin"
 235//config:       default y
 236//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 237//config:
 238//config:config HUSH_EXPORT_N
 239//config:       bool "Support 'export -n' option"
 240//config:       default y
 241//config:       depends on HUSH_EXPORT
 242//config:       help
 243//config:       export -n unexports variables. It is a bash extension.
 244//config:
 245//config:config HUSH_READONLY
 246//config:       bool "readonly builtin"
 247//config:       default y
 248//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 249//config:       help
 250//config:       Enable support for read-only variables.
 251//config:
 252//config:config HUSH_KILL
 253//config:       bool "kill builtin (supports kill %jobspec)"
 254//config:       default y
 255//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 256//config:
 257//config:config HUSH_WAIT
 258//config:       bool "wait builtin"
 259//config:       default y
 260//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 261//config:
 262//config:config HUSH_COMMAND
 263//config:       bool "command builtin"
 264//config:       default y
 265//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 266//config:
 267//config:config HUSH_TRAP
 268//config:       bool "trap builtin"
 269//config:       default y
 270//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 271//config:
 272//config:config HUSH_TYPE
 273//config:       bool "type builtin"
 274//config:       default y
 275//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 276//config:
 277//config:config HUSH_TIMES
 278//config:       bool "times builtin"
 279//config:       default y
 280//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 281//config:
 282//config:config HUSH_READ
 283//config:       bool "read builtin"
 284//config:       default y
 285//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 286//config:
 287//config:config HUSH_SET
 288//config:       bool "set builtin"
 289//config:       default y
 290//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 291//config:
 292//config:config HUSH_UNSET
 293//config:       bool "unset builtin"
 294//config:       default y
 295//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 296//config:
 297//config:config HUSH_ULIMIT
 298//config:       bool "ulimit builtin"
 299//config:       default y
 300//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 301//config:
 302//config:config HUSH_UMASK
 303//config:       bool "umask builtin"
 304//config:       default y
 305//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 306//config:
 307//config:config HUSH_GETOPTS
 308//config:       bool "getopts builtin"
 309//config:       default y
 310//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 311//config:
 312//config:config HUSH_MEMLEAK
 313//config:       bool "memleak builtin (debugging)"
 314//config:       default n
 315//config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
 316
 317//applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP))
 318//                       APPLET_ODDNAME:name  main  location    suid_type     help
 319//applet:IF_SH_IS_HUSH(  APPLET_ODDNAME(sh,   hush, BB_DIR_BIN, BB_SUID_DROP, hush))
 320//applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush))
 321
 322//kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o
 323//kbuild:lib-$(CONFIG_SH_IS_HUSH) += hush.o match.o shell_common.o
 324//kbuild:lib-$(CONFIG_BASH_IS_HUSH) += hush.o match.o shell_common.o
 325//kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o
 326
 327/* -i (interactive) is also accepted,
 328 * but does nothing, therefore not shown in help.
 329 * NOMMU-specific options are not meant to be used by users,
 330 * therefore we don't show them either.
 331 */
 332//usage:#define hush_trivial_usage
 333//usage:        "[-enxl] [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
 334//usage:#define hush_full_usage "\n\n"
 335//usage:        "Unix shell interpreter"
 336
 337#if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
 338        || defined(__APPLE__) \
 339    )
 340# include <malloc.h>   /* for malloc_trim */
 341#endif
 342#include <glob.h>
 343/* #include <dmalloc.h> */
 344#if ENABLE_HUSH_CASE
 345# include <fnmatch.h>
 346#endif
 347#include <sys/times.h>
 348#include <sys/utsname.h> /* for setting $HOSTNAME */
 349
 350#include "busybox.h"  /* for APPLET_IS_NOFORK/NOEXEC */
 351#include "unicode.h"
 352#include "shell_common.h"
 353#include "math.h"
 354#include "match.h"
 355#if ENABLE_HUSH_RANDOM_SUPPORT
 356# include "random.h"
 357#else
 358# define CLEAR_RANDOM_T(rnd) ((void)0)
 359#endif
 360#ifndef F_DUPFD_CLOEXEC
 361# define F_DUPFD_CLOEXEC F_DUPFD
 362#endif
 363#ifndef PIPE_BUF
 364# define PIPE_BUF 4096  /* amount of buffering in a pipe */
 365#endif
 366
 367
 368/* So far, all bash compat is controlled by one config option */
 369/* Separate defines document which part of code implements what */
 370#define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT
 371#define BASH_SUBSTR        ENABLE_HUSH_BASH_COMPAT
 372#define BASH_SOURCE        ENABLE_HUSH_BASH_COMPAT
 373#define BASH_HOSTNAME_VAR  ENABLE_HUSH_BASH_COMPAT
 374#define BASH_TEST2         (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
 375#define BASH_READ_D        ENABLE_HUSH_BASH_COMPAT
 376
 377
 378/* Build knobs */
 379#define LEAK_HUNTING 0
 380#define BUILD_AS_NOMMU 0
 381/* Enable/disable sanity checks. Ok to enable in production,
 382 * only adds a bit of bloat. Set to >1 to get non-production level verbosity.
 383 * Keeping 1 for now even in released versions.
 384 */
 385#define HUSH_DEBUG 1
 386/* Slightly bigger (+200 bytes), but faster hush.
 387 * So far it only enables a trick with counting SIGCHLDs and forks,
 388 * which allows us to do fewer waitpid's.
 389 * (we can detect a case where neither forks were done nor SIGCHLDs happened
 390 * and therefore waitpid will return the same result as last time)
 391 */
 392#define ENABLE_HUSH_FAST 0
 393/* TODO: implement simplified code for users which do not need ${var%...} ops
 394 * So far ${var%...} ops are always enabled:
 395 */
 396#define ENABLE_HUSH_DOLLAR_OPS 1
 397
 398
 399#if BUILD_AS_NOMMU
 400# undef BB_MMU
 401# undef USE_FOR_NOMMU
 402# undef USE_FOR_MMU
 403# define BB_MMU 0
 404# define USE_FOR_NOMMU(...) __VA_ARGS__
 405# define USE_FOR_MMU(...)
 406#endif
 407
 408#include "NUM_APPLETS.h"
 409#if NUM_APPLETS == 1
 410/* STANDALONE does not make sense, and won't compile */
 411# undef CONFIG_FEATURE_SH_STANDALONE
 412# undef ENABLE_FEATURE_SH_STANDALONE
 413# undef IF_FEATURE_SH_STANDALONE
 414# undef IF_NOT_FEATURE_SH_STANDALONE
 415# define ENABLE_FEATURE_SH_STANDALONE 0
 416# define IF_FEATURE_SH_STANDALONE(...)
 417# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
 418#endif
 419
 420#if !ENABLE_HUSH_INTERACTIVE
 421# undef ENABLE_FEATURE_EDITING
 422# define ENABLE_FEATURE_EDITING 0
 423# undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
 424# define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
 425# undef ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
 426# define ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 0
 427#endif
 428
 429/* Do we support ANY keywords? */
 430#if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
 431# define HAS_KEYWORDS 1
 432# define IF_HAS_KEYWORDS(...) __VA_ARGS__
 433# define IF_HAS_NO_KEYWORDS(...)
 434#else
 435# define HAS_KEYWORDS 0
 436# define IF_HAS_KEYWORDS(...)
 437# define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
 438#endif
 439
 440/* If you comment out one of these below, it will be #defined later
 441 * to perform debug printfs to stderr: */
 442#define debug_printf(...)        do {} while (0)
 443/* Finer-grained debug switches */
 444#define debug_printf_parse(...)  do {} while (0)
 445#define debug_print_tree(a, b)   do {} while (0)
 446#define debug_printf_exec(...)   do {} while (0)
 447#define debug_printf_env(...)    do {} while (0)
 448#define debug_printf_jobs(...)   do {} while (0)
 449#define debug_printf_expand(...) do {} while (0)
 450#define debug_printf_varexp(...) do {} while (0)
 451#define debug_printf_glob(...)   do {} while (0)
 452#define debug_printf_redir(...)  do {} while (0)
 453#define debug_printf_list(...)   do {} while (0)
 454#define debug_printf_subst(...)  do {} while (0)
 455#define debug_printf_prompt(...) do {} while (0)
 456#define debug_printf_clean(...)  do {} while (0)
 457
 458#define ERR_PTR ((void*)(long)1)
 459
 460#define JOB_STATUS_FORMAT    "[%u] %-22s %.40s\n"
 461
 462#define _SPECIAL_VARS_STR     "_*@$!?#"
 463#define SPECIAL_VARS_STR     ("_*@$!?#" + 1)
 464#define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3)
 465#if BASH_PATTERN_SUBST
 466/* Support / and // replace ops */
 467/* Note that // is stored as \ in "encoded" string representation */
 468# define VAR_ENCODED_SUBST_OPS      "\\/%#:-=+?"
 469# define VAR_SUBST_OPS             ("\\/%#:-=+?" + 1)
 470# define MINUS_PLUS_EQUAL_QUESTION ("\\/%#:-=+?" + 5)
 471#else
 472# define VAR_ENCODED_SUBST_OPS      "%#:-=+?"
 473# define VAR_SUBST_OPS              "%#:-=+?"
 474# define MINUS_PLUS_EQUAL_QUESTION ("%#:-=+?" + 3)
 475#endif
 476
 477#define SPECIAL_VAR_SYMBOL_STR "\3"
 478#define SPECIAL_VAR_SYMBOL       3
 479/* The "variable" with name "\1" emits string "\3". Testcase: "echo ^C" */
 480#define SPECIAL_VAR_QUOTED_SVS   1
 481
 482struct variable;
 483
 484static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER;
 485
 486/* This supports saving pointers malloced in vfork child,
 487 * to be freed in the parent.
 488 */
 489#if !BB_MMU
 490typedef struct nommu_save_t {
 491        struct variable *old_vars;
 492        char **argv;
 493        char **argv_from_re_execing;
 494} nommu_save_t;
 495#endif
 496
 497enum {
 498        RES_NONE  = 0,
 499#if ENABLE_HUSH_IF
 500        RES_IF    ,
 501        RES_THEN  ,
 502        RES_ELIF  ,
 503        RES_ELSE  ,
 504        RES_FI    ,
 505#endif
 506#if ENABLE_HUSH_LOOPS
 507        RES_FOR   ,
 508        RES_WHILE ,
 509        RES_UNTIL ,
 510        RES_DO    ,
 511        RES_DONE  ,
 512#endif
 513#if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
 514        RES_IN    ,
 515#endif
 516#if ENABLE_HUSH_CASE
 517        RES_CASE  ,
 518        /* three pseudo-keywords support contrived "case" syntax: */
 519        RES_CASE_IN,   /* "case ... IN", turns into RES_MATCH when IN is observed */
 520        RES_MATCH ,    /* "word)" */
 521        RES_CASE_BODY, /* "this command is inside CASE" */
 522        RES_ESAC  ,
 523#endif
 524        RES_XXXX  ,
 525        RES_SNTX
 526};
 527
 528typedef struct o_string {
 529        char *data;
 530        int length; /* position where data is appended */
 531        int maxlen;
 532        int o_expflags;
 533        /* At least some part of the string was inside '' or "",
 534         * possibly empty one: word"", wo''rd etc. */
 535        smallint has_quoted_part;
 536        smallint has_empty_slot;
 537} o_string;
 538enum {
 539        EXP_FLAG_SINGLEWORD     = 0x80, /* must be 0x80 */
 540        EXP_FLAG_GLOB           = 0x2,
 541        /* Protect newly added chars against globbing
 542         * by prepending \ to *, ?, [, \ */
 543        EXP_FLAG_ESC_GLOB_CHARS = 0x1,
 544};
 545/* Used for initialization: o_string foo = NULL_O_STRING; */
 546#define NULL_O_STRING { NULL }
 547
 548#ifndef debug_printf_parse
 549static const char *const assignment_flag[] = {
 550        "MAYBE_ASSIGNMENT",
 551        "DEFINITELY_ASSIGNMENT",
 552        "NOT_ASSIGNMENT",
 553        "WORD_IS_KEYWORD",
 554};
 555#endif
 556
 557typedef struct in_str {
 558        const char *p;
 559        int peek_buf[2];
 560        int last_char;
 561        FILE *file;
 562} in_str;
 563
 564/* The descrip member of this structure is only used to make
 565 * debugging output pretty */
 566static const struct {
 567        int mode;
 568        signed char default_fd;
 569        char descrip[3];
 570} redir_table[] = {
 571        { O_RDONLY,                  0, "<"  },
 572        { O_CREAT|O_TRUNC|O_WRONLY,  1, ">"  },
 573        { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
 574        { O_CREAT|O_RDWR,            1, "<>" },
 575        { O_RDONLY,                  0, "<<" },
 576/* Should not be needed. Bogus default_fd helps in debugging */
 577/*      { O_RDONLY,                 77, "<<" }, */
 578};
 579
 580struct redir_struct {
 581        struct redir_struct *next;
 582        char *rd_filename;          /* filename */
 583        int rd_fd;                  /* fd to redirect */
 584        /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */
 585        int rd_dup;
 586        smallint rd_type;           /* (enum redir_type) */
 587        /* note: for heredocs, rd_filename contains heredoc delimiter,
 588         * and subsequently heredoc itself; and rd_dup is a bitmask:
 589         * bit 0: do we need to trim leading tabs?
 590         * bit 1: is heredoc quoted (<<'delim' syntax) ?
 591         */
 592};
 593typedef enum redir_type {
 594        REDIRECT_INPUT     = 0,
 595        REDIRECT_OVERWRITE = 1,
 596        REDIRECT_APPEND    = 2,
 597        REDIRECT_IO        = 3,
 598        REDIRECT_HEREDOC   = 4,
 599        REDIRECT_HEREDOC2  = 5, /* REDIRECT_HEREDOC after heredoc is loaded */
 600
 601        REDIRFD_CLOSE      = -3,
 602        REDIRFD_SYNTAX_ERR = -2,
 603        REDIRFD_TO_FILE    = -1,
 604        /* otherwise, rd_fd is redirected to rd_dup */
 605
 606        HEREDOC_SKIPTABS = 1,
 607        HEREDOC_QUOTED   = 2,
 608} redir_type;
 609
 610
 611struct command {
 612        pid_t pid;                  /* 0 if exited */
 613        unsigned assignment_cnt;    /* how many argv[i] are assignments? */
 614#if ENABLE_HUSH_LINENO_VAR
 615        unsigned lineno;
 616#endif
 617        smallint cmd_type;          /* CMD_xxx */
 618#define CMD_NORMAL   0
 619#define CMD_SUBSHELL 1
 620#if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
 621/* used for "[[ EXPR ]]", and to prevent word splitting and globbing in
 622 * "export v=t*"
 623 */
 624# define CMD_SINGLEWORD_NOGLOB 2
 625#endif
 626#if ENABLE_HUSH_FUNCTIONS
 627# define CMD_FUNCDEF 3
 628#endif
 629
 630        smalluint cmd_exitcode;
 631        /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
 632        struct pipe *group;
 633#if !BB_MMU
 634        char *group_as_string;
 635#endif
 636#if ENABLE_HUSH_FUNCTIONS
 637        struct function *child_func;
 638/* This field is used to prevent a bug here:
 639 * while...do f1() {a;}; f1; f1() {b;}; f1; done
 640 * When we execute "f1() {a;}" cmd, we create new function and clear
 641 * cmd->group, cmd->group_as_string, cmd->argv[0].
 642 * When we execute "f1() {b;}", we notice that f1 exists,
 643 * and that its "parent cmd" struct is still "alive",
 644 * we put those fields back into cmd->xxx
 645 * (struct function has ->parent_cmd ptr to facilitate that).
 646 * When we loop back, we can execute "f1() {a;}" again and set f1 correctly.
 647 * Without this trick, loop would execute a;b;b;b;...
 648 * instead of correct sequence a;b;a;b;...
 649 * When command is freed, it severs the link
 650 * (sets ->child_func->parent_cmd to NULL).
 651 */
 652#endif
 653        char **argv;                /* command name and arguments */
 654/* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
 655 * and on execution these are substituted with their values.
 656 * Substitution can make _several_ words out of one argv[n]!
 657 * Example: argv[0]=='.^C*^C.' here: echo .$*.
 658 * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
 659 */
 660        struct redir_struct *redirects; /* I/O redirections */
 661};
 662/* Is there anything in this command at all? */
 663#define IS_NULL_CMD(cmd) \
 664        (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects)
 665
 666struct pipe {
 667        struct pipe *next;
 668        int num_cmds;               /* total number of commands in pipe */
 669        int alive_cmds;             /* number of commands running (not exited) */
 670        int stopped_cmds;           /* number of commands alive, but stopped */
 671#if ENABLE_HUSH_JOB
 672        unsigned jobid;             /* job number */
 673        pid_t pgrp;                 /* process group ID for the job */
 674        char *cmdtext;              /* name of job */
 675#endif
 676        struct command *cmds;       /* array of commands in pipe */
 677        smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
 678        IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
 679        IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
 680};
 681typedef enum pipe_style {
 682        PIPE_SEQ = 0,
 683        PIPE_AND = 1,
 684        PIPE_OR  = 2,
 685        PIPE_BG  = 3,
 686} pipe_style;
 687/* Is there anything in this pipe at all? */
 688#define IS_NULL_PIPE(pi) \
 689        ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE))
 690
 691/* This holds pointers to the various results of parsing */
 692struct parse_context {
 693        /* linked list of pipes */
 694        struct pipe *list_head;
 695        /* last pipe (being constructed right now) */
 696        struct pipe *pipe;
 697        /* last command in pipe (being constructed right now) */
 698        struct command *command;
 699        /* last redirect in command->redirects list */
 700        struct redir_struct *pending_redirect;
 701        o_string word;
 702#if !BB_MMU
 703        o_string as_string;
 704#endif
 705        smallint is_assignment; /* 0:maybe, 1:yes, 2:no, 3:keyword */
 706#if HAS_KEYWORDS
 707        smallint ctx_res_w;
 708        smallint ctx_inverted; /* "! cmd | cmd" */
 709#if ENABLE_HUSH_CASE
 710        smallint ctx_dsemicolon; /* ";;" seen */
 711#endif
 712        /* bitmask of FLAG_xxx, for figuring out valid reserved words */
 713        int old_flag;
 714        /* group we are enclosed in:
 715         * example: "if pipe1; pipe2; then pipe3; fi"
 716         * when we see "if" or "then", we malloc and copy current context,
 717         * and make ->stack point to it. then we parse pipeN.
 718         * when closing "then" / fi" / whatever is found,
 719         * we move list_head into ->stack->command->group,
 720         * copy ->stack into current context, and delete ->stack.
 721         * (parsing of { list } and ( list ) doesn't use this method)
 722         */
 723        struct parse_context *stack;
 724#endif
 725};
 726enum {
 727        MAYBE_ASSIGNMENT      = 0,
 728        DEFINITELY_ASSIGNMENT = 1,
 729        NOT_ASSIGNMENT        = 2,
 730        /* Not an assignment, but next word may be: "if v=xyz cmd;" */
 731        WORD_IS_KEYWORD       = 3,
 732};
 733
 734/* On program start, environ points to initial environment.
 735 * putenv adds new pointers into it, unsetenv removes them.
 736 * Neither of these (de)allocates the strings.
 737 * setenv allocates new strings in malloc space and does putenv,
 738 * and thus setenv is unusable (leaky) for shell's purposes */
 739#define setenv(...) setenv_is_leaky_dont_use()
 740struct variable {
 741        struct variable *next;
 742        char *varstr;        /* points to "name=" portion */
 743        int max_len;         /* if > 0, name is part of initial env; else name is malloced */
 744        uint16_t var_nest_level;
 745        smallint flg_export; /* putenv should be done on this var */
 746        smallint flg_read_only;
 747};
 748
 749enum {
 750        BC_BREAK = 1,
 751        BC_CONTINUE = 2,
 752};
 753
 754#if ENABLE_HUSH_FUNCTIONS
 755struct function {
 756        struct function *next;
 757        char *name;
 758        struct command *parent_cmd;
 759        struct pipe *body;
 760# if !BB_MMU
 761        char *body_as_string;
 762# endif
 763};
 764#endif
 765
 766
 767/* set -/+o OPT support. (TODO: make it optional)
 768 * bash supports the following opts:
 769 * allexport       off
 770 * braceexpand     on
 771 * emacs           on
 772 * errexit         off
 773 * errtrace        off
 774 * functrace       off
 775 * hashall         on
 776 * histexpand      off
 777 * history         on
 778 * ignoreeof       off
 779 * interactive-comments    on
 780 * keyword         off
 781 * monitor         on
 782 * noclobber       off
 783 * noexec          off
 784 * noglob          off
 785 * nolog           off
 786 * notify          off
 787 * nounset         off
 788 * onecmd          off
 789 * physical        off
 790 * pipefail        off
 791 * posix           off
 792 * privileged      off
 793 * verbose         off
 794 * vi              off
 795 * xtrace          off
 796 */
 797static const char o_opt_strings[] ALIGN1 =
 798        "pipefail\0"
 799        "noexec\0"
 800        "errexit\0"
 801#if ENABLE_HUSH_MODE_X
 802        "xtrace\0"
 803#endif
 804        ;
 805enum {
 806        OPT_O_PIPEFAIL,
 807        OPT_O_NOEXEC,
 808        OPT_O_ERREXIT,
 809#if ENABLE_HUSH_MODE_X
 810        OPT_O_XTRACE,
 811#endif
 812        NUM_OPT_O
 813};
 814
 815
 816struct FILE_list {
 817        struct FILE_list *next;
 818        FILE *fp;
 819        int fd;
 820};
 821
 822
 823/* "Globals" within this file */
 824/* Sorted roughly by size (smaller offsets == smaller code) */
 825struct globals {
 826        /* interactive_fd != 0 means we are an interactive shell.
 827         * If we are, then saved_tty_pgrp can also be != 0, meaning
 828         * that controlling tty is available. With saved_tty_pgrp == 0,
 829         * job control still works, but terminal signals
 830         * (^C, ^Z, ^Y, ^\) won't work at all, and background
 831         * process groups can only be created with "cmd &".
 832         * With saved_tty_pgrp != 0, hush will use tcsetpgrp()
 833         * to give tty to the foreground process group,
 834         * and will take it back when the group is stopped (^Z)
 835         * or killed (^C).
 836         */
 837#if ENABLE_HUSH_INTERACTIVE
 838        /* 'interactive_fd' is a fd# open to ctty, if we have one
 839         * _AND_ if we decided to act interactively */
 840        int interactive_fd;
 841        const char *PS1;
 842        IF_FEATURE_EDITING_FANCY_PROMPT(const char *PS2;)
 843# define G_interactive_fd (G.interactive_fd)
 844#else
 845# define G_interactive_fd 0
 846#endif
 847#if ENABLE_FEATURE_EDITING
 848        line_input_t *line_input_state;
 849#endif
 850        pid_t root_pid;
 851        pid_t root_ppid;
 852        pid_t last_bg_pid;
 853#if ENABLE_HUSH_RANDOM_SUPPORT
 854        random_t random_gen;
 855#endif
 856#if ENABLE_HUSH_JOB
 857        int run_list_level;
 858        unsigned last_jobid;
 859        pid_t saved_tty_pgrp;
 860        struct pipe *job_list;
 861# define G_saved_tty_pgrp (G.saved_tty_pgrp)
 862#else
 863# define G_saved_tty_pgrp 0
 864#endif
 865        /* How deeply are we in context where "set -e" is ignored */
 866        int errexit_depth;
 867        /* "set -e" rules (do we follow them correctly?):
 868         * Exit if pipe, list, or compound command exits with a non-zero status.
 869         * Shell does not exit if failed command is part of condition in
 870         * if/while, part of && or || list except the last command, any command
 871         * in a pipe but the last, or if the command's return value is being
 872         * inverted with !. If a compound command other than a subshell returns a
 873         * non-zero status because a command failed while -e was being ignored, the
 874         * shell does not exit. A trap on ERR, if set, is executed before the shell
 875         * exits [ERR is a bashism].
 876         *
 877         * If a compound command or function executes in a context where -e is
 878         * ignored, none of the commands executed within are affected by the -e
 879         * setting. If a compound command or function sets -e while executing in a
 880         * context where -e is ignored, that setting does not have any effect until
 881         * the compound command or the command containing the function call completes.
 882         */
 883
 884        char o_opt[NUM_OPT_O];
 885#if ENABLE_HUSH_MODE_X
 886# define G_x_mode (G.o_opt[OPT_O_XTRACE])
 887#else
 888# define G_x_mode 0
 889#endif
 890#if ENABLE_HUSH_INTERACTIVE
 891        smallint promptmode; /* 0: PS1, 1: PS2 */
 892#endif
 893        smallint flag_SIGINT;
 894#if ENABLE_HUSH_LOOPS
 895        smallint flag_break_continue;
 896#endif
 897#if ENABLE_HUSH_FUNCTIONS
 898        /* 0: outside of a function (or sourced file)
 899         * -1: inside of a function, ok to use return builtin
 900         * 1: return is invoked, skip all till end of func
 901         */
 902        smallint flag_return_in_progress;
 903# define G_flag_return_in_progress (G.flag_return_in_progress)
 904#else
 905# define G_flag_return_in_progress 0
 906#endif
 907        smallint exiting; /* used to prevent EXIT trap recursion */
 908        /* These support $?, $#, and $1 */
 909        smalluint last_exitcode;
 910        smalluint expand_exitcode;
 911        smalluint last_bg_pid_exitcode;
 912#if ENABLE_HUSH_SET
 913        /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */
 914        smalluint global_args_malloced;
 915# define G_global_args_malloced (G.global_args_malloced)
 916#else
 917# define G_global_args_malloced 0
 918#endif
 919        /* how many non-NULL argv's we have. NB: $# + 1 */
 920        int global_argc;
 921        char **global_argv;
 922#if !BB_MMU
 923        char *argv0_for_re_execing;
 924#endif
 925#if ENABLE_HUSH_LOOPS
 926        unsigned depth_break_continue;
 927        unsigned depth_of_loop;
 928#endif
 929#if ENABLE_HUSH_GETOPTS
 930        unsigned getopt_count;
 931#endif
 932        const char *ifs;
 933        char *ifs_whitespace; /* = G.ifs or malloced */
 934        const char *cwd;
 935        struct variable *top_var;
 936        char **expanded_assignments;
 937        struct variable **shadowed_vars_pp;
 938        unsigned var_nest_level;
 939#if ENABLE_HUSH_FUNCTIONS
 940# if ENABLE_HUSH_LOCAL
 941        unsigned func_nest_level; /* solely to prevent "local v" in non-functions */
 942# endif
 943        struct function *top_func;
 944#endif
 945        /* Signal and trap handling */
 946#if ENABLE_HUSH_FAST
 947        unsigned count_SIGCHLD;
 948        unsigned handled_SIGCHLD;
 949        smallint we_have_children;
 950#endif
 951#if ENABLE_HUSH_LINENO_VAR
 952        unsigned lineno;
 953        char *lineno_var;
 954#endif
 955        struct FILE_list *FILE_list;
 956        /* Which signals have non-DFL handler (even with no traps set)?
 957         * Set at the start to:
 958         * (SIGQUIT + maybe SPECIAL_INTERACTIVE_SIGS + maybe SPECIAL_JOBSTOP_SIGS)
 959         * SPECIAL_INTERACTIVE_SIGS are cleared after fork.
 960         * The rest is cleared right before execv syscalls.
 961         * Other than these two times, never modified.
 962         */
 963        unsigned special_sig_mask;
 964#if ENABLE_HUSH_JOB
 965        unsigned fatal_sig_mask;
 966# define G_fatal_sig_mask (G.fatal_sig_mask)
 967#else
 968# define G_fatal_sig_mask 0
 969#endif
 970#if ENABLE_HUSH_TRAP
 971        char **traps; /* char *traps[NSIG] */
 972# define G_traps G.traps
 973#else
 974# define G_traps ((char**)NULL)
 975#endif
 976        sigset_t pending_set;
 977#if ENABLE_HUSH_MEMLEAK
 978        unsigned long memleak_value;
 979#endif
 980#if HUSH_DEBUG
 981        int debug_indent;
 982#endif
 983        struct sigaction sa;
 984#if ENABLE_FEATURE_EDITING
 985        char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
 986#endif
 987};
 988#define G (*ptr_to_globals)
 989/* Not #defining name to G.name - this quickly gets unwieldy
 990 * (too many defines). Also, I actually prefer to see when a variable
 991 * is global, thus "G." prefix is a useful hint */
 992#define INIT_G() do { \
 993        SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
 994        /* memset(&G.sa, 0, sizeof(G.sa)); */  \
 995        sigfillset(&G.sa.sa_mask); \
 996        G.sa.sa_flags = SA_RESTART; \
 997} while (0)
 998
 999
1000/* Function prototypes for builtins */
1001static int builtin_cd(char **argv) FAST_FUNC;
1002#if ENABLE_HUSH_ECHO
1003static int builtin_echo(char **argv) FAST_FUNC;
1004#endif
1005static int builtin_eval(char **argv) FAST_FUNC;
1006static int builtin_exec(char **argv) FAST_FUNC;
1007static int builtin_exit(char **argv) FAST_FUNC;
1008#if ENABLE_HUSH_EXPORT
1009static int builtin_export(char **argv) FAST_FUNC;
1010#endif
1011#if ENABLE_HUSH_READONLY
1012static int builtin_readonly(char **argv) FAST_FUNC;
1013#endif
1014#if ENABLE_HUSH_JOB
1015static int builtin_fg_bg(char **argv) FAST_FUNC;
1016static int builtin_jobs(char **argv) FAST_FUNC;
1017#endif
1018#if ENABLE_HUSH_GETOPTS
1019static int builtin_getopts(char **argv) FAST_FUNC;
1020#endif
1021#if ENABLE_HUSH_HELP
1022static int builtin_help(char **argv) FAST_FUNC;
1023#endif
1024#if MAX_HISTORY && ENABLE_FEATURE_EDITING
1025static int builtin_history(char **argv) FAST_FUNC;
1026#endif
1027#if ENABLE_HUSH_LOCAL
1028static int builtin_local(char **argv) FAST_FUNC;
1029#endif
1030#if ENABLE_HUSH_MEMLEAK
1031static int builtin_memleak(char **argv) FAST_FUNC;
1032#endif
1033#if ENABLE_HUSH_PRINTF
1034static int builtin_printf(char **argv) FAST_FUNC;
1035#endif
1036static int builtin_pwd(char **argv) FAST_FUNC;
1037#if ENABLE_HUSH_READ
1038static int builtin_read(char **argv) FAST_FUNC;
1039#endif
1040#if ENABLE_HUSH_SET
1041static int builtin_set(char **argv) FAST_FUNC;
1042#endif
1043static int builtin_shift(char **argv) FAST_FUNC;
1044static int builtin_source(char **argv) FAST_FUNC;
1045#if ENABLE_HUSH_TEST || BASH_TEST2
1046static int builtin_test(char **argv) FAST_FUNC;
1047#endif
1048#if ENABLE_HUSH_TRAP
1049static int builtin_trap(char **argv) FAST_FUNC;
1050#endif
1051#if ENABLE_HUSH_TYPE
1052static int builtin_type(char **argv) FAST_FUNC;
1053#endif
1054#if ENABLE_HUSH_TIMES
1055static int builtin_times(char **argv) FAST_FUNC;
1056#endif
1057static int builtin_true(char **argv) FAST_FUNC;
1058#if ENABLE_HUSH_UMASK
1059static int builtin_umask(char **argv) FAST_FUNC;
1060#endif
1061#if ENABLE_HUSH_UNSET
1062static int builtin_unset(char **argv) FAST_FUNC;
1063#endif
1064#if ENABLE_HUSH_KILL
1065static int builtin_kill(char **argv) FAST_FUNC;
1066#endif
1067#if ENABLE_HUSH_WAIT
1068static int builtin_wait(char **argv) FAST_FUNC;
1069#endif
1070#if ENABLE_HUSH_LOOPS
1071static int builtin_break(char **argv) FAST_FUNC;
1072static int builtin_continue(char **argv) FAST_FUNC;
1073#endif
1074#if ENABLE_HUSH_FUNCTIONS
1075static int builtin_return(char **argv) FAST_FUNC;
1076#endif
1077
1078/* Table of built-in functions.  They can be forked or not, depending on
1079 * context: within pipes, they fork.  As simple commands, they do not.
1080 * When used in non-forking context, they can change global variables
1081 * in the parent shell process.  If forked, of course they cannot.
1082 * For example, 'unset foo | whatever' will parse and run, but foo will
1083 * still be set at the end. */
1084struct built_in_command {
1085        const char *b_cmd;
1086        int (*b_function)(char **argv) FAST_FUNC;
1087#if ENABLE_HUSH_HELP
1088        const char *b_descr;
1089# define BLTIN(cmd, func, help) { cmd, func, help }
1090#else
1091# define BLTIN(cmd, func, help) { cmd, func }
1092#endif
1093};
1094
1095static const struct built_in_command bltins1[] = {
1096        BLTIN("."        , builtin_source  , "Run commands in file"),
1097        BLTIN(":"        , builtin_true    , NULL),
1098#if ENABLE_HUSH_JOB
1099        BLTIN("bg"       , builtin_fg_bg   , "Resume job in background"),
1100#endif
1101#if ENABLE_HUSH_LOOPS
1102        BLTIN("break"    , builtin_break   , "Exit loop"),
1103#endif
1104        BLTIN("cd"       , builtin_cd      , "Change directory"),
1105#if ENABLE_HUSH_LOOPS
1106        BLTIN("continue" , builtin_continue, "Start new loop iteration"),
1107#endif
1108        BLTIN("eval"     , builtin_eval    , "Construct and run shell command"),
1109        BLTIN("exec"     , builtin_exec    , "Execute command, don't return to shell"),
1110        BLTIN("exit"     , builtin_exit    , NULL),
1111#if ENABLE_HUSH_EXPORT
1112        BLTIN("export"   , builtin_export  , "Set environment variables"),
1113#endif
1114#if ENABLE_HUSH_JOB
1115        BLTIN("fg"       , builtin_fg_bg   , "Bring job to foreground"),
1116#endif
1117#if ENABLE_HUSH_GETOPTS
1118        BLTIN("getopts"  , builtin_getopts , NULL),
1119#endif
1120#if ENABLE_HUSH_HELP
1121        BLTIN("help"     , builtin_help    , NULL),
1122#endif
1123#if MAX_HISTORY && ENABLE_FEATURE_EDITING
1124        BLTIN("history"  , builtin_history , "Show history"),
1125#endif
1126#if ENABLE_HUSH_JOB
1127        BLTIN("jobs"     , builtin_jobs    , "List jobs"),
1128#endif
1129#if ENABLE_HUSH_KILL
1130        BLTIN("kill"     , builtin_kill    , "Send signals to processes"),
1131#endif
1132#if ENABLE_HUSH_LOCAL
1133        BLTIN("local"    , builtin_local   , "Set local variables"),
1134#endif
1135#if ENABLE_HUSH_MEMLEAK
1136        BLTIN("memleak"  , builtin_memleak , NULL),
1137#endif
1138#if ENABLE_HUSH_READ
1139        BLTIN("read"     , builtin_read    , "Input into variable"),
1140#endif
1141#if ENABLE_HUSH_READONLY
1142        BLTIN("readonly" , builtin_readonly, "Make variables read-only"),
1143#endif
1144#if ENABLE_HUSH_FUNCTIONS
1145        BLTIN("return"   , builtin_return  , "Return from function"),
1146#endif
1147#if ENABLE_HUSH_SET
1148        BLTIN("set"      , builtin_set     , "Set positional parameters"),
1149#endif
1150        BLTIN("shift"    , builtin_shift   , "Shift positional parameters"),
1151#if BASH_SOURCE
1152        BLTIN("source"   , builtin_source  , NULL),
1153#endif
1154#if ENABLE_HUSH_TIMES
1155        BLTIN("times"    , builtin_times   , NULL),
1156#endif
1157#if ENABLE_HUSH_TRAP
1158        BLTIN("trap"     , builtin_trap    , "Trap signals"),
1159#endif
1160        BLTIN("true"     , builtin_true    , NULL),
1161#if ENABLE_HUSH_TYPE
1162        BLTIN("type"     , builtin_type    , "Show command type"),
1163#endif
1164#if ENABLE_HUSH_ULIMIT
1165        BLTIN("ulimit"   , shell_builtin_ulimit, "Control resource limits"),
1166#endif
1167#if ENABLE_HUSH_UMASK
1168        BLTIN("umask"    , builtin_umask   , "Set file creation mask"),
1169#endif
1170#if ENABLE_HUSH_UNSET
1171        BLTIN("unset"    , builtin_unset   , "Unset variables"),
1172#endif
1173#if ENABLE_HUSH_WAIT
1174        BLTIN("wait"     , builtin_wait    , "Wait for process to finish"),
1175#endif
1176};
1177/* These builtins won't be used if we are on NOMMU and need to re-exec
1178 * (it's cheaper to run an external program in this case):
1179 */
1180static const struct built_in_command bltins2[] = {
1181#if ENABLE_HUSH_TEST
1182        BLTIN("["        , builtin_test    , NULL),
1183#endif
1184#if BASH_TEST2
1185        BLTIN("[["       , builtin_test    , NULL),
1186#endif
1187#if ENABLE_HUSH_ECHO
1188        BLTIN("echo"     , builtin_echo    , NULL),
1189#endif
1190#if ENABLE_HUSH_PRINTF
1191        BLTIN("printf"   , builtin_printf  , NULL),
1192#endif
1193        BLTIN("pwd"      , builtin_pwd     , NULL),
1194#if ENABLE_HUSH_TEST
1195        BLTIN("test"     , builtin_test    , NULL),
1196#endif
1197};
1198
1199
1200/* Debug printouts.
1201 */
1202#if HUSH_DEBUG
1203/* prevent disasters with G.debug_indent < 0 */
1204# define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "")
1205# define debug_enter() (G.debug_indent++)
1206# define debug_leave() (G.debug_indent--)
1207#else
1208# define indent()      ((void)0)
1209# define debug_enter() ((void)0)
1210# define debug_leave() ((void)0)
1211#endif
1212
1213#ifndef debug_printf
1214# define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__))
1215#endif
1216
1217#ifndef debug_printf_parse
1218# define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__))
1219#endif
1220
1221#ifndef debug_printf_exec
1222#define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__))
1223#endif
1224
1225#ifndef debug_printf_env
1226# define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__))
1227#endif
1228
1229#ifndef debug_printf_jobs
1230# define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__))
1231# define DEBUG_JOBS 1
1232#else
1233# define DEBUG_JOBS 0
1234#endif
1235
1236#ifndef debug_printf_expand
1237# define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__))
1238# define DEBUG_EXPAND 1
1239#else
1240# define DEBUG_EXPAND 0
1241#endif
1242
1243#ifndef debug_printf_varexp
1244# define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__))
1245#endif
1246
1247#ifndef debug_printf_glob
1248# define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__))
1249# define DEBUG_GLOB 1
1250#else
1251# define DEBUG_GLOB 0
1252#endif
1253
1254#ifndef debug_printf_redir
1255# define debug_printf_redir(...) (indent(), fdprintf(2, __VA_ARGS__))
1256#endif
1257
1258#ifndef debug_printf_list
1259# define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__))
1260#endif
1261
1262#ifndef debug_printf_subst
1263# define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__))
1264#endif
1265
1266#ifndef debug_printf_prompt
1267# define debug_printf_prompt(...) (indent(), fdprintf(2, __VA_ARGS__))
1268#endif
1269
1270#ifndef debug_printf_clean
1271# define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__))
1272# define DEBUG_CLEAN 1
1273#else
1274# define DEBUG_CLEAN 0
1275#endif
1276
1277#if DEBUG_EXPAND
1278static void debug_print_strings(const char *prefix, char **vv)
1279{
1280        indent();
1281        fdprintf(2, "%s:\n", prefix);
1282        while (*vv)
1283                fdprintf(2, " '%s'\n", *vv++);
1284}
1285#else
1286# define debug_print_strings(prefix, vv) ((void)0)
1287#endif
1288
1289
1290/* Leak hunting. Use hush_leaktool.sh for post-processing.
1291 */
1292#if LEAK_HUNTING
1293static void *xxmalloc(int lineno, size_t size)
1294{
1295        void *ptr = xmalloc((size + 0xff) & ~0xff);
1296        fdprintf(2, "line %d: malloc %p\n", lineno, ptr);
1297        return ptr;
1298}
1299static void *xxrealloc(int lineno, void *ptr, size_t size)
1300{
1301        ptr = xrealloc(ptr, (size + 0xff) & ~0xff);
1302        fdprintf(2, "line %d: realloc %p\n", lineno, ptr);
1303        return ptr;
1304}
1305static char *xxstrdup(int lineno, const char *str)
1306{
1307        char *ptr = xstrdup(str);
1308        fdprintf(2, "line %d: strdup %p\n", lineno, ptr);
1309        return ptr;
1310}
1311static void xxfree(void *ptr)
1312{
1313        fdprintf(2, "free %p\n", ptr);
1314        free(ptr);
1315}
1316# define xmalloc(s)     xxmalloc(__LINE__, s)
1317# define xrealloc(p, s) xxrealloc(__LINE__, p, s)
1318# define xstrdup(s)     xxstrdup(__LINE__, s)
1319# define free(p)        xxfree(p)
1320#endif
1321
1322
1323/* Syntax and runtime errors. They always abort scripts.
1324 * In interactive use they usually discard unparsed and/or unexecuted commands
1325 * and return to the prompt.
1326 * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
1327 */
1328#if HUSH_DEBUG < 2
1329# define msg_and_die_if_script(lineno, ...)     msg_and_die_if_script(__VA_ARGS__)
1330# define syntax_error(lineno, msg)              syntax_error(msg)
1331# define syntax_error_at(lineno, msg)           syntax_error_at(msg)
1332# define syntax_error_unterm_ch(lineno, ch)     syntax_error_unterm_ch(ch)
1333# define syntax_error_unterm_str(lineno, s)     syntax_error_unterm_str(s)
1334# define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch)
1335#endif
1336
1337static void die_if_script(void)
1338{
1339        if (!G_interactive_fd) {
1340                if (G.last_exitcode) /* sometines it's 2, not 1 (bash compat) */
1341                        xfunc_error_retval = G.last_exitcode;
1342                xfunc_die();
1343        }
1344}
1345
1346static void msg_and_die_if_script(unsigned lineno, const char *fmt, ...)
1347{
1348        va_list p;
1349
1350#if HUSH_DEBUG >= 2
1351        bb_error_msg("hush.c:%u", lineno);
1352#endif
1353        va_start(p, fmt);
1354        bb_verror_msg(fmt, p, NULL);
1355        va_end(p);
1356        die_if_script();
1357}
1358
1359static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg)
1360{
1361        if (msg)
1362                bb_error_msg("syntax error: %s", msg);
1363        else
1364                bb_error_msg("syntax error");
1365        die_if_script();
1366}
1367
1368static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg)
1369{
1370        bb_error_msg("syntax error at '%s'", msg);
1371        die_if_script();
1372}
1373
1374static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s)
1375{
1376        bb_error_msg("syntax error: unterminated %s", s);
1377//? source4.tests fails: in bash, echo ${^} in script does not terminate the script
1378//      die_if_script();
1379}
1380
1381static void syntax_error_unterm_ch(unsigned lineno, char ch)
1382{
1383        char msg[2] = { ch, '\0' };
1384        syntax_error_unterm_str(lineno, msg);
1385}
1386
1387static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch)
1388{
1389        char msg[2];
1390        msg[0] = ch;
1391        msg[1] = '\0';
1392#if HUSH_DEBUG >= 2
1393        bb_error_msg("hush.c:%u", lineno);
1394#endif
1395        bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg);
1396        die_if_script();
1397}
1398
1399#if HUSH_DEBUG < 2
1400# undef msg_and_die_if_script
1401# undef syntax_error
1402# undef syntax_error_at
1403# undef syntax_error_unterm_ch
1404# undef syntax_error_unterm_str
1405# undef syntax_error_unexpected_ch
1406#else
1407# define msg_and_die_if_script(...)     msg_and_die_if_script(__LINE__, __VA_ARGS__)
1408# define syntax_error(msg)              syntax_error(__LINE__, msg)
1409# define syntax_error_at(msg)           syntax_error_at(__LINE__, msg)
1410# define syntax_error_unterm_ch(ch)     syntax_error_unterm_ch(__LINE__, ch)
1411# define syntax_error_unterm_str(s)     syntax_error_unterm_str(__LINE__, s)
1412# define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch)
1413#endif
1414
1415
1416#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
1417static void cmdedit_update_prompt(void);
1418#else
1419# define cmdedit_update_prompt() ((void)0)
1420#endif
1421
1422
1423/* Utility functions
1424 */
1425/* Replace each \x with x in place, return ptr past NUL. */
1426static char *unbackslash(char *src)
1427{
1428        char *dst = src = strchrnul(src, '\\');
1429        while (1) {
1430                if (*src == '\\') {
1431                        src++;
1432                        if (*src != '\0') {
1433                                /* \x -> x */
1434                                *dst++ = *src++;
1435                                continue;
1436                        }
1437                        /* else: "\<nul>". Do not delete this backslash.
1438                         * Testcase: eval 'echo ok\'
1439                         */
1440                        *dst++ = '\\';
1441                        /* fallthrough */
1442                }
1443                if ((*dst++ = *src++) == '\0')
1444                        break;
1445        }
1446        return dst;
1447}
1448
1449static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
1450{
1451        int i;
1452        unsigned count1;
1453        unsigned count2;
1454        char **v;
1455
1456        v = strings;
1457        count1 = 0;
1458        if (v) {
1459                while (*v) {
1460                        count1++;
1461                        v++;
1462                }
1463        }
1464        count2 = 0;
1465        v = add;
1466        while (*v) {
1467                count2++;
1468                v++;
1469        }
1470        v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*));
1471        v[count1 + count2] = NULL;
1472        i = count2;
1473        while (--i >= 0)
1474                v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
1475        return v;
1476}
1477#if LEAK_HUNTING
1478static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup)
1479{
1480        char **ptr = add_strings_to_strings(strings, add, need_to_dup);
1481        fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr);
1482        return ptr;
1483}
1484#define add_strings_to_strings(strings, add, need_to_dup) \
1485        xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup)
1486#endif
1487
1488/* Note: takes ownership of "add" ptr (it is not strdup'ed) */
1489static char **add_string_to_strings(char **strings, char *add)
1490{
1491        char *v[2];
1492        v[0] = add;
1493        v[1] = NULL;
1494        return add_strings_to_strings(strings, v, /*dup:*/ 0);
1495}
1496#if LEAK_HUNTING
1497static char **xx_add_string_to_strings(int lineno, char **strings, char *add)
1498{
1499        char **ptr = add_string_to_strings(strings, add);
1500        fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr);
1501        return ptr;
1502}
1503#define add_string_to_strings(strings, add) \
1504        xx_add_string_to_strings(__LINE__, strings, add)
1505#endif
1506
1507static void free_strings(char **strings)
1508{
1509        char **v;
1510
1511        if (!strings)
1512                return;
1513        v = strings;
1514        while (*v) {
1515                free(*v);
1516                v++;
1517        }
1518        free(strings);
1519}
1520
1521static int dup_CLOEXEC(int fd, int avoid_fd)
1522{
1523        int newfd;
1524 repeat:
1525        newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1526        if (newfd >= 0) {
1527                if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1528                        fcntl(newfd, F_SETFD, FD_CLOEXEC);
1529        } else { /* newfd < 0 */
1530                if (errno == EBUSY)
1531                        goto repeat;
1532                if (errno == EINTR)
1533                        goto repeat;
1534        }
1535        return newfd;
1536}
1537
1538static int xdup_CLOEXEC_and_close(int fd, int avoid_fd)
1539{
1540        int newfd;
1541 repeat:
1542        newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1543        if (newfd < 0) {
1544                if (errno == EBUSY)
1545                        goto repeat;
1546                if (errno == EINTR)
1547                        goto repeat;
1548                /* fd was not open? */
1549                if (errno == EBADF)
1550                        return fd;
1551                xfunc_die();
1552        }
1553        if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1554                fcntl(newfd, F_SETFD, FD_CLOEXEC);
1555        close(fd);
1556        return newfd;
1557}
1558
1559
1560/* Manipulating the list of open FILEs */
1561static FILE *remember_FILE(FILE *fp)
1562{
1563        if (fp) {
1564                struct FILE_list *n = xmalloc(sizeof(*n));
1565                n->next = G.FILE_list;
1566                G.FILE_list = n;
1567                n->fp = fp;
1568                n->fd = fileno(fp);
1569                close_on_exec_on(n->fd);
1570        }
1571        return fp;
1572}
1573static void fclose_and_forget(FILE *fp)
1574{
1575        struct FILE_list **pp = &G.FILE_list;
1576        while (*pp) {
1577                struct FILE_list *cur = *pp;
1578                if (cur->fp == fp) {
1579                        *pp = cur->next;
1580                        free(cur);
1581                        break;
1582                }
1583                pp = &cur->next;
1584        }
1585        fclose(fp);
1586}
1587static int save_FILEs_on_redirect(int fd, int avoid_fd)
1588{
1589        struct FILE_list *fl = G.FILE_list;
1590        while (fl) {
1591                if (fd == fl->fd) {
1592                        /* We use it only on script files, they are all CLOEXEC */
1593                        fl->fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1594                        debug_printf_redir("redirect_fd %d: matches a script fd, moving it to %d\n", fd, fl->fd);
1595                        return 1;
1596                }
1597                fl = fl->next;
1598        }
1599        return 0;
1600}
1601static void restore_redirected_FILEs(void)
1602{
1603        struct FILE_list *fl = G.FILE_list;
1604        while (fl) {
1605                int should_be = fileno(fl->fp);
1606                if (fl->fd != should_be) {
1607                        debug_printf_redir("restoring script fd from %d to %d\n", fl->fd, should_be);
1608                        xmove_fd(fl->fd, should_be);
1609                        fl->fd = should_be;
1610                }
1611                fl = fl->next;
1612        }
1613}
1614#if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
1615static void close_all_FILE_list(void)
1616{
1617        struct FILE_list *fl = G.FILE_list;
1618        while (fl) {
1619                /* fclose would also free FILE object.
1620                 * It is disastrous if we share memory with a vforked parent.
1621                 * I'm not sure we never come here after vfork.
1622                 * Therefore just close fd, nothing more.
1623                 */
1624                /*fclose(fl->fp); - unsafe */
1625                close(fl->fd);
1626                fl = fl->next;
1627        }
1628}
1629#endif
1630static int fd_in_FILEs(int fd)
1631{
1632        struct FILE_list *fl = G.FILE_list;
1633        while (fl) {
1634                if (fl->fd == fd)
1635                        return 1;
1636                fl = fl->next;
1637        }
1638        return 0;
1639}
1640
1641
1642/* Helpers for setting new $n and restoring them back
1643 */
1644typedef struct save_arg_t {
1645        char *sv_argv0;
1646        char **sv_g_argv;
1647        int sv_g_argc;
1648        IF_HUSH_SET(smallint sv_g_malloced;)
1649} save_arg_t;
1650
1651static void save_and_replace_G_args(save_arg_t *sv, char **argv)
1652{
1653        sv->sv_argv0 = argv[0];
1654        sv->sv_g_argv = G.global_argv;
1655        sv->sv_g_argc = G.global_argc;
1656        IF_HUSH_SET(sv->sv_g_malloced = G.global_args_malloced;)
1657
1658        argv[0] = G.global_argv[0]; /* retain $0 */
1659        G.global_argv = argv;
1660        IF_HUSH_SET(G.global_args_malloced = 0;)
1661
1662        G.global_argc = 1 + string_array_len(argv + 1);
1663}
1664
1665static void restore_G_args(save_arg_t *sv, char **argv)
1666{
1667#if ENABLE_HUSH_SET
1668        if (G.global_args_malloced) {
1669                /* someone ran "set -- arg1 arg2 ...", undo */
1670                char **pp = G.global_argv;
1671                while (*++pp) /* note: does not free $0 */
1672                        free(*pp);
1673                free(G.global_argv);
1674        }
1675#endif
1676        argv[0] = sv->sv_argv0;
1677        G.global_argv = sv->sv_g_argv;
1678        G.global_argc = sv->sv_g_argc;
1679        IF_HUSH_SET(G.global_args_malloced = sv->sv_g_malloced;)
1680}
1681
1682
1683/* Basic theory of signal handling in shell
1684 * ========================================
1685 * This does not describe what hush does, rather, it is current understanding
1686 * what it _should_ do. If it doesn't, it's a bug.
1687 * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
1688 *
1689 * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
1690 * is finished or backgrounded. It is the same in interactive and
1691 * non-interactive shells, and is the same regardless of whether
1692 * a user trap handler is installed or a shell special one is in effect.
1693 * ^C or ^Z from keyboard seems to execute "at once" because it usually
1694 * backgrounds (i.e. stops) or kills all members of currently running
1695 * pipe.
1696 *
1697 * Wait builtin is interruptible by signals for which user trap is set
1698 * or by SIGINT in interactive shell.
1699 *
1700 * Trap handlers will execute even within trap handlers. (right?)
1701 *
1702 * User trap handlers are forgotten when subshell ("(cmd)") is entered,
1703 * except for handlers set to '' (empty string).
1704 *
1705 * If job control is off, backgrounded commands ("cmd &")
1706 * have SIGINT, SIGQUIT set to SIG_IGN.
1707 *
1708 * Commands which are run in command substitution ("`cmd`")
1709 * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
1710 *
1711 * Ordinary commands have signals set to SIG_IGN/DFL as inherited
1712 * by the shell from its parent.
1713 *
1714 * Signals which differ from SIG_DFL action
1715 * (note: child (i.e., [v]forked) shell is not an interactive shell):
1716 *
1717 * SIGQUIT: ignore
1718 * SIGTERM (interactive): ignore
1719 * SIGHUP (interactive):
1720 *    send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit
1721 * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
1722 *    Note that ^Z is handled not by trapping SIGTSTP, but by seeing
1723 *    that all pipe members are stopped. Try this in bash:
1724 *    while :; do :; done - ^Z does not background it
1725 *    (while :; do :; done) - ^Z backgrounds it
1726 * SIGINT (interactive): wait for last pipe, ignore the rest
1727 *    of the command line, show prompt. NB: ^C does not send SIGINT
1728 *    to interactive shell while shell is waiting for a pipe,
1729 *    since shell is bg'ed (is not in foreground process group).
1730 *    Example 1: this waits 5 sec, but does not execute ls:
1731 *    "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
1732 *    Example 2: this does not wait and does not execute ls:
1733 *    "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1734 *    Example 3: this does not wait 5 sec, but executes ls:
1735 *    "sleep 5; ls -l" + press ^C
1736 *    Example 4: this does not wait and does not execute ls:
1737 *    "sleep 5 & wait; ls -l" + press ^C
1738 *
1739 * (What happens to signals which are IGN on shell start?)
1740 * (What happens with signal mask on shell start?)
1741 *
1742 * Old implementation
1743 * ==================
1744 * We use in-kernel pending signal mask to determine which signals were sent.
1745 * We block all signals which we don't want to take action immediately,
1746 * i.e. we block all signals which need to have special handling as described
1747 * above, and all signals which have traps set.
1748 * After each pipe execution, we extract any pending signals via sigtimedwait()
1749 * and act on them.
1750 *
1751 * unsigned special_sig_mask: a mask of such "special" signals
1752 * sigset_t blocked_set:  current blocked signal set
1753 *
1754 * "trap - SIGxxx":
1755 *    clear bit in blocked_set unless it is also in special_sig_mask
1756 * "trap 'cmd' SIGxxx":
1757 *    set bit in blocked_set (even if 'cmd' is '')
1758 * after [v]fork, if we plan to be a shell:
1759 *    unblock signals with special interactive handling
1760 *    (child shell is not interactive),
1761 *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1762 * after [v]fork, if we plan to exec:
1763 *    POSIX says fork clears pending signal mask in child - no need to clear it.
1764 *    Restore blocked signal set to one inherited by shell just prior to exec.
1765 *
1766 * Note: as a result, we do not use signal handlers much. The only uses
1767 * are to count SIGCHLDs
1768 * and to restore tty pgrp on signal-induced exit.
1769 *
1770 * Note 2 (compat):
1771 * Standard says "When a subshell is entered, traps that are not being ignored
1772 * are set to the default actions". bash interprets it so that traps which
1773 * are set to '' (ignore) are NOT reset to defaults. We do the same.
1774 *
1775 * Problem: the above approach makes it unwieldy to catch signals while
1776 * we are in read builtin, or while we read commands from stdin:
1777 * masked signals are not visible!
1778 *
1779 * New implementation
1780 * ==================
1781 * We record each signal we are interested in by installing signal handler
1782 * for them - a bit like emulating kernel pending signal mask in userspace.
1783 * We are interested in: signals which need to have special handling
1784 * as described above, and all signals which have traps set.
1785 * Signals are recorded in pending_set.
1786 * After each pipe execution, we extract any pending signals
1787 * and act on them.
1788 *
1789 * unsigned special_sig_mask: a mask of shell-special signals.
1790 * unsigned fatal_sig_mask: a mask of signals on which we restore tty pgrp.
1791 * char *traps[sig] if trap for sig is set (even if it's '').
1792 * sigset_t pending_set: set of sigs we received.
1793 *
1794 * "trap - SIGxxx":
1795 *    if sig is in special_sig_mask, set handler back to:
1796 *        record_pending_signo, or to IGN if it's a tty stop signal
1797 *    if sig is in fatal_sig_mask, set handler back to sigexit.
1798 *    else: set handler back to SIG_DFL
1799 * "trap 'cmd' SIGxxx":
1800 *    set handler to record_pending_signo.
1801 * "trap '' SIGxxx":
1802 *    set handler to SIG_IGN.
1803 * after [v]fork, if we plan to be a shell:
1804 *    set signals with special interactive handling to SIG_DFL
1805 *    (because child shell is not interactive),
1806 *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1807 * after [v]fork, if we plan to exec:
1808 *    POSIX says fork clears pending signal mask in child - no need to clear it.
1809 *
1810 * To make wait builtin interruptible, we handle SIGCHLD as special signal,
1811 * otherwise (if we leave it SIG_DFL) sigsuspend in wait builtin will not wake up on it.
1812 *
1813 * Note (compat):
1814 * Standard says "When a subshell is entered, traps that are not being ignored
1815 * are set to the default actions". bash interprets it so that traps which
1816 * are set to '' (ignore) are NOT reset to defaults. We do the same.
1817 */
1818enum {
1819        SPECIAL_INTERACTIVE_SIGS = 0
1820                | (1 << SIGTERM)
1821                | (1 << SIGINT)
1822                | (1 << SIGHUP)
1823                ,
1824        SPECIAL_JOBSTOP_SIGS = 0
1825#if ENABLE_HUSH_JOB
1826                | (1 << SIGTTIN)
1827                | (1 << SIGTTOU)
1828                | (1 << SIGTSTP)
1829#endif
1830                ,
1831};
1832
1833static void record_pending_signo(int sig)
1834{
1835        sigaddset(&G.pending_set, sig);
1836#if ENABLE_HUSH_FAST
1837        if (sig == SIGCHLD) {
1838                G.count_SIGCHLD++;
1839//bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1840        }
1841#endif
1842}
1843
1844static sighandler_t install_sighandler(int sig, sighandler_t handler)
1845{
1846        struct sigaction old_sa;
1847
1848        /* We could use signal() to install handlers... almost:
1849         * except that we need to mask ALL signals while handlers run.
1850         * I saw signal nesting in strace, race window isn't small.
1851         * SA_RESTART is also needed, but in Linux, signal()
1852         * sets SA_RESTART too.
1853         */
1854        /* memset(&G.sa, 0, sizeof(G.sa)); - already done */
1855        /* sigfillset(&G.sa.sa_mask);      - already done */
1856        /* G.sa.sa_flags = SA_RESTART;     - already done */
1857        G.sa.sa_handler = handler;
1858        sigaction(sig, &G.sa, &old_sa);
1859        return old_sa.sa_handler;
1860}
1861
1862static void hush_exit(int exitcode) NORETURN;
1863
1864static void restore_ttypgrp_and__exit(void) NORETURN;
1865static void restore_ttypgrp_and__exit(void)
1866{
1867        /* xfunc has failed! die die die */
1868        /* no EXIT traps, this is an escape hatch! */
1869        G.exiting = 1;
1870        hush_exit(xfunc_error_retval);
1871}
1872
1873#if ENABLE_HUSH_JOB
1874
1875/* Needed only on some libc:
1876 * It was observed that on exit(), fgetc'ed buffered data
1877 * gets "unwound" via lseek(fd, -NUM, SEEK_CUR).
1878 * With the net effect that even after fork(), not vfork(),
1879 * exit() in NOEXECed applet in "sh SCRIPT":
1880 *      noexec_applet_here
1881 *      echo END_OF_SCRIPT
1882 * lseeks fd in input FILE object from EOF to "e" in "echo END_OF_SCRIPT".
1883 * This makes "echo END_OF_SCRIPT" executed twice.
1884 * Similar problems can be seen with msg_and_die_if_script() -> xfunc_die()
1885 * and in `cmd` handling.
1886 * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit():
1887 */
1888static void fflush_and__exit(void) NORETURN;
1889static void fflush_and__exit(void)
1890{
1891        fflush_all();
1892        _exit(xfunc_error_retval);
1893}
1894
1895/* After [v]fork, in child: do not restore tty pgrp on xfunc death */
1896# define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit)
1897/* After [v]fork, in parent: restore tty pgrp on xfunc death */
1898# define enable_restore_tty_pgrp_on_exit()  (die_func = restore_ttypgrp_and__exit)
1899
1900/* Restores tty foreground process group, and exits.
1901 * May be called as signal handler for fatal signal
1902 * (will resend signal to itself, producing correct exit state)
1903 * or called directly with -EXITCODE.
1904 * We also call it if xfunc is exiting.
1905 */
1906static void sigexit(int sig) NORETURN;
1907static void sigexit(int sig)
1908{
1909        /* Careful: we can end up here after [v]fork. Do not restore
1910         * tty pgrp then, only top-level shell process does that */
1911        if (G_saved_tty_pgrp && getpid() == G.root_pid) {
1912                /* Disable all signals: job control, SIGPIPE, etc.
1913                 * Mostly paranoid measure, to prevent infinite SIGTTOU.
1914                 */
1915                sigprocmask_allsigs(SIG_BLOCK);
1916                tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
1917        }
1918
1919        /* Not a signal, just exit */
1920        if (sig <= 0)
1921                _exit(- sig);
1922
1923        kill_myself_with_sig(sig); /* does not return */
1924}
1925#else
1926
1927# define disable_restore_tty_pgrp_on_exit() ((void)0)
1928# define enable_restore_tty_pgrp_on_exit()  ((void)0)
1929
1930#endif
1931
1932static sighandler_t pick_sighandler(unsigned sig)
1933{
1934        sighandler_t handler = SIG_DFL;
1935        if (sig < sizeof(unsigned)*8) {
1936                unsigned sigmask = (1 << sig);
1937
1938#if ENABLE_HUSH_JOB
1939                /* is sig fatal? */
1940                if (G_fatal_sig_mask & sigmask)
1941                        handler = sigexit;
1942                else
1943#endif
1944                /* sig has special handling? */
1945                if (G.special_sig_mask & sigmask) {
1946                        handler = record_pending_signo;
1947                        /* TTIN/TTOU/TSTP can't be set to record_pending_signo
1948                         * in order to ignore them: they will be raised
1949                         * in an endless loop when we try to do some
1950                         * terminal ioctls! We do have to _ignore_ these.
1951                         */
1952                        if (SPECIAL_JOBSTOP_SIGS & sigmask)
1953                                handler = SIG_IGN;
1954                }
1955        }
1956        return handler;
1957}
1958
1959/* Restores tty foreground process group, and exits. */
1960static void hush_exit(int exitcode)
1961{
1962#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1963        save_history(G.line_input_state);
1964#endif
1965
1966        fflush_all();
1967        if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) {
1968                char *argv[3];
1969                /* argv[0] is unused */
1970                argv[1] = xstrdup(G_traps[0]); /* copy, since EXIT trap handler may modify G_traps[0] */
1971                argv[2] = NULL;
1972                G.exiting = 1; /* prevent EXIT trap recursion */
1973                /* Note: G_traps[0] is not cleared!
1974                 * "trap" will still show it, if executed
1975                 * in the handler */
1976                builtin_eval(argv);
1977        }
1978
1979#if ENABLE_FEATURE_CLEAN_UP
1980        {
1981                struct variable *cur_var;
1982                if (G.cwd != bb_msg_unknown)
1983                        free((char*)G.cwd);
1984                cur_var = G.top_var;
1985                while (cur_var) {
1986                        struct variable *tmp = cur_var;
1987                        if (!cur_var->max_len)
1988                                free(cur_var->varstr);
1989                        cur_var = cur_var->next;
1990                        free(tmp);
1991                }
1992        }
1993#endif
1994
1995        fflush_all();
1996#if ENABLE_HUSH_JOB
1997        sigexit(- (exitcode & 0xff));
1998#else
1999        _exit(exitcode);
2000#endif
2001}
2002
2003
2004//TODO: return a mask of ALL handled sigs?
2005static int check_and_run_traps(void)
2006{
2007        int last_sig = 0;
2008
2009        while (1) {
2010                int sig;
2011
2012                if (sigisemptyset(&G.pending_set))
2013                        break;
2014                sig = 0;
2015                do {
2016                        sig++;
2017                        if (sigismember(&G.pending_set, sig)) {
2018                                sigdelset(&G.pending_set, sig);
2019                                goto got_sig;
2020                        }
2021                } while (sig < NSIG);
2022                break;
2023 got_sig:
2024                if (G_traps && G_traps[sig]) {
2025                        debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]);
2026                        if (G_traps[sig][0]) {
2027                                /* We have user-defined handler */
2028                                smalluint save_rcode;
2029                                char *argv[3];
2030                                /* argv[0] is unused */
2031                                argv[1] = xstrdup(G_traps[sig]);
2032                                /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */
2033                                argv[2] = NULL;
2034                                save_rcode = G.last_exitcode;
2035                                builtin_eval(argv);
2036                                free(argv[1]);
2037//FIXME: shouldn't it be set to 128 + sig instead?
2038                                G.last_exitcode = save_rcode;
2039                                last_sig = sig;
2040                        } /* else: "" trap, ignoring signal */
2041                        continue;
2042                }
2043                /* not a trap: special action */
2044                switch (sig) {
2045                case SIGINT:
2046                        debug_printf_exec("%s: sig:%d default SIGINT handler\n", __func__, sig);
2047                        G.flag_SIGINT = 1;
2048                        last_sig = sig;
2049                        break;
2050#if ENABLE_HUSH_JOB
2051                case SIGHUP: {
2052//TODO: why are we doing this? ash and dash don't do this,
2053//they have no handler for SIGHUP at all,
2054//they rely on kernel to send SIGHUP+SIGCONT to orphaned process groups
2055                        struct pipe *job;
2056                        debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig);
2057                        /* bash is observed to signal whole process groups,
2058                         * not individual processes */
2059                        for (job = G.job_list; job; job = job->next) {
2060                                if (job->pgrp <= 0)
2061                                        continue;
2062                                debug_printf_exec("HUPing pgrp %d\n", job->pgrp);
2063                                if (kill(- job->pgrp, SIGHUP) == 0)
2064                                        kill(- job->pgrp, SIGCONT);
2065                        }
2066                        sigexit(SIGHUP);
2067                }
2068#endif
2069#if ENABLE_HUSH_FAST
2070                case SIGCHLD:
2071                        debug_printf_exec("%s: sig:%d default SIGCHLD handler\n", __func__, sig);
2072                        G.count_SIGCHLD++;
2073//bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
2074                        /* Note:
2075                         * We don't do 'last_sig = sig' here -> NOT returning this sig.
2076                         * This simplifies wait builtin a bit.
2077                         */
2078                        break;
2079#endif
2080                default: /* ignored: */
2081                        debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig);
2082                        /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
2083                        /* Note:
2084                         * We don't do 'last_sig = sig' here -> NOT returning this sig.
2085                         * Example: wait is not interrupted by TERM
2086                         * in interactive shell, because TERM is ignored.
2087                         */
2088                        break;
2089                }
2090        }
2091        return last_sig;
2092}
2093
2094
2095static const char *get_cwd(int force)
2096{
2097        if (force || G.cwd == NULL) {
2098                /* xrealloc_getcwd_or_warn(arg) calls free(arg),
2099                 * we must not try to free(bb_msg_unknown) */
2100                if (G.cwd == bb_msg_unknown)
2101                        G.cwd = NULL;
2102                G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd);
2103                if (!G.cwd)
2104                        G.cwd = bb_msg_unknown;
2105        }
2106        return G.cwd;
2107}
2108
2109
2110/*
2111 * Shell and environment variable support
2112 */
2113static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
2114{
2115        struct variable **pp;
2116        struct variable *cur;
2117
2118        pp = &G.top_var;
2119        while ((cur = *pp) != NULL) {
2120                if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
2121                        return pp;
2122                pp = &cur->next;
2123        }
2124        return NULL;
2125}
2126
2127static const char* FAST_FUNC get_local_var_value(const char *name)
2128{
2129        struct variable **vpp;
2130        unsigned len = strlen(name);
2131
2132        if (G.expanded_assignments) {
2133                char **cpp = G.expanded_assignments;
2134                while (*cpp) {
2135                        char *cp = *cpp;
2136                        if (strncmp(cp, name, len) == 0 && cp[len] == '=')
2137                                return cp + len + 1;
2138                        cpp++;
2139                }
2140        }
2141
2142        vpp = get_ptr_to_local_var(name, len);
2143        if (vpp)
2144                return (*vpp)->varstr + len + 1;
2145
2146        if (strcmp(name, "PPID") == 0)
2147                return utoa(G.root_ppid);
2148        // bash compat: UID? EUID?
2149#if ENABLE_HUSH_RANDOM_SUPPORT
2150        if (strcmp(name, "RANDOM") == 0)
2151                return utoa(next_random(&G.random_gen));
2152#endif
2153        return NULL;
2154}
2155
2156static void handle_changed_special_names(const char *name, unsigned name_len)
2157{
2158        if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
2159         && name_len == 3 && name[0] == 'P' && name[1] == 'S'
2160        ) {
2161                cmdedit_update_prompt();
2162                return;
2163        }
2164
2165        if ((ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS)
2166         && name_len == 6
2167        ) {
2168#if ENABLE_HUSH_LINENO_VAR
2169                if (strncmp(name, "LINENO", 6) == 0) {
2170                        G.lineno_var = NULL;
2171                        return;
2172                }
2173#endif
2174#if ENABLE_HUSH_GETOPTS
2175                if (strncmp(name, "OPTIND", 6) == 0) {
2176                        G.getopt_count = 0;
2177                        return;
2178                }
2179#endif
2180        }
2181}
2182
2183/* str holds "NAME=VAL" and is expected to be malloced.
2184 * We take ownership of it.
2185 */
2186#define SETFLAG_EXPORT   (1 << 0)
2187#define SETFLAG_UNEXPORT (1 << 1)
2188#define SETFLAG_MAKE_RO  (1 << 2)
2189#define SETFLAG_VARLVL_SHIFT   3
2190static int set_local_var(char *str, unsigned flags)
2191{
2192        struct variable **cur_pp;
2193        struct variable *cur;
2194        char *free_me = NULL;
2195        char *eq_sign;
2196        int name_len;
2197        unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT);
2198
2199        eq_sign = strchr(str, '=');
2200        if (HUSH_DEBUG && !eq_sign)
2201                bb_error_msg_and_die("BUG in setvar");
2202
2203        name_len = eq_sign - str + 1; /* including '=' */
2204        cur_pp = &G.top_var;
2205        while ((cur = *cur_pp) != NULL) {
2206                if (strncmp(cur->varstr, str, name_len) != 0) {
2207                        cur_pp = &cur->next;
2208                        continue;
2209                }
2210
2211                /* We found an existing var with this name */
2212                if (cur->flg_read_only) {
2213                        bb_error_msg("%s: readonly variable", str);
2214                        free(str);
2215//NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1,
2216//but export per se succeeds (does put the var in env). We don't mimic that.
2217                        return -1;
2218                }
2219                if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ?
2220                        debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
2221                        *eq_sign = '\0';
2222                        unsetenv(str);
2223                        *eq_sign = '=';
2224                }
2225                if (cur->var_nest_level < local_lvl) {
2226                        /* bash 3.2.33(1) and exported vars:
2227                         * # export z=z
2228                         * # f() { local z=a; env | grep ^z; }
2229                         * # f
2230                         * z=a
2231                         * # env | grep ^z
2232                         * z=z
2233                         */
2234                        if (cur->flg_export)
2235                                flags |= SETFLAG_EXPORT;
2236                        /* New variable is local ("local VAR=VAL" or
2237                         * "VAR=VAL cmd")
2238                         * and existing one is global, or local
2239                         * on a lower level that new one.
2240                         * Remove it from global variable list:
2241                         */
2242                        *cur_pp = cur->next;
2243                        if (G.shadowed_vars_pp) {
2244                                /* Save in "shadowed" list */
2245                                debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n",
2246                                        cur->flg_export ? "exported " : "",
2247                                        cur->varstr, cur->var_nest_level, str, local_lvl
2248                                );
2249                                cur->next = *G.shadowed_vars_pp;
2250                                *G.shadowed_vars_pp = cur;
2251                        } else {
2252                                /* Came from pseudo_exec_argv(), no need to save: delete it */
2253                                debug_printf_env("shadow-deleting %s'%s'/%u by '%s'/%u\n",
2254                                        cur->flg_export ? "exported " : "",
2255                                        cur->varstr, cur->var_nest_level, str, local_lvl
2256                                );
2257                                if (cur->max_len == 0) /* allocated "VAR=VAL"? */
2258                                        free_me = cur->varstr; /* then free it later */
2259                                free(cur);
2260                        }
2261                        break;
2262                }
2263
2264                if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) {
2265                        debug_printf_env("assignement '%s' does not change anything\n", str);
2266 free_and_exp:
2267                        free(str);
2268                        goto exp;
2269                }
2270
2271                /* Replace the value in the found "struct variable" */
2272                if (cur->max_len != 0) {
2273                        if (cur->max_len >= strnlen(str, cur->max_len + 1)) {
2274                                /* This one is from startup env, reuse space */
2275                                debug_printf_env("reusing startup env for '%s'\n", str);
2276                                strcpy(cur->varstr, str);
2277                                goto free_and_exp;
2278                        }
2279                        /* Can't reuse */
2280                        cur->max_len = 0;
2281                        goto set_str_and_exp;
2282                }
2283                /* max_len == 0 signifies "malloced" var, which we can
2284                 * (and have to) free. But we can't free(cur->varstr) here:
2285                 * if cur->flg_export is 1, it is in the environment.
2286                 * We should either unsetenv+free, or wait until putenv,
2287                 * then putenv(new)+free(old).
2288                 */
2289                free_me = cur->varstr;
2290                goto set_str_and_exp;
2291        }
2292
2293        /* Not found or shadowed - create new variable struct */
2294        debug_printf_env("%s: alloc new var '%s'/%u\n", __func__, str, local_lvl);
2295        cur = xzalloc(sizeof(*cur));
2296        cur->var_nest_level = local_lvl;
2297        cur->next = *cur_pp;
2298        *cur_pp = cur;
2299
2300 set_str_and_exp:
2301        cur->varstr = str;
2302 exp:
2303#if !BB_MMU || ENABLE_HUSH_READONLY
2304        if (flags & SETFLAG_MAKE_RO) {
2305                cur->flg_read_only = 1;
2306        }
2307#endif
2308        if (flags & SETFLAG_EXPORT)
2309                cur->flg_export = 1;
2310        if (cur->flg_export) {
2311                if (flags & SETFLAG_UNEXPORT) {
2312                        cur->flg_export = 0;
2313                        /* unsetenv was already done */
2314                } else {
2315                        int i;
2316                        debug_printf_env("%s: putenv '%s'/%u\n", __func__, cur->varstr, cur->var_nest_level);
2317                        i = putenv(cur->varstr);
2318                        /* only now we can free old exported malloced string */
2319                        free(free_me);
2320                        return i;
2321                }
2322        }
2323        free(free_me);
2324
2325        handle_changed_special_names(cur->varstr, name_len - 1);
2326
2327        return 0;
2328}
2329
2330/* Used at startup and after each cd */
2331static void set_pwd_var(unsigned flag)
2332{
2333        set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)), flag);
2334}
2335
2336#if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
2337static int unset_local_var_len(const char *name, int name_len)
2338{
2339        struct variable *cur;
2340        struct variable **cur_pp;
2341
2342        cur_pp = &G.top_var;
2343        while ((cur = *cur_pp) != NULL) {
2344                if (strncmp(cur->varstr, name, name_len) == 0
2345                 && cur->varstr[name_len] == '='
2346                ) {
2347                        if (cur->flg_read_only) {
2348                                bb_error_msg("%s: readonly variable", name);
2349                                return EXIT_FAILURE;
2350                        }
2351
2352                        *cur_pp = cur->next;
2353                        debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
2354                        bb_unsetenv(cur->varstr);
2355                        if (!cur->max_len)
2356                                free(cur->varstr);
2357                        free(cur);
2358
2359                        break;
2360                }
2361                cur_pp = &cur->next;
2362        }
2363
2364        /* Handle "unset PS1" et al even if did not find the variable to unset */
2365        handle_changed_special_names(name, name_len);
2366
2367        return EXIT_SUCCESS;
2368}
2369
2370static int unset_local_var(const char *name)
2371{
2372        return unset_local_var_len(name, strlen(name));
2373}
2374#endif
2375
2376#if BASH_HOSTNAME_VAR || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_READ || ENABLE_HUSH_GETOPTS \
2377 || (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT)
2378static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val)
2379{
2380        char *var = xasprintf("%s=%s", name, val);
2381        set_local_var(var, /*flag:*/ 0);
2382}
2383#endif
2384
2385
2386/*
2387 * Helpers for "var1=val1 var2=val2 cmd" feature
2388 */
2389static void add_vars(struct variable *var)
2390{
2391        struct variable *next;
2392
2393        while (var) {
2394                next = var->next;
2395                var->next = G.top_var;
2396                G.top_var = var;
2397                if (var->flg_export) {
2398                        debug_printf_env("%s: restoring exported '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2399                        putenv(var->varstr);
2400                } else {
2401                        debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2402                }
2403                var = next;
2404        }
2405}
2406
2407/* We put strings[i] into variable table and possibly putenv them.
2408 * If variable is read only, we can free the strings[i]
2409 * which attempts to overwrite it.
2410 * The strings[] vector itself is freed.
2411 */
2412static void set_vars_and_save_old(char **strings)
2413{
2414        char **s;
2415
2416        if (!strings)
2417                return;
2418
2419        s = strings;
2420        while (*s) {
2421                struct variable *var_p;
2422                struct variable **var_pp;
2423                char *eq;
2424
2425                eq = strchr(*s, '=');
2426                if (eq) {
2427                        var_pp = get_ptr_to_local_var(*s, eq - *s);
2428                        if (var_pp) {
2429                                var_p = *var_pp;
2430                                if (var_p->flg_read_only) {
2431                                        char **p;
2432                                        bb_error_msg("%s: readonly variable", *s);
2433                                        /*
2434                                         * "VAR=V BLTIN" unsets VARs after BLTIN completes.
2435                                         * If VAR is readonly, leaving it in the list
2436                                         * after asssignment error (msg above)
2437                                         * causes doubled error message later, on unset.
2438                                         */
2439                                        debug_printf_env("removing/freeing '%s' element\n", *s);
2440                                        free(*s);
2441                                        p = s;
2442                                        do { *p = p[1]; p++; } while (*p);
2443                                        goto next;
2444                                }
2445                                /* below, set_local_var() with nest level will
2446                                 * "shadow" (remove) this variable from
2447                                 * global linked list.
2448                                 */
2449                        }
2450                        debug_printf_env("%s: env override '%s'/%u\n", __func__, *s, G.var_nest_level);
2451                        set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT);
2452                } else if (HUSH_DEBUG) {
2453                        bb_error_msg_and_die("BUG in varexp4");
2454                }
2455                s++;
2456 next: ;
2457        }
2458        free(strings);
2459}
2460
2461
2462/*
2463 * Unicode helper
2464 */
2465static void reinit_unicode_for_hush(void)
2466{
2467        /* Unicode support should be activated even if LANG is set
2468         * _during_ shell execution, not only if it was set when
2469         * shell was started. Therefore, re-check LANG every time:
2470         */
2471        if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2472         || ENABLE_UNICODE_USING_LOCALE
2473        ) {
2474                const char *s = get_local_var_value("LC_ALL");
2475                if (!s) s = get_local_var_value("LC_CTYPE");
2476                if (!s) s = get_local_var_value("LANG");
2477                reinit_unicode(s);
2478        }
2479}
2480
2481/*
2482 * in_str support (strings, and "strings" read from files).
2483 */
2484
2485#if ENABLE_HUSH_INTERACTIVE
2486/* To test correct lineedit/interactive behavior, type from command line:
2487 *      echo $P\
2488 *      \
2489 *      AT\
2490 *      H\
2491 *      \
2492 * It exercises a lot of corner cases.
2493 */
2494# if ENABLE_FEATURE_EDITING_FANCY_PROMPT
2495static void cmdedit_update_prompt(void)
2496{
2497        G.PS1 = get_local_var_value("PS1");
2498        if (G.PS1 == NULL)
2499                G.PS1 = "";
2500        G.PS2 = get_local_var_value("PS2");
2501        if (G.PS2 == NULL)
2502                G.PS2 = "";
2503}
2504# endif
2505static const char *setup_prompt_string(void)
2506{
2507        const char *prompt_str;
2508
2509        debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode);
2510
2511        IF_FEATURE_EDITING_FANCY_PROMPT(    prompt_str = G.PS2;)
2512        IF_NOT_FEATURE_EDITING_FANCY_PROMPT(prompt_str = "> ";)
2513        if (G.promptmode == 0) { /* PS1 */
2514                if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT) {
2515                        /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
2516                        free((char*)G.PS1);
2517                        /* bash uses $PWD value, even if it is set by user.
2518                         * It uses current dir only if PWD is unset.
2519                         * We always use current dir. */
2520                        G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
2521                }
2522                prompt_str = G.PS1;
2523        }
2524        debug_printf("prompt_str '%s'\n", prompt_str);
2525        return prompt_str;
2526}
2527static int get_user_input(struct in_str *i)
2528{
2529        int r;
2530        const char *prompt_str;
2531
2532        prompt_str = setup_prompt_string();
2533# if ENABLE_FEATURE_EDITING
2534        for (;;) {
2535                reinit_unicode_for_hush();
2536                if (G.flag_SIGINT) {
2537                        /* There was ^C'ed, make it look prettier: */
2538                        bb_putchar('\n');
2539                        G.flag_SIGINT = 0;
2540                }
2541                /* buglet: SIGINT will not make new prompt to appear _at once_,
2542                 * only after <Enter>. (^C works immediately) */
2543                r = read_line_input(G.line_input_state, prompt_str,
2544                                G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1
2545                );
2546                /* read_line_input intercepts ^C, "convert" it to SIGINT */
2547                if (r == 0)
2548                        raise(SIGINT);
2549                check_and_run_traps();
2550                if (r != 0 && !G.flag_SIGINT)
2551                        break;
2552                /* ^C or SIGINT: repeat */
2553                /* bash prints ^C even on real SIGINT (non-kbd generated) */
2554                write(STDOUT_FILENO, "^C", 2);
2555                G.last_exitcode = 128 + SIGINT;
2556        }
2557        if (r < 0) {
2558                /* EOF/error detected */
2559                i->p = NULL;
2560                i->peek_buf[0] = r = EOF;
2561                return r;
2562        }
2563        i->p = G.user_input_buf;
2564        return (unsigned char)*i->p++;
2565# else
2566        for (;;) {
2567                G.flag_SIGINT = 0;
2568                if (i->last_char == '\0' || i->last_char == '\n') {
2569                        /* Why check_and_run_traps here? Try this interactively:
2570                         * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) &
2571                         * $ <[enter], repeatedly...>
2572                         * Without check_and_run_traps, handler never runs.
2573                         */
2574                        check_and_run_traps();
2575                        fputs(prompt_str, stdout);
2576                }
2577                fflush_all();
2578//FIXME: here ^C or SIGINT will have effect only after <Enter>
2579                r = fgetc(i->file);
2580                /* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
2581                 * no ^C masking happens during fgetc, no special code for ^C:
2582                 * it generates SIGINT as usual.
2583                 */
2584                check_and_run_traps();
2585                if (G.flag_SIGINT)
2586                        G.last_exitcode = 128 + SIGINT;
2587                if (r != '\0')
2588                        break;
2589        }
2590        return r;
2591# endif
2592}
2593/* This is the magic location that prints prompts
2594 * and gets data back from the user */
2595static int fgetc_interactive(struct in_str *i)
2596{
2597        int ch;
2598        /* If it's interactive stdin, get new line. */
2599        if (G_interactive_fd && i->file == stdin) {
2600                /* Returns first char (or EOF), the rest is in i->p[] */
2601                ch = get_user_input(i);
2602                G.promptmode = 1; /* PS2 */
2603                debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
2604        } else {
2605                /* Not stdin: script file, sourced file, etc */
2606                do ch = fgetc(i->file); while (ch == '\0');
2607        }
2608        return ch;
2609}
2610#else
2611static inline int fgetc_interactive(struct in_str *i)
2612{
2613        int ch;
2614        do ch = fgetc(i->file); while (ch == '\0');
2615        return ch;
2616}
2617#endif  /* INTERACTIVE */
2618
2619static int i_getch(struct in_str *i)
2620{
2621        int ch;
2622
2623        if (!i->file) {
2624                /* string-based in_str */
2625                ch = (unsigned char)*i->p;
2626                if (ch != '\0') {
2627                        i->p++;
2628                        i->last_char = ch;
2629                        return ch;
2630                }
2631                return EOF;
2632        }
2633
2634        /* FILE-based in_str */
2635
2636#if ENABLE_FEATURE_EDITING
2637        /* This can be stdin, check line editing char[] buffer */
2638        if (i->p && *i->p != '\0') {
2639                ch = (unsigned char)*i->p++;
2640                goto out;
2641        }
2642#endif
2643        /* peek_buf[] is an int array, not char. Can contain EOF. */
2644        ch = i->peek_buf[0];
2645        if (ch != 0) {
2646                int ch2 = i->peek_buf[1];
2647                i->peek_buf[0] = ch2;
2648                if (ch2 == 0) /* very likely, avoid redundant write */
2649                        goto out;
2650                i->peek_buf[1] = 0;
2651                goto out;
2652        }
2653
2654        ch = fgetc_interactive(i);
2655 out:
2656        debug_printf("file_get: got '%c' %d\n", ch, ch);
2657        i->last_char = ch;
2658#if ENABLE_HUSH_LINENO_VAR
2659        if (ch == '\n') {
2660                G.lineno++;
2661                debug_printf_parse("G.lineno++ = %u\n", G.lineno);
2662        }
2663#endif
2664        return ch;
2665}
2666
2667static int i_peek(struct in_str *i)
2668{
2669        int ch;
2670
2671        if (!i->file) {
2672                /* string-based in_str */
2673                /* Doesn't report EOF on NUL. None of the callers care. */
2674                return (unsigned char)*i->p;
2675        }
2676
2677        /* FILE-based in_str */
2678
2679#if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2680        /* This can be stdin, check line editing char[] buffer */
2681        if (i->p && *i->p != '\0')
2682                return (unsigned char)*i->p;
2683#endif
2684        /* peek_buf[] is an int array, not char. Can contain EOF. */
2685        ch = i->peek_buf[0];
2686        if (ch != 0)
2687                return ch;
2688
2689        /* Need to get a new char */
2690        ch = fgetc_interactive(i);
2691        debug_printf("file_peek: got '%c' %d\n", ch, ch);
2692
2693        /* Save it by either rolling back line editing buffer, or in i->peek_buf[0] */
2694#if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2695        if (i->p) {
2696                i->p -= 1;
2697                return ch;
2698        }
2699#endif
2700        i->peek_buf[0] = ch;
2701        /*i->peek_buf[1] = 0; - already is */
2702        return ch;
2703}
2704
2705/* Only ever called if i_peek() was called, and did not return EOF.
2706 * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
2707 * not end-of-line. Therefore we never need to read a new editing line here.
2708 */
2709static int i_peek2(struct in_str *i)
2710{
2711        int ch;
2712
2713        /* There are two cases when i->p[] buffer exists.
2714         * (1) it's a string in_str.
2715         * (2) It's a file, and we have a saved line editing buffer.
2716         * In both cases, we know that i->p[0] exists and not NUL, and
2717         * the peek2 result is in i->p[1].
2718         */
2719        if (i->p)
2720                return (unsigned char)i->p[1];
2721
2722        /* Now we know it is a file-based in_str. */
2723
2724        /* peek_buf[] is an int array, not char. Can contain EOF. */
2725        /* Is there 2nd char? */
2726        ch = i->peek_buf[1];
2727        if (ch == 0) {
2728                /* We did not read it yet, get it now */
2729                do ch = fgetc(i->file); while (ch == '\0');
2730                i->peek_buf[1] = ch;
2731        }
2732
2733        debug_printf("file_peek2: got '%c' %d\n", ch, ch);
2734        return ch;
2735}
2736
2737static int i_getch_and_eat_bkslash_nl(struct in_str *input)
2738{
2739        for (;;) {
2740                int ch, ch2;
2741
2742                ch = i_getch(input);
2743                if (ch != '\\')
2744                        return ch;
2745                ch2 = i_peek(input);
2746                if (ch2 != '\n')
2747                        return ch;
2748                /* backslash+newline, skip it */
2749                i_getch(input);
2750        }
2751}
2752
2753/* Note: this function _eats_ \<newline> pairs, safe to use plain
2754 * i_getch() after it instead of i_getch_and_eat_bkslash_nl().
2755 */
2756static int i_peek_and_eat_bkslash_nl(struct in_str *input)
2757{
2758        for (;;) {
2759                int ch, ch2;
2760
2761                ch = i_peek(input);
2762                if (ch != '\\')
2763                        return ch;
2764                ch2 = i_peek2(input);
2765                if (ch2 != '\n')
2766                        return ch;
2767                /* backslash+newline, skip it */
2768                i_getch(input);
2769                i_getch(input);
2770        }
2771}
2772
2773static void setup_file_in_str(struct in_str *i, FILE *f)
2774{
2775        memset(i, 0, sizeof(*i));
2776        i->file = f;
2777        /* i->p = NULL; */
2778}
2779
2780static void setup_string_in_str(struct in_str *i, const char *s)
2781{
2782        memset(i, 0, sizeof(*i));
2783        /*i->file = NULL */;
2784        i->p = s;
2785}
2786
2787
2788/*
2789 * o_string support
2790 */
2791#define B_CHUNK  (32 * sizeof(char*))
2792
2793static void o_reset_to_empty_unquoted(o_string *o)
2794{
2795        o->length = 0;
2796        o->has_quoted_part = 0;
2797        if (o->data)
2798                o->data[0] = '\0';
2799}
2800
2801static void o_free(o_string *o)
2802{
2803        free(o->data);
2804        memset(o, 0, sizeof(*o));
2805}
2806
2807static ALWAYS_INLINE void o_free_unsafe(o_string *o)
2808{
2809        free(o->data);
2810}
2811
2812static void o_grow_by(o_string *o, int len)
2813{
2814        if (o->length + len > o->maxlen) {
2815                o->maxlen += (2 * len) | (B_CHUNK-1);
2816                o->data = xrealloc(o->data, 1 + o->maxlen);
2817        }
2818}
2819
2820static void o_addchr(o_string *o, int ch)
2821{
2822        debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
2823        if (o->length < o->maxlen) {
2824                /* likely. avoid o_grow_by() call */
2825 add:
2826                o->data[o->length] = ch;
2827                o->length++;
2828                o->data[o->length] = '\0';
2829                return;
2830        }
2831        o_grow_by(o, 1);
2832        goto add;
2833}
2834
2835#if 0
2836/* Valid only if we know o_string is not empty */
2837static void o_delchr(o_string *o)
2838{
2839        o->length--;
2840        o->data[o->length] = '\0';
2841}
2842#endif
2843
2844static void o_addblock(o_string *o, const char *str, int len)
2845{
2846        o_grow_by(o, len);
2847        ((char*)mempcpy(&o->data[o->length], str, len))[0] = '\0';
2848        o->length += len;
2849}
2850
2851static void o_addstr(o_string *o, const char *str)
2852{
2853        o_addblock(o, str, strlen(str));
2854}
2855
2856#if !BB_MMU
2857static void nommu_addchr(o_string *o, int ch)
2858{
2859        if (o)
2860                o_addchr(o, ch);
2861}
2862#else
2863# define nommu_addchr(o, str) ((void)0)
2864#endif
2865
2866static void o_addstr_with_NUL(o_string *o, const char *str)
2867{
2868        o_addblock(o, str, strlen(str) + 1);
2869}
2870
2871/*
2872 * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side.
2873 * Currently, "v='{q,w}'; echo $v" erroneously expands braces in $v.
2874 * Apparently, on unquoted $v bash still does globbing
2875 * ("v='*.txt'; echo $v" prints all .txt files),
2876 * but NOT brace expansion! Thus, there should be TWO independent
2877 * quoting mechanisms on $v expansion side: one protects
2878 * $v from brace expansion, and other additionally protects "$v" against globbing.
2879 * We have only second one.
2880 */
2881
2882#if ENABLE_HUSH_BRACE_EXPANSION
2883# define MAYBE_BRACES "{}"
2884#else
2885# define MAYBE_BRACES ""
2886#endif
2887
2888/* My analysis of quoting semantics tells me that state information
2889 * is associated with a destination, not a source.
2890 */
2891static void o_addqchr(o_string *o, int ch)
2892{
2893        int sz = 1;
2894        char *found = strchr("*?[\\" MAYBE_BRACES, ch);
2895        if (found)
2896                sz++;
2897        o_grow_by(o, sz);
2898        if (found) {
2899                o->data[o->length] = '\\';
2900                o->length++;
2901        }
2902        o->data[o->length] = ch;
2903        o->length++;
2904        o->data[o->length] = '\0';
2905}
2906
2907static void o_addQchr(o_string *o, int ch)
2908{
2909        int sz = 1;
2910        if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)
2911         && strchr("*?[\\" MAYBE_BRACES, ch)
2912        ) {
2913                sz++;
2914                o->data[o->length] = '\\';
2915                o->length++;
2916        }
2917        o_grow_by(o, sz);
2918        o->data[o->length] = ch;
2919        o->length++;
2920        o->data[o->length] = '\0';
2921}
2922
2923static void o_addqblock(o_string *o, const char *str, int len)
2924{
2925        while (len) {
2926                char ch;
2927                int sz;
2928                int ordinary_cnt = strcspn(str, "*?[\\" MAYBE_BRACES);
2929                if (ordinary_cnt > len) /* paranoia */
2930                        ordinary_cnt = len;
2931                o_addblock(o, str, ordinary_cnt);
2932                if (ordinary_cnt == len)
2933                        return; /* NUL is already added by o_addblock */
2934                str += ordinary_cnt;
2935                len -= ordinary_cnt + 1; /* we are processing + 1 char below */
2936
2937                ch = *str++;
2938                sz = 1;
2939                if (ch) { /* it is necessarily one of "*?[\\" MAYBE_BRACES */
2940                        sz++;
2941                        o->data[o->length] = '\\';
2942                        o->length++;
2943                }
2944                o_grow_by(o, sz);
2945                o->data[o->length] = ch;
2946                o->length++;
2947        }
2948        o->data[o->length] = '\0';
2949}
2950
2951static void o_addQblock(o_string *o, const char *str, int len)
2952{
2953        if (!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)) {
2954                o_addblock(o, str, len);
2955                return;
2956        }
2957        o_addqblock(o, str, len);
2958}
2959
2960static void o_addQstr(o_string *o, const char *str)
2961{
2962        o_addQblock(o, str, strlen(str));
2963}
2964
2965/* A special kind of o_string for $VAR and `cmd` expansion.
2966 * It contains char* list[] at the beginning, which is grown in 16 element
2967 * increments. Actual string data starts at the next multiple of 16 * (char*).
2968 * list[i] contains an INDEX (int!) into this string data.
2969 * It means that if list[] needs to grow, data needs to be moved higher up
2970 * but list[i]'s need not be modified.
2971 * NB: remembering how many list[i]'s you have there is crucial.
2972 * o_finalize_list() operation post-processes this structure - calculates
2973 * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
2974 */
2975#if DEBUG_EXPAND || DEBUG_GLOB
2976static void debug_print_list(const char *prefix, o_string *o, int n)
2977{
2978        char **list = (char**)o->data;
2979        int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
2980        int i = 0;
2981
2982        indent();
2983        fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
2984                        prefix, list, n, string_start, o->length, o->maxlen,
2985                        !!(o->o_expflags & EXP_FLAG_GLOB),
2986                        o->has_quoted_part,
2987                        !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
2988        while (i < n) {
2989                indent();
2990                fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i],
2991                                o->data + (int)(uintptr_t)list[i] + string_start,
2992                                o->data + (int)(uintptr_t)list[i] + string_start);
2993                i++;
2994        }
2995        if (n) {
2996                const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start;
2997                indent();
2998                fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
2999        }
3000}
3001#else
3002# define debug_print_list(prefix, o, n) ((void)0)
3003#endif
3004
3005/* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
3006 * in list[n] so that it points past last stored byte so far.
3007 * It returns n+1. */
3008static int o_save_ptr_helper(o_string *o, int n)
3009{
3010        char **list = (char**)o->data;
3011        int string_start;
3012        int string_len;
3013
3014        if (!o->has_empty_slot) {
3015                string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3016                string_len = o->length - string_start;
3017                if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */
3018                        debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start);
3019                        /* list[n] points to string_start, make space for 16 more pointers */
3020                        o->maxlen += 0x10 * sizeof(list[0]);
3021                        o->data = xrealloc(o->data, o->maxlen + 1);
3022                        list = (char**)o->data;
3023                        memmove(list + n + 0x10, list + n, string_len);
3024                        o->length += 0x10 * sizeof(list[0]);
3025                } else {
3026                        debug_printf_list("list[%d]=%d string_start=%d\n",
3027                                        n, string_len, string_start);
3028                }
3029        } else {
3030                /* We have empty slot at list[n], reuse without growth */
3031                string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
3032                string_len = o->length - string_start;
3033                debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
3034                                n, string_len, string_start);
3035                o->has_empty_slot = 0;
3036        }
3037        o->has_quoted_part = 0;
3038        list[n] = (char*)(uintptr_t)string_len;
3039        return n + 1;
3040}
3041
3042/* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
3043static int o_get_last_ptr(o_string *o, int n)
3044{
3045        char **list = (char**)o->data;
3046        int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3047
3048        return ((int)(uintptr_t)list[n-1]) + string_start;
3049}
3050
3051#if ENABLE_HUSH_BRACE_EXPANSION
3052/* There in a GNU extension, GLOB_BRACE, but it is not usable:
3053 * first, it processes even {a} (no commas), second,
3054 * I didn't manage to make it return strings when they don't match
3055 * existing files. Need to re-implement it.
3056 */
3057
3058/* Helper */
3059static int glob_needed(const char *s)
3060{
3061        while (*s) {
3062                if (*s == '\\') {
3063                        if (!s[1])
3064                                return 0;
3065                        s += 2;
3066                        continue;
3067                }
3068                if (*s == '*' || *s == '[' || *s == '?' || *s == '{')
3069                        return 1;
3070                s++;
3071        }
3072        return 0;
3073}
3074/* Return pointer to next closing brace or to comma */
3075static const char *next_brace_sub(const char *cp)
3076{
3077        unsigned depth = 0;
3078        cp++;
3079        while (*cp != '\0') {
3080                if (*cp == '\\') {
3081                        if (*++cp == '\0')
3082                                break;
3083                        cp++;
3084                        continue;
3085                }
3086                if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
3087                        break;
3088                if (*cp++ == '{')
3089                        depth++;
3090        }
3091
3092        return *cp != '\0' ? cp : NULL;
3093}
3094/* Recursive brace globber. Note: may garble pattern[]. */
3095static int glob_brace(char *pattern, o_string *o, int n)
3096{
3097        char *new_pattern_buf;
3098        const char *begin;
3099        const char *next;
3100        const char *rest;
3101        const char *p;
3102        size_t rest_len;
3103
3104        debug_printf_glob("glob_brace('%s')\n", pattern);
3105
3106        begin = pattern;
3107        while (1) {
3108                if (*begin == '\0')
3109                        goto simple_glob;
3110                if (*begin == '{') {
3111                        /* Find the first sub-pattern and at the same time
3112                         * find the rest after the closing brace */
3113                        next = next_brace_sub(begin);
3114                        if (next == NULL) {
3115                                /* An illegal expression */
3116                                goto simple_glob;
3117                        }
3118                        if (*next == '}') {
3119                                /* "{abc}" with no commas - illegal
3120                                 * brace expr, disregard and skip it */
3121                                begin = next + 1;
3122                                continue;
3123                        }
3124                        break;
3125                }
3126                if (*begin == '\\' && begin[1] != '\0')
3127                        begin++;
3128                begin++;
3129        }
3130        debug_printf_glob("begin:%s\n", begin);
3131        debug_printf_glob("next:%s\n", next);
3132
3133        /* Now find the end of the whole brace expression */
3134        rest = next;
3135        while (*rest != '}') {
3136                rest = next_brace_sub(rest);
3137                if (rest == NULL) {
3138                        /* An illegal expression */
3139                        goto simple_glob;
3140                }
3141                debug_printf_glob("rest:%s\n", rest);
3142        }
3143        rest_len = strlen(++rest) + 1;
3144
3145        /* We are sure the brace expression is well-formed */
3146
3147        /* Allocate working buffer large enough for our work */
3148        new_pattern_buf = xmalloc(strlen(pattern));
3149
3150        /* We have a brace expression.  BEGIN points to the opening {,
3151         * NEXT points past the terminator of the first element, and REST
3152         * points past the final }.  We will accumulate result names from
3153         * recursive runs for each brace alternative in the buffer using
3154         * GLOB_APPEND.  */
3155
3156        p = begin + 1;
3157        while (1) {
3158                /* Construct the new glob expression */
3159                memcpy(
3160                        mempcpy(
3161                                mempcpy(new_pattern_buf,
3162                                        /* We know the prefix for all sub-patterns */
3163                                        pattern, begin - pattern),
3164                                p, next - p),
3165                        rest, rest_len);
3166
3167                /* Note: glob_brace() may garble new_pattern_buf[].
3168                 * That's why we re-copy prefix every time (1st memcpy above).
3169                 */
3170                n = glob_brace(new_pattern_buf, o, n);
3171                if (*next == '}') {
3172                        /* We saw the last entry */
3173                        break;
3174                }
3175                p = next + 1;
3176                next = next_brace_sub(next);
3177        }
3178        free(new_pattern_buf);
3179        return n;
3180
3181 simple_glob:
3182        {
3183                int gr;
3184                glob_t globdata;
3185
3186                memset(&globdata, 0, sizeof(globdata));
3187                gr = glob(pattern, 0, NULL, &globdata);
3188                debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3189                if (gr != 0) {
3190                        if (gr == GLOB_NOMATCH) {
3191                                globfree(&globdata);
3192                                /* NB: garbles parameter */
3193                                unbackslash(pattern);
3194                                o_addstr_with_NUL(o, pattern);
3195                                debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3196                                return o_save_ptr_helper(o, n);
3197                        }
3198                        if (gr == GLOB_NOSPACE)
3199                                bb_die_memory_exhausted();
3200                        /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3201                         * but we didn't specify it. Paranoia again. */
3202                        bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3203                }
3204                if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3205                        char **argv = globdata.gl_pathv;
3206                        while (1) {
3207                                o_addstr_with_NUL(o, *argv);
3208                                n = o_save_ptr_helper(o, n);
3209                                argv++;
3210                                if (!*argv)
3211                                        break;
3212                        }
3213                }
3214                globfree(&globdata);
3215        }
3216        return n;
3217}
3218/* Performs globbing on last list[],
3219 * saving each result as a new list[].
3220 */
3221static int perform_glob(o_string *o, int n)
3222{
3223        char *pattern, *copy;
3224
3225        debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3226        if (!o->data)
3227                return o_save_ptr_helper(o, n);
3228        pattern = o->data + o_get_last_ptr(o, n);
3229        debug_printf_glob("glob pattern '%s'\n", pattern);
3230        if (!glob_needed(pattern)) {
3231                /* unbackslash last string in o in place, fix length */
3232                o->length = unbackslash(pattern) - o->data;
3233                debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3234                return o_save_ptr_helper(o, n);
3235        }
3236
3237        copy = xstrdup(pattern);
3238        /* "forget" pattern in o */
3239        o->length = pattern - o->data;
3240        n = glob_brace(copy, o, n);
3241        free(copy);
3242        if (DEBUG_GLOB)
3243                debug_print_list("perform_glob returning", o, n);
3244        return n;
3245}
3246
3247#else /* !HUSH_BRACE_EXPANSION */
3248
3249/* Helper */
3250static int glob_needed(const char *s)
3251{
3252        while (*s) {
3253                if (*s == '\\') {
3254                        if (!s[1])
3255                                return 0;
3256                        s += 2;
3257                        continue;
3258                }
3259                if (*s == '*' || *s == '[' || *s == '?')
3260                        return 1;
3261                s++;
3262        }
3263        return 0;
3264}
3265/* Performs globbing on last list[],
3266 * saving each result as a new list[].
3267 */
3268static int perform_glob(o_string *o, int n)
3269{
3270        glob_t globdata;
3271        int gr;
3272        char *pattern;
3273
3274        debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3275        if (!o->data)
3276                return o_save_ptr_helper(o, n);
3277        pattern = o->data + o_get_last_ptr(o, n);
3278        debug_printf_glob("glob pattern '%s'\n", pattern);
3279        if (!glob_needed(pattern)) {
3280 literal:
3281                /* unbackslash last string in o in place, fix length */
3282                o->length = unbackslash(pattern) - o->data;
3283                debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3284                return o_save_ptr_helper(o, n);
3285        }
3286
3287        memset(&globdata, 0, sizeof(globdata));
3288        /* Can't use GLOB_NOCHECK: it does not unescape the string.
3289         * If we glob "*.\*" and don't find anything, we need
3290         * to fall back to using literal "*.*", but GLOB_NOCHECK
3291         * will return "*.\*"!
3292         */
3293        gr = glob(pattern, 0, NULL, &globdata);
3294        debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3295        if (gr != 0) {
3296                if (gr == GLOB_NOMATCH) {
3297                        globfree(&globdata);
3298                        goto literal;
3299                }
3300                if (gr == GLOB_NOSPACE)
3301                        bb_die_memory_exhausted();
3302                /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3303                 * but we didn't specify it. Paranoia again. */
3304                bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3305        }
3306        if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3307                char **argv = globdata.gl_pathv;
3308                /* "forget" pattern in o */
3309                o->length = pattern - o->data;
3310                while (1) {
3311                        o_addstr_with_NUL(o, *argv);
3312                        n = o_save_ptr_helper(o, n);
3313                        argv++;
3314                        if (!*argv)
3315                                break;
3316                }
3317        }
3318        globfree(&globdata);
3319        if (DEBUG_GLOB)
3320                debug_print_list("perform_glob returning", o, n);
3321        return n;
3322}
3323
3324#endif /* !HUSH_BRACE_EXPANSION */
3325
3326/* If o->o_expflags & EXP_FLAG_GLOB, glob the string so far remembered.
3327 * Otherwise, just finish current list[] and start new */
3328static int o_save_ptr(o_string *o, int n)
3329{
3330        if (o->o_expflags & EXP_FLAG_GLOB) {
3331                /* If o->has_empty_slot, list[n] was already globbed
3332                 * (if it was requested back then when it was filled)
3333                 * so don't do that again! */
3334                if (!o->has_empty_slot)
3335                        return perform_glob(o, n); /* o_save_ptr_helper is inside */
3336        }
3337        return o_save_ptr_helper(o, n);
3338}
3339
3340/* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
3341static char **o_finalize_list(o_string *o, int n)
3342{
3343        char **list;
3344        int string_start;
3345
3346        n = o_save_ptr(o, n); /* force growth for list[n] if necessary */
3347        if (DEBUG_EXPAND)
3348                debug_print_list("finalized", o, n);
3349        debug_printf_expand("finalized n:%d\n", n);
3350        list = (char**)o->data;
3351        string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3352        list[--n] = NULL;
3353        while (n) {
3354                n--;
3355                list[n] = o->data + (int)(uintptr_t)list[n] + string_start;
3356        }
3357        return list;
3358}
3359
3360static void free_pipe_list(struct pipe *pi);
3361
3362/* Returns pi->next - next pipe in the list */
3363static struct pipe *free_pipe(struct pipe *pi)
3364{
3365        struct pipe *next;
3366        int i;
3367
3368        debug_printf_clean("free_pipe (pid %d)\n", getpid());
3369        for (i = 0; i < pi->num_cmds; i++) {
3370                struct command *command;
3371                struct redir_struct *r, *rnext;
3372
3373                command = &pi->cmds[i];
3374                debug_printf_clean("  command %d:\n", i);
3375                if (command->argv) {
3376                        if (DEBUG_CLEAN) {
3377                                int a;
3378                                char **p;
3379                                for (a = 0, p = command->argv; *p; a++, p++) {
3380                                        debug_printf_clean("   argv[%d] = %s\n", a, *p);
3381                                }
3382                        }
3383                        free_strings(command->argv);
3384                        //command->argv = NULL;
3385                }
3386                /* not "else if": on syntax error, we may have both! */
3387                if (command->group) {
3388                        debug_printf_clean("   begin group (cmd_type:%d)\n",
3389                                        command->cmd_type);
3390                        free_pipe_list(command->group);
3391                        debug_printf_clean("   end group\n");
3392                        //command->group = NULL;
3393                }
3394                /* else is crucial here.
3395                 * If group != NULL, child_func is meaningless */
3396#if ENABLE_HUSH_FUNCTIONS
3397                else if (command->child_func) {
3398                        debug_printf_exec("cmd %p releases child func at %p\n", command, command->child_func);
3399                        command->child_func->parent_cmd = NULL;
3400                }
3401#endif
3402#if !BB_MMU
3403                free(command->group_as_string);
3404                //command->group_as_string = NULL;
3405#endif
3406                for (r = command->redirects; r; r = rnext) {
3407                        debug_printf_clean("   redirect %d%s",
3408                                        r->rd_fd, redir_table[r->rd_type].descrip);
3409                        /* guard against the case >$FOO, where foo is unset or blank */
3410                        if (r->rd_filename) {
3411                                debug_printf_clean(" fname:'%s'\n", r->rd_filename);
3412                                free(r->rd_filename);
3413                                //r->rd_filename = NULL;
3414                        }
3415                        debug_printf_clean(" rd_dup:%d\n", r->rd_dup);
3416                        rnext = r->next;
3417                        free(r);
3418                }
3419                //command->redirects = NULL;
3420        }
3421        free(pi->cmds);   /* children are an array, they get freed all at once */
3422        //pi->cmds = NULL;
3423#if ENABLE_HUSH_JOB
3424        free(pi->cmdtext);
3425        //pi->cmdtext = NULL;
3426#endif
3427
3428        next = pi->next;
3429        free(pi);
3430        return next;
3431}
3432
3433static void free_pipe_list(struct pipe *pi)
3434{
3435        while (pi) {
3436#if HAS_KEYWORDS
3437                debug_printf_clean("pipe reserved word %d\n", pi->res_word);
3438#endif
3439                debug_printf_clean("pipe followup code %d\n", pi->followup);
3440                pi = free_pipe(pi);
3441        }
3442}
3443
3444
3445/*** Parsing routines ***/
3446
3447#ifndef debug_print_tree
3448static void debug_print_tree(struct pipe *pi, int lvl)
3449{
3450        static const char *const PIPE[] = {
3451                [PIPE_SEQ] = "SEQ",
3452                [PIPE_AND] = "AND",
3453                [PIPE_OR ] = "OR" ,
3454                [PIPE_BG ] = "BG" ,
3455        };
3456        static const char *RES[] = {
3457                [RES_NONE ] = "NONE" ,
3458# if ENABLE_HUSH_IF
3459                [RES_IF   ] = "IF"   ,
3460                [RES_THEN ] = "THEN" ,
3461                [RES_ELIF ] = "ELIF" ,
3462                [RES_ELSE ] = "ELSE" ,
3463                [RES_FI   ] = "FI"   ,
3464# endif
3465# if ENABLE_HUSH_LOOPS
3466                [RES_FOR  ] = "FOR"  ,
3467                [RES_WHILE] = "WHILE",
3468                [RES_UNTIL] = "UNTIL",
3469                [RES_DO   ] = "DO"   ,
3470                [RES_DONE ] = "DONE" ,
3471# endif
3472# if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
3473                [RES_IN   ] = "IN"   ,
3474# endif
3475# if ENABLE_HUSH_CASE
3476                [RES_CASE ] = "CASE" ,
3477                [RES_CASE_IN ] = "CASE_IN" ,
3478                [RES_MATCH] = "MATCH",
3479                [RES_CASE_BODY] = "CASE_BODY",
3480                [RES_ESAC ] = "ESAC" ,
3481# endif
3482                [RES_XXXX ] = "XXXX" ,
3483                [RES_SNTX ] = "SNTX" ,
3484        };
3485        static const char *const CMDTYPE[] = {
3486                "{}",
3487                "()",
3488                "[noglob]",
3489# if ENABLE_HUSH_FUNCTIONS
3490                "func()",
3491# endif
3492        };
3493
3494        int pin, prn;
3495
3496        pin = 0;
3497        while (pi) {
3498                fdprintf(2, "%*spipe %d %sres_word=%s followup=%d %s\n",
3499                                lvl*2, "",
3500                                pin,
3501                                (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""),
3502                                RES[pi->res_word],
3503                                pi->followup, PIPE[pi->followup]
3504                );
3505                prn = 0;
3506                while (prn < pi->num_cmds) {
3507                        struct command *command = &pi->cmds[prn];
3508                        char **argv = command->argv;
3509
3510                        fdprintf(2, "%*s cmd %d assignment_cnt:%d",
3511                                        lvl*2, "", prn,
3512                                        command->assignment_cnt);
3513#if ENABLE_HUSH_LINENO_VAR
3514                        fdprintf(2, " LINENO:%u", command->lineno);
3515#endif
3516                        if (command->group) {
3517                                fdprintf(2, " group %s: (argv=%p)%s%s\n",
3518                                                CMDTYPE[command->cmd_type],
3519                                                argv
3520# if !BB_MMU
3521                                                , " group_as_string:", command->group_as_string
3522# else
3523                                                , "", ""
3524# endif
3525                                );
3526                                debug_print_tree(command->group, lvl+1);
3527                                prn++;
3528                                continue;
3529                        }
3530                        if (argv) while (*argv) {
3531                                fdprintf(2, " '%s'", *argv);
3532                                argv++;
3533                        }
3534                        fdprintf(2, "\n");
3535                        prn++;
3536                }
3537                pi = pi->next;
3538                pin++;
3539        }
3540}
3541#endif /* debug_print_tree */
3542
3543static struct pipe *new_pipe(void)
3544{
3545        struct pipe *pi;
3546        pi = xzalloc(sizeof(struct pipe));
3547        /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
3548        return pi;
3549}
3550
3551/* Command (member of a pipe) is complete, or we start a new pipe
3552 * if ctx->command is NULL.
3553 * No errors possible here.
3554 */
3555static int done_command(struct parse_context *ctx)
3556{
3557        /* The command is really already in the pipe structure, so
3558         * advance the pipe counter and make a new, null command. */
3559        struct pipe *pi = ctx->pipe;
3560        struct command *command = ctx->command;
3561
3562#if 0   /* Instead we emit error message at run time */
3563        if (ctx->pending_redirect) {
3564                /* For example, "cmd >" (no filename to redirect to) */
3565                syntax_error("invalid redirect");
3566                ctx->pending_redirect = NULL;
3567        }
3568#endif
3569
3570        if (command) {
3571                if (IS_NULL_CMD(command)) {
3572                        debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
3573                        goto clear_and_ret;
3574                }
3575                pi->num_cmds++;
3576                debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
3577                //debug_print_tree(ctx->list_head, 20);
3578        } else {
3579                debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
3580        }
3581
3582        /* Only real trickiness here is that the uncommitted
3583         * command structure is not counted in pi->num_cmds. */
3584        pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1));
3585        ctx->command = command = &pi->cmds[pi->num_cmds];
3586 clear_and_ret:
3587        memset(command, 0, sizeof(*command));
3588#if ENABLE_HUSH_LINENO_VAR
3589        command->lineno = G.lineno;
3590        debug_printf_parse("command->lineno = G.lineno (%u)\n", G.lineno);
3591#endif
3592        return pi->num_cmds; /* used only for 0/nonzero check */
3593}
3594
3595static void done_pipe(struct parse_context *ctx, pipe_style type)
3596{
3597        int not_null;
3598
3599        debug_printf_parse("done_pipe entered, followup %d\n", type);
3600        /* Close previous command */
3601        not_null = done_command(ctx);
3602#if HAS_KEYWORDS
3603        ctx->pipe->pi_inverted = ctx->ctx_inverted;
3604        ctx->ctx_inverted = 0;
3605        ctx->pipe->res_word = ctx->ctx_res_w;
3606#endif
3607        if (type == PIPE_BG && ctx->list_head != ctx->pipe) {
3608                /* Necessary since && and || have precedence over &:
3609                 * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2,
3610                 * in a backgrounded subshell.
3611                 */
3612                struct pipe *pi;
3613                struct command *command;
3614
3615                /* Is this actually this construct, all pipes end with && or ||? */
3616                pi = ctx->list_head;
3617                while (pi != ctx->pipe) {
3618                        if (pi->followup != PIPE_AND && pi->followup != PIPE_OR)
3619                                goto no_conv;
3620                        pi = pi->next;
3621                }
3622
3623                debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n");
3624                pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */
3625                pi = xzalloc(sizeof(*pi));
3626                pi->followup = PIPE_BG;
3627                pi->num_cmds = 1;
3628                pi->cmds = xzalloc(sizeof(pi->cmds[0]));
3629                command = &pi->cmds[0];
3630                if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */
3631                        command->cmd_type = CMD_NORMAL;
3632                command->group = ctx->list_head;
3633#if !BB_MMU
3634                command->group_as_string = xstrndup(
3635                            ctx->as_string.data,
3636                            ctx->as_string.length - 1 /* do not copy last char, "&" */
3637                );
3638#endif
3639                /* Replace all pipes in ctx with one newly created */
3640                ctx->list_head = ctx->pipe = pi;
3641        } else {
3642 no_conv:
3643                ctx->pipe->followup = type;
3644        }
3645
3646        /* Without this check, even just <enter> on command line generates
3647         * tree of three NOPs (!). Which is harmless but annoying.
3648         * IOW: it is safe to do it unconditionally. */
3649        if (not_null
3650#if ENABLE_HUSH_IF
3651         || ctx->ctx_res_w == RES_FI
3652#endif
3653#if ENABLE_HUSH_LOOPS
3654         || ctx->ctx_res_w == RES_DONE
3655         || ctx->ctx_res_w == RES_FOR
3656         || ctx->ctx_res_w == RES_IN
3657#endif
3658#if ENABLE_HUSH_CASE
3659         || ctx->ctx_res_w == RES_ESAC
3660#endif
3661        ) {
3662                struct pipe *new_p;
3663                debug_printf_parse("done_pipe: adding new pipe: "
3664                                "not_null:%d ctx->ctx_res_w:%d\n",
3665                                not_null, ctx->ctx_res_w);
3666                new_p = new_pipe();
3667                ctx->pipe->next = new_p;
3668                ctx->pipe = new_p;
3669                /* RES_THEN, RES_DO etc are "sticky" -
3670                 * they remain set for pipes inside if/while.
3671                 * This is used to control execution.
3672                 * RES_FOR and RES_IN are NOT sticky (needed to support
3673                 * cases where variable or value happens to match a keyword):
3674                 */
3675#if ENABLE_HUSH_LOOPS
3676                if (ctx->ctx_res_w == RES_FOR
3677                 || ctx->ctx_res_w == RES_IN)
3678                        ctx->ctx_res_w = RES_NONE;
3679#endif
3680#if ENABLE_HUSH_CASE
3681                if (ctx->ctx_res_w == RES_MATCH)
3682                        ctx->ctx_res_w = RES_CASE_BODY;
3683                if (ctx->ctx_res_w == RES_CASE)
3684                        ctx->ctx_res_w = RES_CASE_IN;
3685#endif
3686                ctx->command = NULL; /* trick done_command below */
3687                /* Create the memory for command, roughly:
3688                 * ctx->pipe->cmds = new struct command;
3689                 * ctx->command = &ctx->pipe->cmds[0];
3690                 */
3691                done_command(ctx);
3692                //debug_print_tree(ctx->list_head, 10);
3693        }
3694        debug_printf_parse("done_pipe return\n");
3695}
3696
3697static void initialize_context(struct parse_context *ctx)
3698{
3699        memset(ctx, 0, sizeof(*ctx));
3700        if (MAYBE_ASSIGNMENT != 0)
3701                ctx->is_assignment = MAYBE_ASSIGNMENT;
3702        ctx->pipe = ctx->list_head = new_pipe();
3703        /* Create the memory for command, roughly:
3704         * ctx->pipe->cmds = new struct command;
3705         * ctx->command = &ctx->pipe->cmds[0];
3706         */
3707        done_command(ctx);
3708}
3709
3710/* If a reserved word is found and processed, parse context is modified
3711 * and 1 is returned.
3712 */
3713#if HAS_KEYWORDS
3714struct reserved_combo {
3715        char literal[6];
3716        unsigned char res;
3717        unsigned char assignment_flag;
3718        int flag;
3719};
3720enum {
3721        FLAG_END   = (1 << RES_NONE ),
3722# if ENABLE_HUSH_IF
3723        FLAG_IF    = (1 << RES_IF   ),
3724        FLAG_THEN  = (1 << RES_THEN ),
3725        FLAG_ELIF  = (1 << RES_ELIF ),
3726        FLAG_ELSE  = (1 << RES_ELSE ),
3727        FLAG_FI    = (1 << RES_FI   ),
3728# endif
3729# if ENABLE_HUSH_LOOPS
3730        FLAG_FOR   = (1 << RES_FOR  ),
3731        FLAG_WHILE = (1 << RES_WHILE),
3732        FLAG_UNTIL = (1 << RES_UNTIL),
3733        FLAG_DO    = (1 << RES_DO   ),
3734        FLAG_DONE  = (1 << RES_DONE ),
3735        FLAG_IN    = (1 << RES_IN   ),
3736# endif
3737# if ENABLE_HUSH_CASE
3738        FLAG_MATCH = (1 << RES_MATCH),
3739        FLAG_ESAC  = (1 << RES_ESAC ),
3740# endif
3741        FLAG_START = (1 << RES_XXXX ),
3742};
3743
3744static const struct reserved_combo* match_reserved_word(o_string *word)
3745{
3746        /* Mostly a list of accepted follow-up reserved words.
3747         * FLAG_END means we are done with the sequence, and are ready
3748         * to turn the compound list into a command.
3749         * FLAG_START means the word must start a new compound list.
3750         */
3751        static const struct reserved_combo reserved_list[] = {
3752# if ENABLE_HUSH_IF
3753                { "!",     RES_NONE,  NOT_ASSIGNMENT  , 0 },
3754                { "if",    RES_IF,    MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START },
3755                { "then",  RES_THEN,  MAYBE_ASSIGNMENT, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
3756                { "elif",  RES_ELIF,  MAYBE_ASSIGNMENT, FLAG_THEN },
3757                { "else",  RES_ELSE,  MAYBE_ASSIGNMENT, FLAG_FI   },
3758                { "fi",    RES_FI,    NOT_ASSIGNMENT  , FLAG_END  },
3759# endif
3760# if ENABLE_HUSH_LOOPS
3761                { "for",   RES_FOR,   NOT_ASSIGNMENT  , FLAG_IN | FLAG_DO | FLAG_START },
3762                { "while", RES_WHILE, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3763                { "until", RES_UNTIL, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3764                { "in",    RES_IN,    NOT_ASSIGNMENT  , FLAG_DO   },
3765                { "do",    RES_DO,    MAYBE_ASSIGNMENT, FLAG_DONE },
3766                { "done",  RES_DONE,  NOT_ASSIGNMENT  , FLAG_END  },
3767# endif
3768# if ENABLE_HUSH_CASE
3769                { "case",  RES_CASE,  NOT_ASSIGNMENT  , FLAG_MATCH | FLAG_START },
3770                { "esac",  RES_ESAC,  NOT_ASSIGNMENT  , FLAG_END  },
3771# endif
3772        };
3773        const struct reserved_combo *r;
3774
3775        for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
3776                if (strcmp(word->data, r->literal) == 0)
3777                        return r;
3778        }
3779        return NULL;
3780}
3781/* Return NULL: not a keyword, else: keyword
3782 */
3783static const struct reserved_combo* reserved_word(struct parse_context *ctx)
3784{
3785# if ENABLE_HUSH_CASE
3786        static const struct reserved_combo reserved_match = {
3787                "",        RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC
3788        };
3789# endif
3790        const struct reserved_combo *r;
3791
3792        if (ctx->word.has_quoted_part)
3793                return 0;
3794        r = match_reserved_word(&ctx->word);
3795        if (!r)
3796                return r; /* NULL */
3797
3798        debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
3799# if ENABLE_HUSH_CASE
3800        if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE_IN) {
3801                /* "case word IN ..." - IN part starts first MATCH part */
3802                r = &reserved_match;
3803        } else
3804# endif
3805        if (r->flag == 0) { /* '!' */
3806                if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */
3807                        syntax_error("! ! command");
3808                        ctx->ctx_res_w = RES_SNTX;
3809                }
3810                ctx->ctx_inverted = 1;
3811                return r;
3812        }
3813        if (r->flag & FLAG_START) {
3814                struct parse_context *old;
3815
3816                old = xmemdup(ctx, sizeof(*ctx));
3817                debug_printf_parse("push stack %p\n", old);
3818                initialize_context(ctx);
3819                ctx->stack = old;
3820        } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
3821                syntax_error_at(ctx->word.data);
3822                ctx->ctx_res_w = RES_SNTX;
3823                return r;
3824        } else {
3825                /* "{...} fi" is ok. "{...} if" is not
3826                 * Example:
3827                 * if { echo foo; } then { echo bar; } fi */
3828                if (ctx->command->group)
3829                        done_pipe(ctx, PIPE_SEQ);
3830        }
3831
3832        ctx->ctx_res_w = r->res;
3833        ctx->old_flag = r->flag;
3834        ctx->is_assignment = r->assignment_flag;
3835        debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
3836
3837        if (ctx->old_flag & FLAG_END) {
3838                struct parse_context *old;
3839
3840                done_pipe(ctx, PIPE_SEQ);
3841                debug_printf_parse("pop stack %p\n", ctx->stack);
3842                old = ctx->stack;
3843                old->command->group = ctx->list_head;
3844                old->command->cmd_type = CMD_NORMAL;
3845# if !BB_MMU
3846                /* At this point, the compound command's string is in
3847                 * ctx->as_string... except for the leading keyword!
3848                 * Consider this example: "echo a | if true; then echo a; fi"
3849                 * ctx->as_string will contain "true; then echo a; fi",
3850                 * with "if " remaining in old->as_string!
3851                 */
3852                {
3853                        char *str;
3854                        int len = old->as_string.length;
3855                        /* Concatenate halves */
3856                        o_addstr(&old->as_string, ctx->as_string.data);
3857                        o_free_unsafe(&ctx->as_string);
3858                        /* Find where leading keyword starts in first half */
3859                        str = old->as_string.data + len;
3860                        if (str > old->as_string.data)
3861                                str--; /* skip whitespace after keyword */
3862                        while (str > old->as_string.data && isalpha(str[-1]))
3863                                str--;
3864                        /* Ugh, we're done with this horrid hack */
3865                        old->command->group_as_string = xstrdup(str);
3866                        debug_printf_parse("pop, remembering as:'%s'\n",
3867                                        old->command->group_as_string);
3868                }
3869# endif
3870                *ctx = *old;   /* physical copy */
3871                free(old);
3872        }
3873        return r;
3874}
3875#endif /* HAS_KEYWORDS */
3876
3877/* Word is complete, look at it and update parsing context.
3878 * Normal return is 0. Syntax errors return 1.
3879 * Note: on return, word is reset, but not o_free'd!
3880 */
3881static int done_word(struct parse_context *ctx)
3882{
3883        struct command *command = ctx->command;
3884
3885        debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command);
3886        if (ctx->word.length == 0 && !ctx->word.has_quoted_part) {
3887                debug_printf_parse("done_word return 0: true null, ignored\n");
3888                return 0;
3889        }
3890
3891        if (ctx->pending_redirect) {
3892                /* We do not glob in e.g. >*.tmp case. bash seems to glob here
3893                 * only if run as "bash", not "sh" */
3894                /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
3895                 * "2.7 Redirection
3896                 * If the redirection operator is "<<" or "<<-", the word
3897                 * that follows the redirection operator shall be
3898                 * subjected to quote removal; it is unspecified whether
3899                 * any of the other expansions occur. For the other
3900                 * redirection operators, the word that follows the
3901                 * redirection operator shall be subjected to tilde
3902                 * expansion, parameter expansion, command substitution,
3903                 * arithmetic expansion, and quote removal.
3904                 * Pathname expansion shall not be performed
3905                 * on the word by a non-interactive shell; an interactive
3906                 * shell may perform it, but shall do so only when
3907                 * the expansion would result in one word."
3908                 */
3909//bash does not do parameter/command substitution or arithmetic expansion
3910//for _heredoc_ redirection word: these constructs look for exact eof marker
3911// as written:
3912// <<EOF$t
3913// <<EOF$((1))
3914// <<EOF`true`  [this case also makes heredoc "quoted", a-la <<"EOF". Probably bash-4.3.43 bug]
3915
3916                ctx->pending_redirect->rd_filename = xstrdup(ctx->word.data);
3917                /* Cater for >\file case:
3918                 * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
3919                 * Same with heredocs:
3920                 * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
3921                 */
3922                if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
3923                        unbackslash(ctx->pending_redirect->rd_filename);
3924                        /* Is it <<"HEREDOC"? */
3925                        if (ctx->word.has_quoted_part) {
3926                                ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
3927                        }
3928                }
3929                debug_printf_parse("word stored in rd_filename: '%s'\n", ctx->word.data);
3930                ctx->pending_redirect = NULL;
3931        } else {
3932#if HAS_KEYWORDS
3933# if ENABLE_HUSH_CASE
3934                if (ctx->ctx_dsemicolon
3935                 && strcmp(ctx->word.data, "esac") != 0 /* not "... pattern) cmd;; esac" */
3936                ) {
3937                        /* already done when ctx_dsemicolon was set to 1: */
3938                        /* ctx->ctx_res_w = RES_MATCH; */
3939                        ctx->ctx_dsemicolon = 0;
3940                } else
3941# endif
3942                if (!command->argv /* if it's the first word... */
3943# if ENABLE_HUSH_LOOPS
3944                 && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */
3945                 && ctx->ctx_res_w != RES_IN
3946# endif
3947# if ENABLE_HUSH_CASE
3948                 && ctx->ctx_res_w != RES_CASE
3949# endif
3950                ) {
3951                        const struct reserved_combo *reserved;
3952                        reserved = reserved_word(ctx);
3953                        debug_printf_parse("checking for reserved-ness: %d\n", !!reserved);
3954                        if (reserved) {
3955# if ENABLE_HUSH_LINENO_VAR
3956/* Case:
3957 * "while ...; do
3958 *      cmd ..."
3959 * If we don't close the pipe _now_, immediately after "do", lineno logic
3960 * sees "cmd" as starting at "do" - i.e., at the previous line.
3961 */
3962                                if (0
3963                                 IF_HUSH_IF(|| reserved->res == RES_THEN)
3964                                 IF_HUSH_IF(|| reserved->res == RES_ELIF)
3965                                 IF_HUSH_IF(|| reserved->res == RES_ELSE)
3966                                 IF_HUSH_LOOPS(|| reserved->res == RES_DO)
3967                                ) {
3968                                        done_pipe(ctx, PIPE_SEQ);
3969                                }
3970# endif
3971                                o_reset_to_empty_unquoted(&ctx->word);
3972                                debug_printf_parse("done_word return %d\n",
3973                                                (ctx->ctx_res_w == RES_SNTX));
3974                                return (ctx->ctx_res_w == RES_SNTX);
3975                        }
3976# if defined(CMD_SINGLEWORD_NOGLOB)
3977                        if (0
3978#  if BASH_TEST2
3979                         || strcmp(ctx->word.data, "[[") == 0
3980#  endif
3981                        /* In bash, local/export/readonly are special, args
3982                         * are assignments and therefore expansion of them
3983                         * should be "one-word" expansion:
3984                         *  $ export i=`echo 'a  b'` # one arg: "i=a  b"
3985                         * compare with:
3986                         *  $ ls i=`echo 'a  b'`     # two args: "i=a" and "b"
3987                         *  ls: cannot access i=a: No such file or directory
3988                         *  ls: cannot access b: No such file or directory
3989                         * Note: bash 3.2.33(1) does this only if export word
3990                         * itself is not quoted:
3991                         *  $ export i=`echo 'aaa  bbb'`; echo "$i"
3992                         *  aaa  bbb
3993                         *  $ "export" i=`echo 'aaa  bbb'`; echo "$i"
3994                         *  aaa
3995                         */
3996                         IF_HUSH_LOCAL(   || strcmp(ctx->word.data, "local") == 0)
3997                         IF_HUSH_EXPORT(  || strcmp(ctx->word.data, "export") == 0)
3998                         IF_HUSH_READONLY(|| strcmp(ctx->word.data, "readonly") == 0)
3999                        ) {
4000                                command->cmd_type = CMD_SINGLEWORD_NOGLOB;
4001                        }
4002                        /* fall through */
4003# endif
4004                }
4005#endif /* HAS_KEYWORDS */
4006
4007                if (command->group) {
4008                        /* "{ echo foo; } echo bar" - bad */
4009                        syntax_error_at(ctx->word.data);
4010                        debug_printf_parse("done_word return 1: syntax error, "
4011                                        "groups and arglists don't mix\n");
4012                        return 1;
4013                }
4014
4015                /* If this word wasn't an assignment, next ones definitely
4016                 * can't be assignments. Even if they look like ones. */
4017                if (ctx->is_assignment != DEFINITELY_ASSIGNMENT
4018                 && ctx->is_assignment != WORD_IS_KEYWORD
4019                ) {
4020                        ctx->is_assignment = NOT_ASSIGNMENT;
4021                } else {
4022                        if (ctx->is_assignment == DEFINITELY_ASSIGNMENT) {
4023                                command->assignment_cnt++;
4024                                debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt);
4025                        }
4026                        debug_printf_parse("ctx->is_assignment was:'%s'\n", assignment_flag[ctx->is_assignment]);
4027                        ctx->is_assignment = MAYBE_ASSIGNMENT;
4028                }
4029                debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
4030                command->argv = add_string_to_strings(command->argv, xstrdup(ctx->word.data));
4031                debug_print_strings("word appended to argv", command->argv);
4032        }
4033
4034#if ENABLE_HUSH_LOOPS
4035        if (ctx->ctx_res_w == RES_FOR) {
4036                if (ctx->word.has_quoted_part
4037                 || !is_well_formed_var_name(command->argv[0], '\0')
4038                ) {
4039                        /* bash says just "not a valid identifier" */
4040                        syntax_error("not a valid identifier in for");
4041                        return 1;
4042                }
4043                /* Force FOR to have just one word (variable name) */
4044                /* NB: basically, this makes hush see "for v in ..."
4045                 * syntax as if it is "for v; in ...". FOR and IN become
4046                 * two pipe structs in parse tree. */
4047                done_pipe(ctx, PIPE_SEQ);
4048        }
4049#endif
4050#if ENABLE_HUSH_CASE
4051        /* Force CASE to have just one word */
4052        if (ctx->ctx_res_w == RES_CASE) {
4053                done_pipe(ctx, PIPE_SEQ);
4054        }
4055#endif
4056
4057        o_reset_to_empty_unquoted(&ctx->word);
4058
4059        debug_printf_parse("done_word return 0\n");
4060        return 0;
4061}
4062
4063
4064/* Peek ahead in the input to find out if we have a "&n" construct,
4065 * as in "2>&1", that represents duplicating a file descriptor.
4066 * Return:
4067 * REDIRFD_CLOSE if >&- "close fd" construct is seen,
4068 * REDIRFD_SYNTAX_ERR if syntax error,
4069 * REDIRFD_TO_FILE if no & was seen,
4070 * or the number found.
4071 */
4072#if BB_MMU
4073#define parse_redir_right_fd(as_string, input) \
4074        parse_redir_right_fd(input)
4075#endif
4076static int parse_redir_right_fd(o_string *as_string, struct in_str *input)
4077{
4078        int ch, d, ok;
4079
4080        ch = i_peek(input);
4081        if (ch != '&')
4082                return REDIRFD_TO_FILE;
4083
4084        ch = i_getch(input);  /* get the & */
4085        nommu_addchr(as_string, ch);
4086        ch = i_peek(input);
4087        if (ch == '-') {
4088                ch = i_getch(input);
4089                nommu_addchr(as_string, ch);
4090                return REDIRFD_CLOSE;
4091        }
4092        d = 0;
4093        ok = 0;
4094        while (ch != EOF && isdigit(ch)) {
4095                d = d*10 + (ch-'0');
4096                ok = 1;
4097                ch = i_getch(input);
4098                nommu_addchr(as_string, ch);
4099                ch = i_peek(input);
4100        }
4101        if (ok) return d;
4102
4103//TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
4104
4105        bb_error_msg("ambiguous redirect");
4106        return REDIRFD_SYNTAX_ERR;
4107}
4108
4109/* Return code is 0 normal, 1 if a syntax error is detected
4110 */
4111static int parse_redirect(struct parse_context *ctx,
4112                int fd,
4113                redir_type style,
4114                struct in_str *input)
4115{
4116        struct command *command = ctx->command;
4117        struct redir_struct *redir;
4118        struct redir_struct **redirp;
4119        int dup_num;
4120
4121        dup_num = REDIRFD_TO_FILE;
4122        if (style != REDIRECT_HEREDOC) {
4123                /* Check for a '>&1' type redirect */
4124                dup_num = parse_redir_right_fd(&ctx->as_string, input);
4125                if (dup_num == REDIRFD_SYNTAX_ERR)
4126                        return 1;
4127        } else {
4128                int ch = i_peek_and_eat_bkslash_nl(input);
4129                dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */
4130                if (dup_num) { /* <<-... */
4131                        ch = i_getch(input);
4132                        nommu_addchr(&ctx->as_string, ch);
4133                        ch = i_peek(input);
4134                }
4135        }
4136
4137        if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) {
4138                int ch = i_peek_and_eat_bkslash_nl(input);
4139                if (ch == '|') {
4140                        /* >|FILE redirect ("clobbering" >).
4141                         * Since we do not support "set -o noclobber" yet,
4142                         * >| and > are the same for now. Just eat |.
4143                         */
4144                        ch = i_getch(input);
4145                        nommu_addchr(&ctx->as_string, ch);
4146                }
4147        }
4148
4149        /* Create a new redir_struct and append it to the linked list */
4150        redirp = &command->redirects;
4151        while ((redir = *redirp) != NULL) {
4152                redirp = &(redir->next);
4153        }
4154        *redirp = redir = xzalloc(sizeof(*redir));
4155        /* redir->next = NULL; */
4156        /* redir->rd_filename = NULL; */
4157        redir->rd_type = style;
4158        redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd;
4159
4160        debug_printf_parse("redirect type %d %s\n", redir->rd_fd,
4161                                redir_table[style].descrip);
4162
4163        redir->rd_dup = dup_num;
4164        if (style != REDIRECT_HEREDOC && dup_num != REDIRFD_TO_FILE) {
4165                /* Erik had a check here that the file descriptor in question
4166                 * is legit; I postpone that to "run time"
4167                 * A "-" representation of "close me" shows up as a -3 here */
4168                debug_printf_parse("duplicating redirect '%d>&%d'\n",
4169                                redir->rd_fd, redir->rd_dup);
4170        } else {
4171#if 0           /* Instead we emit error message at run time */
4172                if (ctx->pending_redirect) {
4173                        /* For example, "cmd > <file" */
4174                        syntax_error("invalid redirect");
4175                }
4176#endif
4177                /* Set ctx->pending_redirect, so we know what to do at the
4178                 * end of the next parsed word. */
4179                ctx->pending_redirect = redir;
4180        }
4181        return 0;
4182}
4183
4184/* If a redirect is immediately preceded by a number, that number is
4185 * supposed to tell which file descriptor to redirect.  This routine
4186 * looks for such preceding numbers.  In an ideal world this routine
4187 * needs to handle all the following classes of redirects...
4188 *     echo 2>foo     # redirects fd  2 to file "foo", nothing passed to echo
4189 *     echo 49>foo    # redirects fd 49 to file "foo", nothing passed to echo
4190 *     echo -2>foo    # redirects fd  1 to file "foo",    "-2" passed to echo
4191 *     echo 49x>foo   # redirects fd  1 to file "foo",   "49x" passed to echo
4192 *
4193 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
4194 * "2.7 Redirection
4195 * ... If n is quoted, the number shall not be recognized as part of
4196 * the redirection expression. For example:
4197 * echo \2>a
4198 * writes the character 2 into file a"
4199 * We are getting it right by setting ->has_quoted_part on any \<char>
4200 *
4201 * A -1 return means no valid number was found,
4202 * the caller should use the appropriate default for this redirection.
4203 */
4204static int redirect_opt_num(o_string *o)
4205{
4206        int num;
4207
4208        if (o->data == NULL)
4209                return -1;
4210        num = bb_strtou(o->data, NULL, 10);
4211        if (errno || num < 0)
4212                return -1;
4213        o_reset_to_empty_unquoted(o);
4214        return num;
4215}
4216
4217#if BB_MMU
4218#define fetch_till_str(as_string, input, word, skip_tabs) \
4219        fetch_till_str(input, word, skip_tabs)
4220#endif
4221static char *fetch_till_str(o_string *as_string,
4222                struct in_str *input,
4223                const char *word,
4224                int heredoc_flags)
4225{
4226        o_string heredoc = NULL_O_STRING;
4227        unsigned past_EOL;
4228        int prev = 0; /* not \ */
4229        int ch;
4230
4231        goto jump_in;
4232
4233        while (1) {
4234                ch = i_getch(input);
4235                if (ch != EOF)
4236                        nommu_addchr(as_string, ch);
4237                if (ch == '\n' || ch == EOF) {
4238 check_heredoc_end:
4239                        if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') {
4240                                if (strcmp(heredoc.data + past_EOL, word) == 0) {
4241                                        heredoc.data[past_EOL] = '\0';
4242                                        debug_printf_parse("parsed heredoc '%s'\n", heredoc.data);
4243                                        return heredoc.data;
4244                                }
4245                                if (ch == '\n') {
4246                                        /* This is a new line.
4247                                         * Remember position and backslash-escaping status.
4248                                         */
4249                                        o_addchr(&heredoc, ch);
4250                                        prev = ch;
4251 jump_in:
4252                                        past_EOL = heredoc.length;
4253                                        /* Get 1st char of next line, possibly skipping leading tabs */
4254                                        do {
4255                                                ch = i_getch(input);
4256                                                if (ch != EOF)
4257                                                        nommu_addchr(as_string, ch);
4258                                        } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t');
4259                                        /* If this immediately ended the line,
4260                                         * go back to end-of-line checks.
4261                                         */
4262                                        if (ch == '\n')
4263                                                goto check_heredoc_end;
4264                                }
4265                        }
4266                }
4267                if (ch == EOF) {
4268                        o_free_unsafe(&heredoc);
4269                        return NULL;
4270                }
4271                o_addchr(&heredoc, ch);
4272                nommu_addchr(as_string, ch);
4273                if (prev == '\\' && ch == '\\')
4274                        /* Correctly handle foo\\<eol> (not a line cont.) */
4275                        prev = 0; /* not \ */
4276                else
4277                        prev = ch;
4278        }
4279}
4280
4281/* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
4282 * and load them all. There should be exactly heredoc_cnt of them.
4283 */
4284static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_str *input)
4285{
4286        struct pipe *pi = ctx->list_head;
4287
4288        while (pi && heredoc_cnt) {
4289                int i;
4290                struct command *cmd = pi->cmds;
4291
4292                debug_printf_parse("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n",
4293                                pi->num_cmds,
4294                                cmd->argv ? cmd->argv[0] : "NONE");
4295                for (i = 0; i < pi->num_cmds; i++) {
4296                        struct redir_struct *redir = cmd->redirects;
4297
4298                        debug_printf_parse("fetch_heredocs: %d cmd argv0:'%s'\n",
4299                                        i, cmd->argv ? cmd->argv[0] : "NONE");
4300                        while (redir) {
4301                                if (redir->rd_type == REDIRECT_HEREDOC) {
4302                                        char *p;
4303
4304                                        redir->rd_type = REDIRECT_HEREDOC2;
4305                                        /* redir->rd_dup is (ab)used to indicate <<- */
4306                                        p = fetch_till_str(&ctx->as_string, input,
4307                                                        redir->rd_filename, redir->rd_dup);
4308                                        if (!p) {
4309                                                syntax_error("unexpected EOF in here document");
4310                                                return 1;
4311                                        }
4312                                        free(redir->rd_filename);
4313                                        redir->rd_filename = p;
4314                                        heredoc_cnt--;
4315                                }
4316                                redir = redir->next;
4317                        }
4318                        cmd++;
4319                }
4320                pi = pi->next;
4321        }
4322#if 0
4323        /* Should be 0. If it isn't, it's a parse error */
4324        if (heredoc_cnt)
4325                bb_error_msg_and_die("heredoc BUG 2");
4326#endif
4327        return 0;
4328}
4329
4330
4331static int run_list(struct pipe *pi);
4332#if BB_MMU
4333#define parse_stream(pstring, input, end_trigger) \
4334        parse_stream(input, end_trigger)
4335#endif
4336static struct pipe *parse_stream(char **pstring,
4337                struct in_str *input,
4338                int end_trigger);
4339
4340
4341static int parse_group(struct parse_context *ctx,
4342        struct in_str *input, int ch)
4343{
4344        /* ctx->word contains characters seen prior to ( or {.
4345         * Typically it's empty, but for function defs,
4346         * it contains function name (without '()'). */
4347#if BB_MMU
4348# define as_string NULL
4349#else
4350        char *as_string = NULL;
4351#endif
4352        struct pipe *pipe_list;
4353        int endch;
4354        struct command *command = ctx->command;
4355
4356        debug_printf_parse("parse_group entered\n");
4357#if ENABLE_HUSH_FUNCTIONS
4358        if (ch == '(' && !ctx->word.has_quoted_part) {
4359                if (ctx->word.length)
4360                        if (done_word(ctx))
4361                                return 1;
4362                if (!command->argv)
4363                        goto skip; /* (... */
4364                if (command->argv[1]) { /* word word ... (... */
4365                        syntax_error_unexpected_ch('(');
4366                        return 1;
4367                }
4368                /* it is "word(..." or "word (..." */
4369                do
4370                        ch = i_getch(input);
4371                while (ch == ' ' || ch == '\t');
4372                if (ch != ')') {
4373                        syntax_error_unexpected_ch(ch);
4374                        return 1;
4375                }
4376                nommu_addchr(&ctx->as_string, ch);
4377                do
4378                        ch = i_getch(input);
4379                while (ch == ' ' || ch == '\t' || ch == '\n');
4380                if (ch != '{' && ch != '(') {
4381                        syntax_error_unexpected_ch(ch);
4382                        return 1;
4383                }
4384                nommu_addchr(&ctx->as_string, ch);
4385                command->cmd_type = CMD_FUNCDEF;
4386                goto skip;
4387        }
4388#endif
4389
4390#if 0 /* Prevented by caller */
4391        if (command->argv /* word [word]{... */
4392         || ctx->word.length /* word{... */
4393         || ctx->word.has_quoted_part /* ""{... */
4394        ) {
4395                syntax_error(NULL);
4396                debug_printf_parse("parse_group return 1: "
4397                        "syntax error, groups and arglists don't mix\n");
4398                return 1;
4399        }
4400#endif
4401
4402 IF_HUSH_FUNCTIONS(skip:)
4403
4404        endch = '}';
4405        if (ch == '(') {
4406                endch = ')';
4407                IF_HUSH_FUNCTIONS(if (command->cmd_type != CMD_FUNCDEF))
4408                        command->cmd_type = CMD_SUBSHELL;
4409        } else {
4410                /* bash does not allow "{echo...", requires whitespace */
4411                ch = i_peek(input);
4412                if (ch != ' ' && ch != '\t' && ch != '\n'
4413                 && ch != '('   /* but "{(..." is allowed (without whitespace) */
4414                ) {
4415                        syntax_error_unexpected_ch(ch);
4416                        return 1;
4417                }
4418                if (ch != '(') {
4419                        ch = i_getch(input);
4420                        nommu_addchr(&ctx->as_string, ch);
4421                }
4422        }
4423
4424        pipe_list = parse_stream(&as_string, input, endch);
4425#if !BB_MMU
4426        if (as_string)
4427                o_addstr(&ctx->as_string, as_string);
4428#endif
4429
4430        /* empty ()/{} or parse error? */
4431        if (!pipe_list || pipe_list == ERR_PTR) {
4432                /* parse_stream already emitted error msg */
4433                if (!BB_MMU)
4434                        free(as_string);
4435                debug_printf_parse("parse_group return 1: "
4436                        "parse_stream returned %p\n", pipe_list);
4437                return 1;
4438        }
4439#if !BB_MMU
4440        as_string[strlen(as_string) - 1] = '\0'; /* plink ')' or '}' */
4441        command->group_as_string = as_string;
4442        debug_printf_parse("end of group, remembering as:'%s'\n",
4443                        command->group_as_string);
4444#endif
4445
4446#if ENABLE_HUSH_FUNCTIONS
4447        /* Convert "f() (cmds)" to "f() {(cmds)}" */
4448        if (command->cmd_type == CMD_FUNCDEF && endch == ')') {
4449                struct command *cmd2;
4450
4451                cmd2 = xzalloc(sizeof(*cmd2));
4452                cmd2->cmd_type = CMD_SUBSHELL;
4453                cmd2->group = pipe_list;
4454# if !BB_MMU
4455//UNTESTED!
4456                cmd2->group_as_string = command->group_as_string;
4457                command->group_as_string = xasprintf("(%s)", command->group_as_string);
4458# endif
4459
4460                pipe_list = new_pipe();
4461                pipe_list->cmds = cmd2;
4462                pipe_list->num_cmds = 1;
4463        }
4464#endif
4465
4466        command->group = pipe_list;
4467
4468        debug_printf_parse("parse_group return 0\n");
4469        return 0;
4470        /* command remains "open", available for possible redirects */
4471#undef as_string
4472}
4473
4474#if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS
4475/* Subroutines for copying $(...) and `...` things */
4476static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
4477/* '...' */
4478static int add_till_single_quote(o_string *dest, struct in_str *input)
4479{
4480        while (1) {
4481                int ch = i_getch(input);
4482                if (ch == EOF) {
4483                        syntax_error_unterm_ch('\'');
4484                        return 0;
4485                }
4486                if (ch == '\'')
4487                        return 1;
4488                o_addchr(dest, ch);
4489        }
4490}
4491/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
4492static int add_till_double_quote(o_string *dest, struct in_str *input)
4493{
4494        while (1) {
4495                int ch = i_getch(input);
4496                if (ch == EOF) {
4497                        syntax_error_unterm_ch('"');
4498                        return 0;
4499                }
4500                if (ch == '"')
4501                        return 1;
4502                if (ch == '\\') {  /* \x. Copy both chars. */
4503                        o_addchr(dest, ch);
4504                        ch = i_getch(input);
4505                }
4506                o_addchr(dest, ch);
4507                if (ch == '`') {
4508                        if (!add_till_backquote(dest, input, /*in_dquote:*/ 1))
4509                                return 0;
4510                        o_addchr(dest, ch);
4511                        continue;
4512                }
4513                //if (ch == '$') ...
4514        }
4515}
4516/* Process `cmd` - copy contents until "`" is seen. Complicated by
4517 * \` quoting.
4518 * "Within the backquoted style of command substitution, backslash
4519 * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
4520 * The search for the matching backquote shall be satisfied by the first
4521 * backquote found without a preceding backslash; during this search,
4522 * if a non-escaped backquote is encountered within a shell comment,
4523 * a here-document, an embedded command substitution of the $(command)
4524 * form, or a quoted string, undefined results occur. A single-quoted
4525 * or double-quoted string that begins, but does not end, within the
4526 * "`...`" sequence produces undefined results."
4527 * Example                               Output
4528 * echo `echo '\'TEST\`echo ZZ\`BEST`    \TESTZZBEST
4529 */
4530static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote)
4531{
4532        while (1) {
4533                int ch = i_getch(input);
4534                if (ch == '`')
4535                        return 1;
4536                if (ch == '\\') {
4537                        /* \x. Copy both unless it is \`, \$, \\ and maybe \" */
4538                        ch = i_getch(input);
4539                        if (ch != '`'
4540                         && ch != '$'
4541                         && ch != '\\'
4542                         && (!in_dquote || ch != '"')
4543                        ) {
4544                                o_addchr(dest, '\\');
4545                        }
4546                }
4547                if (ch == EOF) {
4548                        syntax_error_unterm_ch('`');
4549                        return 0;
4550                }
4551                o_addchr(dest, ch);
4552        }
4553}
4554/* Process $(cmd) - copy contents until ")" is seen. Complicated by
4555 * quoting and nested ()s.
4556 * "With the $(command) style of command substitution, all characters
4557 * following the open parenthesis to the matching closing parenthesis
4558 * constitute the command. Any valid shell script can be used for command,
4559 * except a script consisting solely of redirections which produces
4560 * unspecified results."
4561 * Example                              Output
4562 * echo $(echo '(TEST)' BEST)           (TEST) BEST
4563 * echo $(echo 'TEST)' BEST)            TEST) BEST
4564 * echo $(echo \(\(TEST\) BEST)         ((TEST) BEST
4565 *
4566 * Also adapted to eat ${var%...} and $((...)) constructs, since ... part
4567 * can contain arbitrary constructs, just like $(cmd).
4568 * In bash compat mode, it needs to also be able to stop on ':' or '/'
4569 * for ${var:N[:M]} and ${var/P[/R]} parsing.
4570 */
4571#define DOUBLE_CLOSE_CHAR_FLAG 0x80
4572static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsigned end_ch)
4573{
4574        int ch;
4575        char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG;
4576# if BASH_SUBSTR || BASH_PATTERN_SUBST
4577        char end_char2 = end_ch >> 8;
4578# endif
4579        end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1);
4580
4581#if ENABLE_HUSH_INTERACTIVE
4582        G.promptmode = 1; /* PS2 */
4583#endif
4584        debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
4585
4586        while (1) {
4587                ch = i_getch(input);
4588                if (ch == EOF) {
4589                        syntax_error_unterm_ch(end_ch);
4590                        return 0;
4591                }
4592                if (ch == end_ch
4593# if BASH_SUBSTR || BASH_PATTERN_SUBST
4594                 || ch == end_char2
4595# endif
4596                ) {
4597                        if (!dbl)
4598                                break;
4599                        /* we look for closing )) of $((EXPR)) */
4600                        if (i_peek_and_eat_bkslash_nl(input) == end_ch) {
4601                                i_getch(input); /* eat second ')' */
4602                                break;
4603                        }
4604                }
4605                o_addchr(dest, ch);
4606                //bb_error_msg("%s:o_addchr('%c')", __func__, ch);
4607                if (ch == '(' || ch == '{') {
4608                        ch = (ch == '(' ? ')' : '}');
4609                        if (!add_till_closing_bracket(dest, input, ch))
4610                                return 0;
4611                        o_addchr(dest, ch);
4612                        continue;
4613                }
4614                if (ch == '\'') {
4615                        if (!add_till_single_quote(dest, input))
4616                                return 0;
4617                        o_addchr(dest, ch);
4618                        continue;
4619                }
4620                if (ch == '"') {
4621                        if (!add_till_double_quote(dest, input))
4622                                return 0;
4623                        o_addchr(dest, ch);
4624                        continue;
4625                }
4626                if (ch == '`') {
4627                        if (!add_till_backquote(dest, input, /*in_dquote:*/ 0))
4628                                return 0;
4629                        o_addchr(dest, ch);
4630                        continue;
4631                }
4632                if (ch == '\\') {
4633                        /* \x. Copy verbatim. Important for  \(, \) */
4634                        ch = i_getch(input);
4635                        if (ch == EOF) {
4636                                syntax_error_unterm_ch(end_ch);
4637                                return 0;
4638                        }
4639#if 0
4640                        if (ch == '\n') {
4641                                /* "backslash+newline", ignore both */
4642                                o_delchr(dest); /* undo insertion of '\' */
4643                                continue;
4644                        }
4645#endif
4646                        o_addchr(dest, ch);
4647                        //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch);
4648                        continue;
4649                }
4650        }
4651        debug_printf_parse("%s return '%s' ch:'%c'\n", __func__, dest->data, ch);
4652        return ch;
4653}
4654#endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */
4655
4656/* Return code: 0 for OK, 1 for syntax error */
4657#if BB_MMU
4658#define parse_dollar(as_string, dest, input, quote_mask) \
4659        parse_dollar(dest, input, quote_mask)
4660#define as_string NULL
4661#endif
4662static int parse_dollar(o_string *as_string,
4663                o_string *dest,
4664                struct in_str *input, unsigned char quote_mask)
4665{
4666        int ch = i_peek_and_eat_bkslash_nl(input);  /* first character after the $ */
4667
4668        debug_printf_parse("parse_dollar entered: ch='%c'\n", ch);
4669        if (isalpha(ch)) {
4670 make_var:
4671                ch = i_getch(input);
4672                nommu_addchr(as_string, ch);
4673 /*make_var1:*/
4674                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4675                while (1) {
4676                        debug_printf_parse(": '%c'\n", ch);
4677                        o_addchr(dest, ch | quote_mask);
4678                        quote_mask = 0;
4679                        ch = i_peek_and_eat_bkslash_nl(input);
4680                        if (!isalnum(ch) && ch != '_') {
4681                                /* End of variable name reached */
4682                                break;
4683                        }
4684                        ch = i_getch(input);
4685                        nommu_addchr(as_string, ch);
4686                }
4687                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4688        } else if (isdigit(ch)) {
4689 make_one_char_var:
4690                ch = i_getch(input);
4691                nommu_addchr(as_string, ch);
4692                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4693                debug_printf_parse(": '%c'\n", ch);
4694                o_addchr(dest, ch | quote_mask);
4695                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4696        } else switch (ch) {
4697        case '$': /* pid */
4698        case '!': /* last bg pid */
4699        case '?': /* last exit code */
4700        case '#': /* number of args */
4701        case '*': /* args */
4702        case '@': /* args */
4703                goto make_one_char_var;
4704        case '{': {
4705                char len_single_ch;
4706
4707                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4708
4709                ch = i_getch(input); /* eat '{' */
4710                nommu_addchr(as_string, ch);
4711
4712                ch = i_getch_and_eat_bkslash_nl(input); /* first char after '{' */
4713                /* It should be ${?}, or ${#var},
4714                 * or even ${?+subst} - operator acting on a special variable,
4715                 * or the beginning of variable name.
4716                 */
4717                if (ch == EOF
4718                 || (!strchr(_SPECIAL_VARS_STR, ch) && !isalnum(ch)) /* not one of those */
4719                ) {
4720 bad_dollar_syntax:
4721                        syntax_error_unterm_str("${name}");
4722                        debug_printf_parse("parse_dollar return 0: unterminated ${name}\n");
4723                        return 0;
4724                }
4725                nommu_addchr(as_string, ch);
4726                len_single_ch = ch;
4727                ch |= quote_mask;
4728
4729                /* It's possible to just call add_till_closing_bracket() at this point.
4730                 * However, this regresses some of our testsuite cases
4731                 * which check invalid constructs like ${%}.
4732                 * Oh well... let's check that the var name part is fine... */
4733
4734                while (1) {
4735                        unsigned pos;
4736
4737                        o_addchr(dest, ch);
4738                        debug_printf_parse(": '%c'\n", ch);
4739
4740                        ch = i_getch(input);
4741                        nommu_addchr(as_string, ch);
4742                        if (ch == '}')
4743                                break;
4744
4745                        if (!isalnum(ch) && ch != '_') {
4746                                unsigned end_ch;
4747                                unsigned char last_ch;
4748                                /* handle parameter expansions
4749                                 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
4750                                 */
4751                                if (!strchr(VAR_SUBST_OPS, ch)) { /* ${var<bad_char>... */
4752                                        if (len_single_ch != '#'
4753                                        /*|| !strchr(SPECIAL_VARS_STR, ch) - disallow errors like ${#+} ? */
4754                                         || i_peek(input) != '}'
4755                                        ) {
4756                                                goto bad_dollar_syntax;
4757                                        }
4758                                        /* else: it's "length of C" ${#C} op,
4759                                         * where C is a single char
4760                                         * special var name, e.g. ${#!}.
4761                                         */
4762                                }
4763                                /* Eat everything until closing '}' (or ':') */
4764                                end_ch = '}';
4765                                if (BASH_SUBSTR
4766                                 && ch == ':'
4767                                 && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input))
4768                                ) {
4769                                        /* It's ${var:N[:M]} thing */
4770                                        end_ch = '}' * 0x100 + ':';
4771                                }
4772                                if (BASH_PATTERN_SUBST
4773                                 && ch == '/'
4774                                ) {
4775                                        /* It's ${var/[/]pattern[/repl]} thing */
4776                                        if (i_peek(input) == '/') { /* ${var//pattern[/repl]}? */
4777                                                i_getch(input);
4778                                                nommu_addchr(as_string, '/');
4779                                                ch = '\\';
4780                                        }
4781                                        end_ch = '}' * 0x100 + '/';
4782                                }
4783                                o_addchr(dest, ch);
4784 again:
4785                                if (!BB_MMU)
4786                                        pos = dest->length;
4787#if ENABLE_HUSH_DOLLAR_OPS
4788                                last_ch = add_till_closing_bracket(dest, input, end_ch);
4789                                if (last_ch == 0) /* error? */
4790                                        return 0;
4791#else
4792#error Simple code to only allow ${var} is not implemented
4793#endif
4794                                if (as_string) {
4795                                        o_addstr(as_string, dest->data + pos);
4796                                        o_addchr(as_string, last_ch);
4797                                }
4798
4799                                if ((BASH_SUBSTR || BASH_PATTERN_SUBST)
4800                                         && (end_ch & 0xff00)
4801                                ) {
4802                                        /* close the first block: */
4803                                        o_addchr(dest, SPECIAL_VAR_SYMBOL);
4804                                        /* while parsing N from ${var:N[:M]}
4805                                         * or pattern from ${var/[/]pattern[/repl]} */
4806                                        if ((end_ch & 0xff) == last_ch) {
4807                                                /* got ':' or '/'- parse the rest */
4808                                                end_ch = '}';
4809                                                goto again;
4810                                        }
4811                                        /* got '}' */
4812                                        if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') {
4813                                                /* it's ${var:N} - emulate :999999999 */
4814                                                o_addstr(dest, "999999999");
4815                                        } /* else: it's ${var/[/]pattern} */
4816                                }
4817                                break;
4818                        }
4819                        len_single_ch = 0; /* it can't be ${#C} op */
4820                }
4821                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4822                break;
4823        }
4824#if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_TICK
4825        case '(': {
4826                unsigned pos;
4827
4828                ch = i_getch(input);
4829                nommu_addchr(as_string, ch);
4830# if ENABLE_FEATURE_SH_MATH
4831                if (i_peek_and_eat_bkslash_nl(input) == '(') {
4832                        ch = i_getch(input);
4833                        nommu_addchr(as_string, ch);
4834                        o_addchr(dest, SPECIAL_VAR_SYMBOL);
4835                        o_addchr(dest, /*quote_mask |*/ '+');
4836                        if (!BB_MMU)
4837                                pos = dest->length;
4838                        if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG))
4839                                return 0; /* error */
4840                        if (as_string) {
4841                                o_addstr(as_string, dest->data + pos);
4842                                o_addchr(as_string, ')');
4843                                o_addchr(as_string, ')');
4844                        }
4845                        o_addchr(dest, SPECIAL_VAR_SYMBOL);
4846                        break;
4847                }
4848# endif
4849# if ENABLE_HUSH_TICK
4850                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4851                o_addchr(dest, quote_mask | '`');
4852                if (!BB_MMU)
4853                        pos = dest->length;
4854                if (!add_till_closing_bracket(dest, input, ')'))
4855                        return 0; /* error */
4856                if (as_string) {
4857                        o_addstr(as_string, dest->data + pos);
4858                        o_addchr(as_string, ')');
4859                }
4860                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4861# endif
4862                break;
4863        }
4864#endif
4865        case '_':
4866                goto make_var;
4867#if 0
4868        /* TODO: $_ and $-: */
4869        /* $_ Shell or shell script name; or last argument of last command
4870         * (if last command wasn't a pipe; if it was, bash sets $_ to "");
4871         * but in command's env, set to full pathname used to invoke it */
4872        /* $- Option flags set by set builtin or shell options (-i etc) */
4873                ch = i_getch(input);
4874                nommu_addchr(as_string, ch);
4875                ch = i_peek_and_eat_bkslash_nl(input);
4876                if (isalnum(ch)) { /* it's $_name or $_123 */
4877                        ch = '_';
4878                        goto make_var1;
4879                }
4880                /* else: it's $_ */
4881#endif
4882        default:
4883                o_addQchr(dest, '$');
4884        }
4885        debug_printf_parse("parse_dollar return 1 (ok)\n");
4886        return 1;
4887#undef as_string
4888}
4889
4890#if BB_MMU
4891# if BASH_PATTERN_SUBST
4892#define encode_string(as_string, dest, input, dquote_end, process_bkslash) \
4893        encode_string(dest, input, dquote_end, process_bkslash)
4894# else
4895/* only ${var/pattern/repl} (its pattern part) needs additional mode */
4896#define encode_string(as_string, dest, input, dquote_end, process_bkslash) \
4897        encode_string(dest, input, dquote_end)
4898# endif
4899#define as_string NULL
4900
4901#else /* !MMU */
4902
4903# if BASH_PATTERN_SUBST
4904/* all parameters are needed, no macro tricks */
4905# else
4906#define encode_string(as_string, dest, input, dquote_end, process_bkslash) \
4907        encode_string(as_string, dest, input, dquote_end)
4908# endif
4909#endif
4910static int encode_string(o_string *as_string,
4911                o_string *dest,
4912                struct in_str *input,
4913                int dquote_end,
4914                int process_bkslash)
4915{
4916#if !BASH_PATTERN_SUBST
4917        const int process_bkslash = 1;
4918#endif
4919        int ch;
4920        int next;
4921
4922 again:
4923        ch = i_getch(input);
4924        if (ch != EOF)
4925                nommu_addchr(as_string, ch);
4926        if (ch == dquote_end) { /* may be only '"' or EOF */
4927                debug_printf_parse("encode_string return 1 (ok)\n");
4928                return 1;
4929        }
4930        /* note: can't move it above ch == dquote_end check! */
4931        if (ch == EOF) {
4932                syntax_error_unterm_ch('"');
4933                return 0; /* error */
4934        }
4935        next = '\0';
4936        if (ch != '\n') {
4937                next = i_peek(input);
4938        }
4939        debug_printf_parse("\" ch=%c (%d) escape=%d\n",
4940                        ch, ch, !!(dest->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
4941        if (process_bkslash && ch == '\\') {
4942                if (next == EOF) {
4943                        /* Testcase: in interactive shell a file with
4944                         *  echo "unterminated string\<eof>
4945                         * is sourced.
4946                         */
4947                        syntax_error_unterm_ch('"');
4948                        return 0; /* error */
4949                }
4950                /* bash:
4951                 * "The backslash retains its special meaning [in "..."]
4952                 * only when followed by one of the following characters:
4953                 * $, `, ", \, or <newline>.  A double quote may be quoted
4954                 * within double quotes by preceding it with a backslash."
4955                 * NB: in (unquoted) heredoc, above does not apply to ",
4956                 * therefore we check for it by "next == dquote_end" cond.
4957                 */
4958                if (next == dquote_end || strchr("$`\\\n", next)) {
4959                        ch = i_getch(input); /* eat next */
4960                        if (ch == '\n')
4961                                goto again; /* skip \<newline> */
4962                } /* else: ch remains == '\\', and we double it below: */
4963                o_addqchr(dest, ch); /* \c if c is a glob char, else just c */
4964                nommu_addchr(as_string, ch);
4965                goto again;
4966        }
4967        if (ch == '$') {
4968                if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) {
4969                        debug_printf_parse("encode_string return 0: "
4970                                        "parse_dollar returned 0 (error)\n");
4971                        return 0;
4972                }
4973                goto again;
4974        }
4975#if ENABLE_HUSH_TICK
4976        if (ch == '`') {
4977                //unsigned pos = dest->length;
4978                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4979                o_addchr(dest, 0x80 | '`');
4980                if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'))
4981                        return 0; /* error */
4982                o_addchr(dest, SPECIAL_VAR_SYMBOL);
4983                //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
4984                goto again;
4985        }
4986#endif
4987        o_addQchr(dest, ch);
4988        goto again;
4989#undef as_string
4990}
4991
4992/*
4993 * Scan input until EOF or end_trigger char.
4994 * Return a list of pipes to execute, or NULL on EOF
4995 * or if end_trigger character is met.
4996 * On syntax error, exit if shell is not interactive,
4997 * reset parsing machinery and start parsing anew,
4998 * or return ERR_PTR.
4999 */
5000static struct pipe *parse_stream(char **pstring,
5001                struct in_str *input,
5002                int end_trigger)
5003{
5004        struct parse_context ctx;
5005        int heredoc_cnt;
5006
5007        /* Single-quote triggers a bypass of the main loop until its mate is
5008         * found.  When recursing, quote state is passed in via ctx.word.o_expflags.
5009         */
5010        debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
5011                        end_trigger ? end_trigger : 'X');
5012        debug_enter();
5013
5014        initialize_context(&ctx);
5015
5016        /* If very first arg is "" or '', ctx.word.data may end up NULL.
5017         * Preventing this:
5018         */
5019        o_addchr(&ctx.word, '\0');
5020        ctx.word.length = 0;
5021
5022        /* We used to separate words on $IFS here. This was wrong.
5023         * $IFS is used only for word splitting when $var is expanded,
5024         * here we should use blank chars as separators, not $IFS
5025         */
5026
5027        heredoc_cnt = 0;
5028        while (1) {
5029                const char *is_blank;
5030                const char *is_special;
5031                int ch;
5032                int next;
5033                int redir_fd;
5034                redir_type redir_style;
5035
5036                ch = i_getch(input);
5037                debug_printf_parse(": ch=%c (%d) escape=%d\n",
5038                                ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5039                if (ch == EOF) {
5040                        struct pipe *pi;
5041
5042                        if (heredoc_cnt) {
5043                                syntax_error_unterm_str("here document");
5044                                goto parse_error;
5045                        }
5046                        if (end_trigger == ')') {
5047                                syntax_error_unterm_ch('(');
5048                                goto parse_error;
5049                        }
5050                        if (end_trigger == '}') {
5051                                syntax_error_unterm_ch('{');
5052                                goto parse_error;
5053                        }
5054
5055                        if (done_word(&ctx)) {
5056                                goto parse_error;
5057                        }
5058                        o_free(&ctx.word);
5059                        done_pipe(&ctx, PIPE_SEQ);
5060                        pi = ctx.list_head;
5061                        /* If we got nothing... */
5062                        /* (this makes bare "&" cmd a no-op.
5063                         * bash says: "syntax error near unexpected token '&'") */
5064                        if (pi->num_cmds == 0
5065                        IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE)
5066                        ) {
5067                                free_pipe_list(pi);
5068                                pi = NULL;
5069                        }
5070#if !BB_MMU
5071                        debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data);
5072                        if (pstring)
5073                                *pstring = ctx.as_string.data;
5074                        else
5075                                o_free_unsafe(&ctx.as_string);
5076#endif
5077                        debug_leave();
5078                        debug_printf_parse("parse_stream return %p\n", pi);
5079                        return pi;
5080                }
5081
5082                /* Handle "'" and "\" first, as they won't play nice with
5083                 * i_peek_and_eat_bkslash_nl() anyway:
5084                 *   echo z\\
5085                 * and
5086                 *   echo '\
5087                 *   '
5088                 * would break.
5089                 */
5090                if (ch == '\\') {
5091                        ch = i_getch(input);
5092                        if (ch == '\n')
5093                                continue; /* drop \<newline>, get next char */
5094                        nommu_addchr(&ctx.as_string, '\\');
5095                        o_addchr(&ctx.word, '\\');
5096                        if (ch == EOF) {
5097                                /* Testcase: eval 'echo Ok\' */
5098                                /* bash-4.3.43 was removing backslash,
5099                                 * but 4.4.19 retains it, most other shells too
5100                                 */
5101                                continue; /* get next char */
5102                        }
5103                        /* Example: echo Hello \2>file
5104                         * we need to know that word 2 is quoted
5105                         */
5106                        ctx.word.has_quoted_part = 1;
5107                        nommu_addchr(&ctx.as_string, ch);
5108                        o_addchr(&ctx.word, ch);
5109                        continue; /* get next char */
5110                }
5111                nommu_addchr(&ctx.as_string, ch);
5112                if (ch == '\'') {
5113                        ctx.word.has_quoted_part = 1;
5114                        next = i_getch(input);
5115                        if (next == '\'' && !ctx.pending_redirect)
5116                                goto insert_empty_quoted_str_marker;
5117
5118                        ch = next;
5119                        while (1) {
5120                                if (ch == EOF) {
5121                                        syntax_error_unterm_ch('\'');
5122                                        goto parse_error;
5123                                }
5124                                nommu_addchr(&ctx.as_string, ch);
5125                                if (ch == '\'')
5126                                        break;
5127                                if (ch == SPECIAL_VAR_SYMBOL) {
5128                                        /* Convert raw ^C to corresponding special variable reference */
5129                                        o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5130                                        o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5131                                }
5132                                o_addqchr(&ctx.word, ch);
5133                                ch = i_getch(input);
5134                        }
5135                        continue; /* get next char */
5136                }
5137
5138                next = '\0';
5139                if (ch != '\n')
5140                        next = i_peek_and_eat_bkslash_nl(input);
5141
5142                is_special = "{}<>;&|()#" /* special outside of "str" */
5143                                "$\"" IF_HUSH_TICK("`") /* always special */
5144                                SPECIAL_VAR_SYMBOL_STR;
5145                /* Are { and } special here? */
5146                if (ctx.command->argv /* word [word]{... - non-special */
5147                 || ctx.word.length       /* word{... - non-special */
5148                 || ctx.word.has_quoted_part     /* ""{... - non-special */
5149                 || (next != ';'             /* }; - special */
5150                    && next != ')'           /* }) - special */
5151                    && next != '('           /* {( - special */
5152                    && next != '&'           /* }& and }&& ... - special */
5153                    && next != '|'           /* }|| ... - special */
5154                    && !strchr(defifs, next) /* {word - non-special */
5155                    )
5156                ) {
5157                        /* They are not special, skip "{}" */
5158                        is_special += 2;
5159                }
5160                is_special = strchr(is_special, ch);
5161                is_blank = strchr(defifs, ch);
5162
5163                if (!is_special && !is_blank) { /* ordinary char */
5164 ordinary_char:
5165                        o_addQchr(&ctx.word, ch);
5166                        if ((ctx.is_assignment == MAYBE_ASSIGNMENT
5167                            || ctx.is_assignment == WORD_IS_KEYWORD)
5168                         && ch == '='
5169                         && is_well_formed_var_name(ctx.word.data, '=')
5170                        ) {
5171                                ctx.is_assignment = DEFINITELY_ASSIGNMENT;
5172                                debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5173                        }
5174                        continue;
5175                }
5176
5177                if (is_blank) {
5178#if ENABLE_HUSH_LINENO_VAR
5179/* Case:
5180 * "while ...; do<whitespace><newline>
5181 *      cmd ..."
5182 * would think that "cmd" starts in <whitespace> -
5183 * i.e., at the previous line.
5184 * We need to skip all whitespace before newlines.
5185 */
5186                        while (ch != '\n') {
5187                                next = i_peek(input);
5188                                if (next != ' ' && next != '\t' && next != '\n')
5189                                        break; /* next char is not ws */
5190                                ch = i_getch(input);
5191                        }
5192                        /* ch == last eaten whitespace char */
5193#endif
5194                        if (done_word(&ctx)) {
5195                                goto parse_error;
5196                        }
5197                        if (ch == '\n') {
5198                                /* Is this a case when newline is simply ignored?
5199                                 * Some examples:
5200                                 * "cmd | <newline> cmd ..."
5201                                 * "case ... in <newline> word) ..."
5202                                 */
5203                                if (IS_NULL_CMD(ctx.command)
5204                                 && ctx.word.length == 0 && !ctx.word.has_quoted_part
5205                                ) {
5206                                        /* This newline can be ignored. But...
5207                                         * Without check #1, interactive shell
5208                                         * ignores even bare <newline>,
5209                                         * and shows the continuation prompt:
5210                                         * ps1_prompt$ <enter>
5211                                         * ps2> _   <=== wrong, should be ps1
5212                                         * Without check #2, "cmd & <newline>"
5213                                         * is similarly mistreated.
5214                                         * (BTW, this makes "cmd & cmd"
5215                                         * and "cmd && cmd" non-orthogonal.
5216                                         * Really, ask yourself, why
5217                                         * "cmd && <newline>" doesn't start
5218                                         * cmd but waits for more input?
5219                                         * The only reason is that it might be
5220                                         * a "cmd1 && <nl> cmd2 &" construct,
5221                                         * cmd1 may need to run in BG).
5222                                         */
5223                                        struct pipe *pi = ctx.list_head;
5224                                        if (pi->num_cmds != 0       /* check #1 */
5225                                         && pi->followup != PIPE_BG /* check #2 */
5226                                        ) {
5227                                                continue;
5228                                        }
5229                                }
5230                                /* Treat newline as a command separator. */
5231                                done_pipe(&ctx, PIPE_SEQ);
5232                                debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt);
5233                                if (heredoc_cnt) {
5234                                        if (fetch_heredocs(heredoc_cnt, &ctx, input)) {
5235                                                goto parse_error;
5236                                        }
5237                                        heredoc_cnt = 0;
5238                                }
5239                                ctx.is_assignment = MAYBE_ASSIGNMENT;
5240                                debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5241                                ch = ';';
5242                                /* note: if (is_blank) continue;
5243                                 * will still trigger for us */
5244                        }
5245                }
5246
5247                /* "cmd}" or "cmd }..." without semicolon or &:
5248                 * } is an ordinary char in this case, even inside { cmd; }
5249                 * Pathological example: { ""}; } should exec "}" cmd
5250                 */
5251                if (ch == '}') {
5252                        if (ctx.word.length != 0 /* word} */
5253                         || ctx.word.has_quoted_part    /* ""} */
5254                        ) {
5255                                goto ordinary_char;
5256                        }
5257                        if (!IS_NULL_CMD(ctx.command)) { /* cmd } */
5258                                /* Generally, there should be semicolon: "cmd; }"
5259                                 * However, bash allows to omit it if "cmd" is
5260                                 * a group. Examples:
5261                                 * { { echo 1; } }
5262                                 * {(echo 1)}
5263                                 * { echo 0 >&2 | { echo 1; } }
5264                                 * { while false; do :; done }
5265                                 * { case a in b) ;; esac }
5266                                 */
5267                                if (ctx.command->group)
5268                                        goto term_group;
5269                                goto ordinary_char;
5270                        }
5271                        if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */
5272                                /* Can't be an end of {cmd}, skip the check */
5273                                goto skip_end_trigger;
5274                        /* else: } does terminate a group */
5275                }
5276 term_group:
5277                if (end_trigger && end_trigger == ch
5278                 && (ch != ';' || heredoc_cnt == 0)
5279#if ENABLE_HUSH_CASE
5280                 && (ch != ')'
5281                    || ctx.ctx_res_w != RES_MATCH
5282                    || (!ctx.word.has_quoted_part && strcmp(ctx.word.data, "esac") == 0)
5283                    )
5284#endif
5285                ) {
5286                        if (heredoc_cnt) {
5287                                /* This is technically valid:
5288                                 * { cat <<HERE; }; echo Ok
5289                                 * heredoc
5290                                 * heredoc
5291                                 * HERE
5292                                 * but we don't support this.
5293                                 * We require heredoc to be in enclosing {}/(),
5294                                 * if any.
5295                                 */
5296                                syntax_error_unterm_str("here document");
5297                                goto parse_error;
5298                        }
5299                        if (done_word(&ctx)) {
5300                                goto parse_error;
5301                        }
5302                        done_pipe(&ctx, PIPE_SEQ);
5303                        ctx.is_assignment = MAYBE_ASSIGNMENT;
5304                        debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5305                        /* Do we sit outside of any if's, loops or case's? */
5306                        if (!HAS_KEYWORDS
5307                        IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
5308                        ) {
5309                                o_free(&ctx.word);
5310#if !BB_MMU
5311                                debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data);
5312                                if (pstring)
5313                                        *pstring = ctx.as_string.data;
5314                                else
5315                                        o_free_unsafe(&ctx.as_string);
5316#endif
5317                                if (ch != ';' && IS_NULL_PIPE(ctx.list_head)) {
5318                                        /* Example: bare "{ }", "()" */
5319                                        G.last_exitcode = 2; /* bash compat */
5320                                        syntax_error_unexpected_ch(ch);
5321                                        goto parse_error2;
5322                                }
5323                                debug_printf_parse("parse_stream return %p: "
5324                                                "end_trigger char found\n",
5325                                                ctx.list_head);
5326                                debug_leave();
5327                                return ctx.list_head;
5328                        }
5329                }
5330
5331                if (is_blank)
5332                        continue;
5333
5334                /* Catch <, > before deciding whether this word is
5335                 * an assignment. a=1 2>z b=2: b=2 is still assignment */
5336                switch (ch) {
5337                case '>':
5338                        redir_fd = redirect_opt_num(&ctx.word);
5339                        if (done_word(&ctx)) {
5340                                goto parse_error;
5341                        }
5342                        redir_style = REDIRECT_OVERWRITE;
5343                        if (next == '>') {
5344                                redir_style = REDIRECT_APPEND;
5345                                ch = i_getch(input);
5346                                nommu_addchr(&ctx.as_string, ch);
5347                        }
5348#if 0
5349                        else if (next == '(') {
5350                                syntax_error(">(process) not supported");
5351                                goto parse_error;
5352                        }
5353#endif
5354                        if (parse_redirect(&ctx, redir_fd, redir_style, input))
5355                                goto parse_error;
5356                        continue; /* get next char */
5357                case '<':
5358                        redir_fd = redirect_opt_num(&ctx.word);
5359                        if (done_word(&ctx)) {
5360                                goto parse_error;
5361                        }
5362                        redir_style = REDIRECT_INPUT;
5363                        if (next == '<') {
5364                                redir_style = REDIRECT_HEREDOC;
5365                                heredoc_cnt++;
5366                                debug_printf_parse("++heredoc_cnt=%d\n", heredoc_cnt);
5367                                ch = i_getch(input);
5368                                nommu_addchr(&ctx.as_string, ch);
5369                        } else if (next == '>') {
5370                                redir_style = REDIRECT_IO;
5371                                ch = i_getch(input);
5372                                nommu_addchr(&ctx.as_string, ch);
5373                        }
5374#if 0
5375                        else if (next == '(') {
5376                                syntax_error("<(process) not supported");
5377                                goto parse_error;
5378                        }
5379#endif
5380                        if (parse_redirect(&ctx, redir_fd, redir_style, input))
5381                                goto parse_error;
5382                        continue; /* get next char */
5383                case '#':
5384                        if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
5385                                /* skip "#comment" */
5386                                /* note: we do not add it to &ctx.as_string */
5387/* TODO: in bash:
5388 * comment inside $() goes to the next \n, even inside quoted string (!):
5389 * cmd "$(cmd2 #comment)" - syntax error
5390 * cmd "`cmd2 #comment`" - ok
5391 * We accept both (comment ends where command subst ends, in both cases).
5392 */
5393                                while (1) {
5394                                        ch = i_peek(input);
5395                                        if (ch == '\n') {
5396                                                nommu_addchr(&ctx.as_string, '\n');
5397                                                break;
5398                                        }
5399                                        ch = i_getch(input);
5400                                        if (ch == EOF)
5401                                                break;
5402                                }
5403                                continue; /* get next char */
5404                        }
5405                        break;
5406                }
5407 skip_end_trigger:
5408
5409                if (ctx.is_assignment == MAYBE_ASSIGNMENT
5410                 /* check that we are not in word in "a=1 2>word b=1": */
5411                 && !ctx.pending_redirect
5412                ) {
5413                        /* ch is a special char and thus this word
5414                         * cannot be an assignment */
5415                        ctx.is_assignment = NOT_ASSIGNMENT;
5416                        debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5417                }
5418
5419                /* Note: nommu_addchr(&ctx.as_string, ch) is already done */
5420
5421                switch (ch) {
5422                case SPECIAL_VAR_SYMBOL:
5423                        /* Convert raw ^C to corresponding special variable reference */
5424                        o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5425                        o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5426                        /* fall through */
5427                case '#':
5428                        /* non-comment #: "echo a#b" etc */
5429                        o_addchr(&ctx.word, ch);
5430                        continue; /* get next char */
5431                case '$':
5432                        if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
5433                                debug_printf_parse("parse_stream parse error: "
5434                                        "parse_dollar returned 0 (error)\n");
5435                                goto parse_error;
5436                        }
5437                        continue; /* get next char */
5438                case '"':
5439                        ctx.word.has_quoted_part = 1;
5440                        if (next == '"' && !ctx.pending_redirect) {
5441                                i_getch(input); /* eat second " */
5442 insert_empty_quoted_str_marker:
5443                                nommu_addchr(&ctx.as_string, next);
5444                                o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5445                                o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5446                                continue; /* get next char */
5447                        }
5448                        if (ctx.is_assignment == NOT_ASSIGNMENT)
5449                                ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS;
5450                        if (!encode_string(&ctx.as_string, &ctx.word, input, '"', /*process_bkslash:*/ 1))
5451                                goto parse_error;
5452                        ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS;
5453                        continue; /* get next char */
5454#if ENABLE_HUSH_TICK
5455                case '`': {
5456                        USE_FOR_NOMMU(unsigned pos;)
5457
5458                        o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5459                        o_addchr(&ctx.word, '`');
5460                        USE_FOR_NOMMU(pos = ctx.word.length;)
5461                        if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0))
5462                                goto parse_error;
5463# if !BB_MMU
5464                        o_addstr(&ctx.as_string, ctx.word.data + pos);
5465                        o_addchr(&ctx.as_string, '`');
5466# endif
5467                        o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5468                        //debug_printf_subst("SUBST RES3 '%s'\n", ctx.word.data + pos);
5469                        continue; /* get next char */
5470                }
5471#endif
5472                case ';':
5473#if ENABLE_HUSH_CASE
5474 case_semi:
5475#endif
5476                        if (done_word(&ctx)) {
5477                                goto parse_error;
5478                        }
5479                        done_pipe(&ctx, PIPE_SEQ);
5480#if ENABLE_HUSH_CASE
5481                        /* Eat multiple semicolons, detect
5482                         * whether it means something special */
5483                        while (1) {
5484                                ch = i_peek_and_eat_bkslash_nl(input);
5485                                if (ch != ';')
5486                                        break;
5487                                ch = i_getch(input);
5488                                nommu_addchr(&ctx.as_string, ch);
5489                                if (ctx.ctx_res_w == RES_CASE_BODY) {
5490                                        ctx.ctx_dsemicolon = 1;
5491                                        ctx.ctx_res_w = RES_MATCH;
5492                                        break;
5493                                }
5494                        }
5495#endif
5496 new_cmd:
5497                        /* We just finished a cmd. New one may start
5498                         * with an assignment */
5499                        ctx.is_assignment = MAYBE_ASSIGNMENT;
5500                        debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5501                        continue; /* get next char */
5502                case '&':
5503                        if (done_word(&ctx)) {
5504                                goto parse_error;
5505                        }
5506                        if (next == '&') {
5507                                ch = i_getch(input);
5508                                nommu_addchr(&ctx.as_string, ch);
5509                                done_pipe(&ctx, PIPE_AND);
5510                        } else {
5511                                done_pipe(&ctx, PIPE_BG);
5512                        }
5513                        goto new_cmd;
5514                case '|':
5515                        if (done_word(&ctx)) {
5516                                goto parse_error;
5517                        }
5518#if ENABLE_HUSH_CASE
5519                        if (ctx.ctx_res_w == RES_MATCH)
5520                                break; /* we are in case's "word | word)" */
5521#endif
5522                        if (next == '|') { /* || */
5523                                ch = i_getch(input);
5524                                nommu_addchr(&ctx.as_string, ch);
5525                                done_pipe(&ctx, PIPE_OR);
5526                        } else {
5527                                /* we could pick up a file descriptor choice here
5528                                 * with redirect_opt_num(), but bash doesn't do it.
5529                                 * "echo foo 2| cat" yields "foo 2". */
5530                                done_command(&ctx);
5531                        }
5532                        goto new_cmd;
5533                case '(':
5534#if ENABLE_HUSH_CASE
5535                        /* "case... in [(]word)..." - skip '(' */
5536                        if (ctx.ctx_res_w == RES_MATCH
5537                         && ctx.command->argv == NULL /* not (word|(... */
5538                         && ctx.word.length == 0 /* not word(... */
5539                         && ctx.word.has_quoted_part == 0 /* not ""(... */
5540                        ) {
5541                                continue; /* get next char */
5542                        }
5543#endif
5544                case '{':
5545                        if (parse_group(&ctx, input, ch) != 0) {
5546                                goto parse_error;
5547                        }
5548                        goto new_cmd;
5549                case ')':
5550#if ENABLE_HUSH_CASE
5551                        if (ctx.ctx_res_w == RES_MATCH)
5552                                goto case_semi;
5553#endif
5554                case '}':
5555                        /* proper use of this character is caught by end_trigger:
5556                         * if we see {, we call parse_group(..., end_trigger='}')
5557                         * and it will match } earlier (not here). */
5558                        G.last_exitcode = 2;
5559                        syntax_error_unexpected_ch(ch);
5560                        goto parse_error2;
5561                default:
5562                        if (HUSH_DEBUG)
5563                                bb_error_msg_and_die("BUG: unexpected %c", ch);
5564                }
5565        } /* while (1) */
5566
5567 parse_error:
5568        G.last_exitcode = 1;
5569 parse_error2:
5570        {
5571                struct parse_context *pctx;
5572                IF_HAS_KEYWORDS(struct parse_context *p2;)
5573
5574                /* Clean up allocated tree.
5575                 * Sample for finding leaks on syntax error recovery path.
5576                 * Run it from interactive shell, watch pmap `pidof hush`.
5577                 * while if false; then false; fi; do break; fi
5578                 * Samples to catch leaks at execution:
5579                 * while if (true | { true;}); then echo ok; fi; do break; done
5580                 * while if (true | { true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done
5581                 */
5582                pctx = &ctx;
5583                do {
5584                        /* Update pipe/command counts,
5585                         * otherwise freeing may miss some */
5586                        done_pipe(pctx, PIPE_SEQ);
5587                        debug_printf_clean("freeing list %p from ctx %p\n",
5588                                        pctx->list_head, pctx);
5589                        debug_print_tree(pctx->list_head, 0);
5590                        free_pipe_list(pctx->list_head);
5591                        debug_printf_clean("freed list %p\n", pctx->list_head);
5592#if !BB_MMU
5593                        o_free_unsafe(&pctx->as_string);
5594#endif
5595                        IF_HAS_KEYWORDS(p2 = pctx->stack;)
5596                        if (pctx != &ctx) {
5597                                free(pctx);
5598                        }
5599                        IF_HAS_KEYWORDS(pctx = p2;)
5600                } while (HAS_KEYWORDS && pctx);
5601
5602                o_free(&ctx.word);
5603#if !BB_MMU
5604                if (pstring)
5605                        *pstring = NULL;
5606#endif
5607                debug_leave();
5608                return ERR_PTR;
5609        }
5610}
5611
5612
5613/*** Execution routines ***/
5614
5615/* Expansion can recurse, need forward decls: */
5616#if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
5617#define expand_string_to_string(str, EXP_flags, do_unbackslash) \
5618        expand_string_to_string(str)
5619#endif
5620static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash);
5621#if ENABLE_HUSH_TICK
5622static int process_command_subs(o_string *dest, const char *s);
5623#endif
5624
5625/* expand_strvec_to_strvec() takes a list of strings, expands
5626 * all variable references within and returns a pointer to
5627 * a list of expanded strings, possibly with larger number
5628 * of strings. (Think VAR="a b"; echo $VAR).
5629 * This new list is allocated as a single malloc block.
5630 * NULL-terminated list of char* pointers is at the beginning of it,
5631 * followed by strings themselves.
5632 * Caller can deallocate entire list by single free(list). */
5633
5634/* A horde of its helpers come first: */
5635
5636static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len)
5637{
5638        while (--len >= 0) {
5639                char c = *str++;
5640
5641#if ENABLE_HUSH_BRACE_EXPANSION
5642                if (c == '{' || c == '}') {
5643                        /* { -> \{, } -> \} */
5644                        o_addchr(o, '\\');
5645                        /* And now we want to add { or } and continue:
5646                         *  o_addchr(o, c);
5647                         *  continue;
5648                         * luckily, just falling through achieves this.
5649                         */
5650                }
5651#endif
5652                o_addchr(o, c);
5653                if (c == '\\') {
5654                        /* \z -> \\\z; \<eol> -> \\<eol> */
5655                        o_addchr(o, '\\');
5656                        if (len) {
5657                                len--;
5658                                o_addchr(o, '\\');
5659                                o_addchr(o, *str++);
5660                        }
5661                }
5662        }
5663}
5664
5665/* Store given string, finalizing the word and starting new one whenever
5666 * we encounter IFS char(s). This is used for expanding variable values.
5667 * End-of-string does NOT finalize word: think about 'echo -$VAR-'.
5668 * Return in *ended_with_ifs:
5669 * 1 - ended with IFS char, else 0 (this includes case of empty str).
5670 */
5671static int expand_on_ifs(int *ended_with_ifs, o_string *output, int n, const char *str)
5672{
5673        int last_is_ifs = 0;
5674
5675        while (1) {
5676                int word_len;
5677
5678                if (!*str)  /* EOL - do not finalize word */
5679                        break;
5680                word_len = strcspn(str, G.ifs);
5681                if (word_len) {
5682                        /* We have WORD_LEN leading non-IFS chars */
5683                        if (!(output->o_expflags & EXP_FLAG_GLOB)) {
5684                                o_addblock(output, str, word_len);
5685                        } else {
5686                                /* Protect backslashes against globbing up :)
5687                                 * Example: "v='\*'; echo b$v" prints "b\*"
5688                                 * (and does not try to glob on "*")
5689                                 */
5690                                o_addblock_duplicate_backslash(output, str, word_len);
5691                                /*/ Why can't we do it easier? */
5692                                /*o_addblock(output, str, word_len); - WRONG: "v='\*'; echo Z$v" prints "Z*" instead of "Z\*" */
5693                                /*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */
5694                        }
5695                        last_is_ifs = 0;
5696                        str += word_len;
5697                        if (!*str)  /* EOL - do not finalize word */
5698                                break;
5699                }
5700
5701                /* We know str here points to at least one IFS char */
5702                last_is_ifs = 1;
5703                str += strspn(str, G.ifs_whitespace); /* skip IFS whitespace chars */
5704                if (!*str)  /* EOL - do not finalize word */
5705                        break;
5706
5707                if (G.ifs_whitespace != G.ifs /* usually false ($IFS is usually all whitespace), */
5708                 && strchr(G.ifs, *str)       /* the second check would fail */
5709                ) {
5710                        /* This is a non-whitespace $IFS char */
5711                        /* Skip it and IFS whitespace chars, start new word */
5712                        str++;
5713                        str += strspn(str, G.ifs_whitespace);
5714                        goto new_word;
5715                }
5716
5717                /* Start new word... but not always! */
5718                /* Case "v=' a'; echo ''$v": we do need to finalize empty word: */
5719                if (output->has_quoted_part
5720                /* Case "v=' a'; echo $v":
5721                 * here nothing precedes the space in $v expansion,
5722                 * therefore we should not finish the word
5723                 * (IOW: if there *is* word to finalize, only then do it):
5724                 */
5725                 || (n > 0 && output->data[output->length - 1])
5726                ) {
5727 new_word:
5728                        o_addchr(output, '\0');
5729                        debug_print_list("expand_on_ifs", output, n);
5730                        n = o_save_ptr(output, n);
5731                }
5732        }
5733
5734        if (ended_with_ifs)
5735                *ended_with_ifs = last_is_ifs;
5736        debug_print_list("expand_on_ifs[1]", output, n);
5737        return n;
5738}
5739
5740/* Helper to expand $((...)) and heredoc body. These act as if
5741 * they are in double quotes, with the exception that they are not :).
5742 * Just the rules are similar: "expand only $var and `cmd`"
5743 *
5744 * Returns malloced string.
5745 * As an optimization, we return NULL if expansion is not needed.
5746 */
5747#if !BASH_PATTERN_SUBST
5748/* only ${var/pattern/repl} (its pattern part) needs additional mode */
5749#define encode_then_expand_string(str, process_bkslash, do_unbackslash) \
5750        encode_then_expand_string(str)
5751#endif
5752static char *encode_then_expand_string(const char *str, int process_bkslash, int do_unbackslash)
5753{
5754#if !BASH_PATTERN_SUBST
5755        enum { do_unbackslash = 1 };
5756#endif
5757        char *exp_str;
5758        struct in_str input;
5759        o_string dest = NULL_O_STRING;
5760
5761        if (!strchr(str, '$')
5762         && !strchr(str, '\\')
5763#if ENABLE_HUSH_TICK
5764         && !strchr(str, '`')
5765#endif
5766        ) {
5767                return NULL;
5768        }
5769
5770        /* We need to expand. Example:
5771         * echo $(($a + `echo 1`)) $((1 + $((2)) ))
5772         */
5773        setup_string_in_str(&input, str);
5774        encode_string(NULL, &dest, &input, EOF, process_bkslash);
5775//TODO: error check (encode_string returns 0 on error)?
5776        //bb_error_msg("'%s' -> '%s'", str, dest.data);
5777        exp_str = expand_string_to_string(dest.data,
5778                        do_unbackslash ? EXP_FLAG_ESC_GLOB_CHARS : 0,
5779                        do_unbackslash
5780        );
5781        //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
5782        o_free_unsafe(&dest);
5783        return exp_str;
5784}
5785
5786#if ENABLE_FEATURE_SH_MATH
5787static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
5788{
5789        arith_state_t math_state;
5790        arith_t res;
5791        char *exp_str;
5792
5793        math_state.lookupvar = get_local_var_value;
5794        math_state.setvar = set_local_var_from_halves;
5795        //math_state.endofname = endofname;
5796        exp_str = encode_then_expand_string(arg, /*process_bkslash:*/ 1, /*unbackslash:*/ 1);
5797        res = arith(&math_state, exp_str ? exp_str : arg);
5798        free(exp_str);
5799        if (errmsg_p)
5800                *errmsg_p = math_state.errmsg;
5801        if (math_state.errmsg)
5802                msg_and_die_if_script(math_state.errmsg);
5803        return res;
5804}
5805#endif
5806
5807#if BASH_PATTERN_SUBST
5808/* ${var/[/]pattern[/repl]} helpers */
5809static char *strstr_pattern(char *val, const char *pattern, int *size)
5810{
5811        while (1) {
5812                char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF);
5813                debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end);
5814                if (end) {
5815                        *size = end - val;
5816                        return val;
5817                }
5818                if (*val == '\0')
5819                        return NULL;
5820                /* Optimization: if "*pat" did not match the start of "string",
5821                 * we know that "tring", "ring" etc will not match too:
5822                 */
5823                if (pattern[0] == '*')
5824                        return NULL;
5825                val++;
5826        }
5827}
5828static char *replace_pattern(char *val, const char *pattern, const char *repl, char exp_op)
5829{
5830        char *result = NULL;
5831        unsigned res_len = 0;
5832        unsigned repl_len = strlen(repl);
5833
5834        /* Null pattern never matches, including if "var" is empty */
5835        if (!pattern[0])
5836                return result; /* NULL, no replaces happened */
5837
5838        while (1) {
5839                int size;
5840                char *s = strstr_pattern(val, pattern, &size);
5841                if (!s)
5842                        break;
5843
5844                result = xrealloc(result, res_len + (s - val) + repl_len + 1);
5845                strcpy(mempcpy(result + res_len, val, s - val), repl);
5846                res_len += (s - val) + repl_len;
5847                debug_printf_varexp("val:'%s' s:'%s' result:'%s'\n", val, s, result);
5848
5849                val = s + size;
5850                if (exp_op == '/')
5851                        break;
5852        }
5853        if (*val && result) {
5854                result = xrealloc(result, res_len + strlen(val) + 1);
5855                strcpy(result + res_len, val);
5856                debug_printf_varexp("val:'%s' result:'%s'\n", val, result);
5857        }
5858        debug_printf_varexp("result:'%s'\n", result);
5859        return result;
5860}
5861#endif /* BASH_PATTERN_SUBST */
5862
5863/* Helper:
5864 * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
5865 */
5866static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, char **pp)
5867{
5868        const char *val;
5869        char *to_be_freed;
5870        char *p;
5871        char *var;
5872        char first_char;
5873        char exp_op;
5874        char exp_save = exp_save; /* for compiler */
5875        char *exp_saveptr; /* points to expansion operator */
5876        char *exp_word = exp_word; /* for compiler */
5877        char arg0;
5878
5879        val = NULL;
5880        to_be_freed = NULL;
5881        p = *pp;
5882        *p = '\0'; /* replace trailing SPECIAL_VAR_SYMBOL */
5883        var = arg;
5884        exp_saveptr = arg[1] ? strchr(VAR_ENCODED_SUBST_OPS, arg[1]) : NULL;
5885        arg0 = arg[0];
5886        first_char = arg[0] = arg0 & 0x7f;
5887        exp_op = 0;
5888
5889        if (first_char == '#' && arg[1] /* ${#...} but not ${#} */
5890         && (!exp_saveptr               /* and ( not(${#<op_char>...}) */
5891            || (arg[2] == '\0' && strchr(SPECIAL_VARS_STR, arg[1])) /* or ${#C} "len of $C" ) */
5892            )           /* NB: skipping ^^^specvar check mishandles ${#::2} */
5893        ) {
5894                /* It must be length operator: ${#var} */
5895                var++;
5896                exp_op = 'L';
5897        } else {
5898                /* Maybe handle parameter expansion */
5899                if (exp_saveptr /* if 2nd char is one of expansion operators */
5900                 && strchr(NUMERIC_SPECVARS_STR, first_char) /* 1st char is special variable */
5901                ) {
5902                        /* ${?:0}, ${#[:]%0} etc */
5903                        exp_saveptr = var + 1;
5904                } else {
5905                        /* ${?}, ${var}, ${var:0}, ${var[:]%0} etc */
5906                        exp_saveptr = var+1 + strcspn(var+1, VAR_ENCODED_SUBST_OPS);
5907                }
5908                exp_op = exp_save = *exp_saveptr;
5909                if (exp_op) {
5910                        exp_word = exp_saveptr + 1;
5911                        if (exp_op == ':') {
5912                                exp_op = *exp_word++;
5913//TODO: try ${var:} and ${var:bogus} in non-bash config
5914                                if (BASH_SUBSTR
5915                                 && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op))
5916                                ) {
5917                                        /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */
5918                                        exp_op = ':';
5919                                        exp_word--;
5920                                }
5921                        }
5922                        *exp_saveptr = '\0';
5923                } /* else: it's not an expansion op, but bare ${var} */
5924        }
5925
5926        /* Look up the variable in question */
5927        if (isdigit(var[0])) {
5928                /* parse_dollar should have vetted var for us */
5929                int n = xatoi_positive(var);
5930                if (n < G.global_argc)
5931                        val = G.global_argv[n];
5932                /* else val remains NULL: $N with too big N */
5933        } else {
5934                switch (var[0]) {
5935                case '$': /* pid */
5936                        val = utoa(G.root_pid);
5937                        break;
5938                case '!': /* bg pid */
5939                        val = G.last_bg_pid ? utoa(G.last_bg_pid) : "";
5940                        break;
5941                case '?': /* exitcode */
5942                        val = utoa(G.last_exitcode);
5943                        break;
5944                case '#': /* argc */
5945                        val = utoa(G.global_argc ? G.global_argc-1 : 0);
5946                        break;
5947                default:
5948                        val = get_local_var_value(var);
5949                }
5950        }
5951
5952        /* Handle any expansions */
5953        if (exp_op == 'L') {
5954                reinit_unicode_for_hush();
5955                debug_printf_expand("expand: length(%s)=", val);
5956                val = utoa(val ? unicode_strlen(val) : 0);
5957                debug_printf_expand("%s\n", val);
5958        } else if (exp_op) {
5959                if (exp_op == '%' || exp_op == '#') {
5960                        /* Standard-mandated substring removal ops:
5961                         * ${parameter%word} - remove smallest suffix pattern
5962                         * ${parameter%%word} - remove largest suffix pattern
5963                         * ${parameter#word} - remove smallest prefix pattern
5964                         * ${parameter##word} - remove largest prefix pattern
5965                         *
5966                         * Word is expanded to produce a glob pattern.
5967                         * Then var's value is matched to it and matching part removed.
5968                         */
5969                        if (val && val[0]) {
5970                                char *t;
5971                                char *exp_exp_word;
5972                                char *loc;
5973                                unsigned scan_flags = pick_scan(exp_op, *exp_word);
5974                                if (exp_op == *exp_word)  /* ## or %% */
5975                                        exp_word++;
5976                                debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
5977                                /*
5978                                 * process_bkslash:1 unbackslash:1 breaks this:
5979                                 * a='a\\'; echo ${a%\\\\} # correct output is: a
5980                                 * process_bkslash:1 unbackslash:0 breaks this:
5981                                 * a='a}'; echo ${a%\}}    # correct output is: a
5982                                 */
5983                                exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 0, /*unbackslash:*/ 0);
5984                                if (exp_exp_word)
5985                                        exp_word = exp_exp_word;
5986                                debug_printf_expand("expand: exp_exp_word:'%s'\n", exp_word);
5987                                /* HACK ALERT. We depend here on the fact that
5988                                 * G.global_argv and results of utoa and get_local_var_value
5989                                 * are actually in writable memory:
5990                                 * scan_and_match momentarily stores NULs there. */
5991                                t = (char*)val;
5992                                loc = scan_and_match(t, exp_word, scan_flags);
5993                                debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc);
5994                                free(exp_exp_word);
5995                                if (loc) { /* match was found */
5996                                        if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */
5997                                                val = loc; /* take right part */
5998                                        else /* %[%] */
5999                                                val = to_be_freed = xstrndup(val, loc - val); /* left */
6000                                }
6001                        }
6002                }
6003#if BASH_PATTERN_SUBST
6004                else if (exp_op == '/' || exp_op == '\\') {
6005                        /* It's ${var/[/]pattern[/repl]} thing.
6006                         * Note that in encoded form it has TWO parts:
6007                         * var/pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6008                         * and if // is used, it is encoded as \:
6009                         * var\pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6010                         */
6011                        if (val && val[0]) {
6012                                /* pattern uses non-standard expansion.
6013                                 * repl should be unbackslashed and globbed
6014                                 * by the usual expansion rules:
6015                                 *  >az >bz
6016                                 *  v='a bz'; echo "${v/a*z/a*z}" #prints "a*z"
6017                                 *  v='a bz'; echo "${v/a*z/\z}"  #prints "z"
6018                                 *  v='a bz'; echo ${v/a*z/a*z}   #prints "az"
6019                                 *  v='a bz'; echo ${v/a*z/\z}    #prints "z"
6020                                 * (note that a*z _pattern_ is never globbed!)
6021                                 */
6022                                char *pattern, *repl, *t;
6023                                pattern = encode_then_expand_string(exp_word, /*process_bkslash:*/ 0, /*unbackslash:*/ 0);
6024                                if (!pattern)
6025                                        pattern = xstrdup(exp_word);
6026                                debug_printf_varexp("pattern:'%s'->'%s'\n", exp_word, pattern);
6027                                *p++ = SPECIAL_VAR_SYMBOL;
6028                                exp_word = p;
6029                                p = strchr(p, SPECIAL_VAR_SYMBOL);
6030                                *p = '\0';
6031                                repl = encode_then_expand_string(exp_word, /*process_bkslash:*/ 0, /*unbackslash:*/ 1);
6032                                debug_printf_varexp("repl:'%s'->'%s'\n", exp_word, repl);
6033                                /* HACK ALERT. We depend here on the fact that
6034                                 * G.global_argv and results of utoa and get_local_var_value
6035                                 * are actually in writable memory:
6036                                 * replace_pattern momentarily stores NULs there. */
6037                                t = (char*)val;
6038                                to_be_freed = replace_pattern(t,
6039                                                pattern,
6040                                                (repl ? repl : exp_word),
6041                                                exp_op);
6042                                if (to_be_freed) /* at least one replace happened */
6043                                        val = to_be_freed;
6044                                free(pattern);
6045                                free(repl);
6046                        } else {
6047                                /* Empty variable always gives nothing */
6048                                // "v=''; echo ${v/*/w}" prints "", not "w"
6049                                /* Just skip "replace" part */
6050                                *p++ = SPECIAL_VAR_SYMBOL;
6051                                p = strchr(p, SPECIAL_VAR_SYMBOL);
6052                                *p = '\0';
6053                        }
6054                }
6055#endif /* BASH_PATTERN_SUBST */
6056                else if (exp_op == ':') {
6057#if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH
6058                        /* It's ${var:N[:M]} bashism.
6059                         * Note that in encoded form it has TWO parts:
6060                         * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL>
6061                         */
6062                        arith_t beg, len;
6063                        const char *errmsg;
6064
6065                        beg = expand_and_evaluate_arith(exp_word, &errmsg);
6066                        if (errmsg)
6067                                goto arith_err;
6068                        debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg);
6069                        *p++ = SPECIAL_VAR_SYMBOL;
6070                        exp_word = p;
6071                        p = strchr(p, SPECIAL_VAR_SYMBOL);
6072                        *p = '\0';
6073                        len = expand_and_evaluate_arith(exp_word, &errmsg);
6074                        if (errmsg)
6075                                goto arith_err;
6076                        debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
6077                        if (beg < 0) {
6078                                /* negative beg counts from the end */
6079                                beg = (arith_t)strlen(val) + beg;
6080                                if (beg < 0) /* ${v: -999999} is "" */
6081                                        beg = len = 0;
6082                        }
6083                        debug_printf_varexp("from val:'%s'\n", val);
6084                        if (len < 0) {
6085                                /* in bash, len=-n means strlen()-n */
6086                                len = (arith_t)strlen(val) - beg + len;
6087                                if (len < 0) /* bash compat */
6088                                        msg_and_die_if_script("%s: substring expression < 0", var);
6089                        }
6090                        if (len <= 0 || !val || beg >= strlen(val)) {
6091 arith_err:
6092                                val = NULL;
6093                        } else {
6094                                /* Paranoia. What if user entered 9999999999999
6095                                 * which fits in arith_t but not int? */
6096                                if (len >= INT_MAX)
6097                                        len = INT_MAX;
6098                                val = to_be_freed = xstrndup(val + beg, len);
6099                        }
6100                        debug_printf_varexp("val:'%s'\n", val);
6101#else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */
6102                        msg_and_die_if_script("malformed ${%s:...}", var);
6103                        val = NULL;
6104#endif
6105                } else { /* one of "-=+?" */
6106                        /* Standard-mandated substitution ops:
6107                         * ${var?word} - indicate error if unset
6108                         *      If var is unset, word (or a message indicating it is unset
6109                         *      if word is null) is written to standard error
6110                         *      and the shell exits with a non-zero exit status.
6111                         *      Otherwise, the value of var is substituted.
6112                         * ${var-word} - use default value
6113                         *      If var is unset, word is substituted.
6114                         * ${var=word} - assign and use default value
6115                         *      If var is unset, word is assigned to var.
6116                         *      In all cases, final value of var is substituted.
6117                         * ${var+word} - use alternative value
6118                         *      If var is unset, null is substituted.
6119                         *      Otherwise, word is substituted.
6120                         *
6121                         * Word is subjected to tilde expansion, parameter expansion,
6122                         * command substitution, and arithmetic expansion.
6123                         * If word is not needed, it is not expanded.
6124                         *
6125                         * Colon forms (${var:-word}, ${var:=word} etc) do the same,
6126                         * but also treat null var as if it is unset.
6127                         */
6128                        int use_word = (!val || ((exp_save == ':') && !val[0]));
6129                        if (exp_op == '+')
6130                                use_word = !use_word;
6131                        debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
6132                                        (exp_save == ':') ? "true" : "false", use_word);
6133                        if (use_word) {
6134                                to_be_freed = encode_then_expand_string(exp_word, /*process_bkslash:*/ 1, /*unbackslash:*/ 1);
6135                                if (to_be_freed)
6136                                        exp_word = to_be_freed;
6137                                if (exp_op == '?') {
6138                                        /* mimic bash message */
6139                                        msg_and_die_if_script("%s: %s",
6140                                                var,
6141                                                exp_word[0]
6142                                                ? exp_word
6143                                                : "parameter null or not set"
6144                                                /* ash has more specific messages, a-la: */
6145                                                /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
6146                                        );
6147//TODO: how interactive bash aborts expansion mid-command?
6148                                } else {
6149                                        val = exp_word;
6150                                }
6151
6152                                if (exp_op == '=') {
6153                                        /* ${var=[word]} or ${var:=[word]} */
6154                                        if (isdigit(var[0]) || var[0] == '#') {
6155                                                /* mimic bash message */
6156                                                msg_and_die_if_script("$%s: cannot assign in this way", var);
6157                                                val = NULL;
6158                                        } else {
6159                                                char *new_var = xasprintf("%s=%s", var, val);
6160                                                set_local_var(new_var, /*flag:*/ 0);
6161                                        }
6162                                }
6163                        }
6164                } /* one of "-=+?" */
6165
6166                *exp_saveptr = exp_save;
6167        } /* if (exp_op) */
6168
6169        arg[0] = arg0;
6170
6171        *pp = p;
6172        *to_be_freed_pp = to_be_freed;
6173        return val;
6174}
6175
6176/* Expand all variable references in given string, adding words to list[]
6177 * at n, n+1,... positions. Return updated n (so that list[n] is next one
6178 * to be filled). This routine is extremely tricky: has to deal with
6179 * variables/parameters with whitespace, $* and $@, and constructs like
6180 * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
6181static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6182{
6183        /* output->o_expflags & EXP_FLAG_SINGLEWORD (0x80) if we are in
6184         * expansion of right-hand side of assignment == 1-element expand.
6185         */
6186        char cant_be_null = 0; /* only bit 0x80 matters */
6187        int ended_in_ifs = 0;  /* did last unquoted expansion end with IFS chars? */
6188        char *p;
6189
6190        debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
6191                        !!(output->o_expflags & EXP_FLAG_SINGLEWORD));
6192        debug_print_list("expand_vars_to_list", output, n);
6193        n = o_save_ptr(output, n);
6194        debug_print_list("expand_vars_to_list[0]", output, n);
6195
6196        while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
6197                char first_ch;
6198                char *to_be_freed = NULL;
6199                const char *val = NULL;
6200#if ENABLE_HUSH_TICK
6201                o_string subst_result = NULL_O_STRING;
6202#endif
6203#if ENABLE_FEATURE_SH_MATH
6204                char arith_buf[sizeof(arith_t)*3 + 2];
6205#endif
6206
6207                if (ended_in_ifs) {
6208                        o_addchr(output, '\0');
6209                        n = o_save_ptr(output, n);
6210                        ended_in_ifs = 0;
6211                }
6212
6213                o_addblock(output, arg, p - arg);
6214                debug_print_list("expand_vars_to_list[1]", output, n);
6215                arg = ++p;
6216                p = strchr(p, SPECIAL_VAR_SYMBOL);
6217
6218                /* Fetch special var name (if it is indeed one of them)
6219                 * and quote bit, force the bit on if singleword expansion -
6220                 * important for not getting v=$@ expand to many words. */
6221                first_ch = arg[0] | (output->o_expflags & EXP_FLAG_SINGLEWORD);
6222
6223                /* Is this variable quoted and thus expansion can't be null?
6224                 * "$@" is special. Even if quoted, it can still
6225                 * expand to nothing (not even an empty string),
6226                 * thus it is excluded. */
6227                if ((first_ch & 0x7f) != '@')
6228                        cant_be_null |= first_ch;
6229
6230                switch (first_ch & 0x7f) {
6231                /* Highest bit in first_ch indicates that var is double-quoted */
6232                case '*':
6233                case '@': {
6234                        int i;
6235                        if (!G.global_argv[1])
6236                                break;
6237                        i = 1;
6238                        cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
6239                        if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
6240                                while (G.global_argv[i]) {
6241                                        n = expand_on_ifs(NULL, output, n, G.global_argv[i]);
6242                                        debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
6243                                        if (G.global_argv[i++][0] && G.global_argv[i]) {
6244                                                /* this argv[] is not empty and not last:
6245                                                 * put terminating NUL, start new word */
6246                                                o_addchr(output, '\0');
6247                                                debug_print_list("expand_vars_to_list[2]", output, n);
6248                                                n = o_save_ptr(output, n);
6249                                                debug_print_list("expand_vars_to_list[3]", output, n);
6250                                        }
6251                                }
6252                        } else
6253                        /* If EXP_FLAG_SINGLEWORD, we handle assignment 'a=....$@.....'
6254                         * and in this case should treat it like '$*' - see 'else...' below */
6255                        if (first_ch == (char)('@'|0x80)  /* quoted $@ */
6256                         && !(output->o_expflags & EXP_FLAG_SINGLEWORD) /* not v="$@" case */
6257                        ) {
6258                                while (1) {
6259                                        o_addQstr(output, G.global_argv[i]);
6260                                        if (++i >= G.global_argc)
6261                                                break;
6262                                        o_addchr(output, '\0');
6263                                        debug_print_list("expand_vars_to_list[4]", output, n);
6264                                        n = o_save_ptr(output, n);
6265                                }
6266                        } else { /* quoted $* (or v="$@" case): add as one word */
6267                                while (1) {
6268                                        o_addQstr(output, G.global_argv[i]);
6269                                        if (!G.global_argv[++i])
6270                                                break;
6271                                        if (G.ifs[0])
6272                                                o_addchr(output, G.ifs[0]);
6273                                }
6274                                output->has_quoted_part = 1;
6275                        }
6276                        break;
6277                }
6278                case SPECIAL_VAR_SYMBOL: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
6279                        /* "Empty variable", used to make "" etc to not disappear */
6280                        output->has_quoted_part = 1;
6281                        arg++;
6282                        cant_be_null = 0x80;
6283                        break;
6284                case SPECIAL_VAR_QUOTED_SVS:
6285                        /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_QUOTED_SVS><SPECIAL_VAR_SYMBOL> */
6286                        arg++;
6287                        val = SPECIAL_VAR_SYMBOL_STR;
6288                        break;
6289#if ENABLE_HUSH_TICK
6290                case '`': /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
6291                        *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6292                        arg++;
6293                        /* Can't just stuff it into output o_string,
6294                         * expanded result may need to be globbed
6295                         * and $IFS-split */
6296                        debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
6297                        G.last_exitcode = process_command_subs(&subst_result, arg);
6298                        G.expand_exitcode = G.last_exitcode;
6299                        debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
6300                        val = subst_result.data;
6301                        goto store_val;
6302#endif
6303#if ENABLE_FEATURE_SH_MATH
6304                case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */
6305                        arith_t res;
6306
6307                        arg++; /* skip '+' */
6308                        *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6309                        debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
6310                        res = expand_and_evaluate_arith(arg, NULL);
6311                        debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res);
6312                        sprintf(arith_buf, ARITH_FMT, res);
6313                        val = arith_buf;
6314                        break;
6315                }
6316#endif
6317                default:
6318                        val = expand_one_var(&to_be_freed, arg, &p);
6319 IF_HUSH_TICK(store_val:)
6320                        if (!(first_ch & 0x80)) { /* unquoted $VAR */
6321                                debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
6322                                                !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6323                                if (val && val[0]) {
6324                                        n = expand_on_ifs(&ended_in_ifs, output, n, val);
6325                                        val = NULL;
6326                                }
6327                        } else { /* quoted $VAR, val will be appended below */
6328                                output->has_quoted_part = 1;
6329                                debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
6330                                                !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6331                        }
6332                        break;
6333                } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
6334
6335                if (val && val[0]) {
6336                        o_addQstr(output, val);
6337                }
6338                free(to_be_freed);
6339
6340                /* Restore NULL'ed SPECIAL_VAR_SYMBOL.
6341                 * Do the check to avoid writing to a const string. */
6342                if (*p != SPECIAL_VAR_SYMBOL)
6343                        *p = SPECIAL_VAR_SYMBOL;
6344
6345#if ENABLE_HUSH_TICK
6346                o_free(&subst_result);
6347#endif
6348                arg = ++p;
6349        } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
6350
6351        if (arg[0]) {
6352                if (ended_in_ifs) {
6353                        o_addchr(output, '\0');
6354                        n = o_save_ptr(output, n);
6355                }
6356                debug_print_list("expand_vars_to_list[a]", output, n);
6357                /* this part is literal, and it was already pre-quoted
6358                 * if needed (much earlier), do not use o_addQstr here! */
6359                o_addstr_with_NUL(output, arg);
6360                debug_print_list("expand_vars_to_list[b]", output, n);
6361        } else if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
6362         && !(cant_be_null & 0x80) /* and all vars were not quoted. */
6363        ) {
6364                n--;
6365                /* allow to reuse list[n] later without re-growth */
6366                output->has_empty_slot = 1;
6367        } else {
6368                o_addchr(output, '\0');
6369        }
6370
6371        return n;
6372}
6373
6374static char **expand_variables(char **argv, unsigned expflags)
6375{
6376        int n;
6377        char **list;
6378        o_string output = NULL_O_STRING;
6379
6380        output.o_expflags = expflags;
6381
6382        n = 0;
6383        while (*argv) {
6384                n = expand_vars_to_list(&output, n, *argv);
6385                argv++;
6386        }
6387        debug_print_list("expand_variables", &output, n);
6388
6389        /* output.data (malloced in one block) gets returned in "list" */
6390        list = o_finalize_list(&output, n);
6391        debug_print_strings("expand_variables[1]", list);
6392        return list;
6393}
6394
6395static char **expand_strvec_to_strvec(char **argv)
6396{
6397        return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
6398}
6399
6400#if defined(CMD_SINGLEWORD_NOGLOB)
6401static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
6402{
6403        return expand_variables(argv, EXP_FLAG_SINGLEWORD);
6404}
6405#endif
6406
6407/* Used for expansion of right hand of assignments,
6408 * $((...)), heredocs, variable expansion parts.
6409 *
6410 * NB: should NOT do globbing!
6411 * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*"
6412 */
6413static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash)
6414{
6415#if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
6416        const int do_unbackslash = 1;
6417        const int EXP_flags = EXP_FLAG_ESC_GLOB_CHARS;
6418#endif
6419        char *argv[2], **list;
6420
6421        debug_printf_expand("string_to_string<='%s'\n", str);
6422        /* This is generally an optimization, but it also
6423         * handles "", which otherwise trips over !list[0] check below.
6424         * (is this ever happens that we actually get str="" here?)
6425         */
6426        if (!strchr(str, SPECIAL_VAR_SYMBOL) && !strchr(str, '\\')) {
6427                //TODO: Can use on strings with \ too, just unbackslash() them?
6428                debug_printf_expand("string_to_string(fast)=>'%s'\n", str);
6429                return xstrdup(str);
6430        }
6431
6432        argv[0] = (char*)str;
6433        argv[1] = NULL;
6434        list = expand_variables(argv, EXP_flags | EXP_FLAG_SINGLEWORD);
6435        if (HUSH_DEBUG)
6436                if (!list[0] || list[1])
6437                        bb_error_msg_and_die("BUG in varexp2");
6438        /* actually, just move string 2*sizeof(char*) bytes back */
6439        overlapping_strcpy((char*)list, list[0]);
6440        if (do_unbackslash)
6441                unbackslash((char*)list);
6442        debug_printf_expand("string_to_string=>'%s'\n", (char*)list);
6443        return (char*)list;
6444}
6445
6446#if 0
6447static char* expand_strvec_to_string(char **argv)
6448{
6449        char **list;
6450
6451        list = expand_variables(argv, EXP_FLAG_SINGLEWORD);
6452        /* Convert all NULs to spaces */
6453        if (list[0]) {
6454                int n = 1;
6455                while (list[n]) {
6456                        if (HUSH_DEBUG)
6457                                if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
6458                                        bb_error_msg_and_die("BUG in varexp3");
6459                        /* bash uses ' ' regardless of $IFS contents */
6460                        list[n][-1] = ' ';
6461                        n++;
6462                }
6463        }
6464        overlapping_strcpy((char*)list, list[0] ? list[0] : "");
6465        debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
6466        return (char*)list;
6467}
6468#endif
6469
6470static char **expand_assignments(char **argv, int count)
6471{
6472        int i;
6473        char **p;
6474
6475        G.expanded_assignments = p = NULL;
6476        /* Expand assignments into one string each */
6477        for (i = 0; i < count; i++) {
6478                p = add_string_to_strings(p,
6479                        expand_string_to_string(argv[i],
6480                                EXP_FLAG_ESC_GLOB_CHARS,
6481                                /*unbackslash:*/ 1
6482                        )
6483                );
6484                G.expanded_assignments = p;
6485        }
6486        G.expanded_assignments = NULL;
6487        return p;
6488}
6489
6490
6491static void switch_off_special_sigs(unsigned mask)
6492{
6493        unsigned sig = 0;
6494        while ((mask >>= 1) != 0) {
6495                sig++;
6496                if (!(mask & 1))
6497                        continue;
6498#if ENABLE_HUSH_TRAP
6499                if (G_traps) {
6500                        if (G_traps[sig] && !G_traps[sig][0])
6501                                /* trap is '', has to remain SIG_IGN */
6502                                continue;
6503                        free(G_traps[sig]);
6504                        G_traps[sig] = NULL;
6505                }
6506#endif
6507                /* We are here only if no trap or trap was not '' */
6508                install_sighandler(sig, SIG_DFL);
6509        }
6510}
6511
6512#if BB_MMU
6513/* never called */
6514void re_execute_shell(char ***to_free, const char *s,
6515                char *g_argv0, char **g_argv,
6516                char **builtin_argv) NORETURN;
6517
6518static void reset_traps_to_defaults(void)
6519{
6520        /* This function is always called in a child shell
6521         * after fork (not vfork, NOMMU doesn't use this function).
6522         */
6523        IF_HUSH_TRAP(unsigned sig;)
6524        unsigned mask;
6525
6526        /* Child shells are not interactive.
6527         * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
6528         * Testcase: (while :; do :; done) + ^Z should background.
6529         * Same goes for SIGTERM, SIGHUP, SIGINT.
6530         */
6531        mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask;
6532        if (!G_traps && !mask)
6533                return; /* already no traps and no special sigs */
6534
6535        /* Switch off special sigs */
6536        switch_off_special_sigs(mask);
6537# if ENABLE_HUSH_JOB
6538        G_fatal_sig_mask = 0;
6539# endif
6540        G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS;
6541        /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS
6542         * remain set in G.special_sig_mask */
6543
6544# if ENABLE_HUSH_TRAP
6545        if (!G_traps)
6546                return;
6547
6548        /* Reset all sigs to default except ones with empty traps */
6549        for (sig = 0; sig < NSIG; sig++) {
6550                if (!G_traps[sig])
6551                        continue; /* no trap: nothing to do */
6552                if (!G_traps[sig][0])
6553                        continue; /* empty trap: has to remain SIG_IGN */
6554                /* sig has non-empty trap, reset it: */
6555                free(G_traps[sig]);
6556                G_traps[sig] = NULL;
6557                /* There is no signal for trap 0 (EXIT) */
6558                if (sig == 0)
6559                        continue;
6560                install_sighandler(sig, pick_sighandler(sig));
6561        }
6562# endif
6563}
6564
6565#else /* !BB_MMU */
6566
6567static void re_execute_shell(char ***to_free, const char *s,
6568                char *g_argv0, char **g_argv,
6569                char **builtin_argv) NORETURN;
6570static void re_execute_shell(char ***to_free, const char *s,
6571                char *g_argv0, char **g_argv,
6572                char **builtin_argv)
6573{
6574# define NOMMU_HACK_FMT ("-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x"))
6575        /* delims + 2 * (number of bytes in printed hex numbers) */
6576        char param_buf[sizeof(NOMMU_HACK_FMT) + 2 * (sizeof(int)*6 + sizeof(long long)*1)];
6577        char *heredoc_argv[4];
6578        struct variable *cur;
6579# if ENABLE_HUSH_FUNCTIONS
6580        struct function *funcp;
6581# endif
6582        char **argv, **pp;
6583        unsigned cnt;
6584        unsigned long long empty_trap_mask;
6585
6586        if (!g_argv0) { /* heredoc */
6587                argv = heredoc_argv;
6588                argv[0] = (char *) G.argv0_for_re_execing;
6589                argv[1] = (char *) "-<";
6590                argv[2] = (char *) s;
6591                argv[3] = NULL;
6592                pp = &argv[3]; /* used as pointer to empty environment */
6593                goto do_exec;
6594        }
6595
6596        cnt = 0;
6597        pp = builtin_argv;
6598        if (pp) while (*pp++)
6599                cnt++;
6600
6601        empty_trap_mask = 0;
6602        if (G_traps) {
6603                int sig;
6604                for (sig = 1; sig < NSIG; sig++) {
6605                        if (G_traps[sig] && !G_traps[sig][0])
6606                                empty_trap_mask |= 1LL << sig;
6607                }
6608        }
6609
6610        sprintf(param_buf, NOMMU_HACK_FMT
6611                        , (unsigned) G.root_pid
6612                        , (unsigned) G.root_ppid
6613                        , (unsigned) G.last_bg_pid
6614                        , (unsigned) G.last_exitcode
6615                        , cnt
6616                        , empty_trap_mask
6617                        IF_HUSH_LOOPS(, G.depth_of_loop)
6618                        );
6619# undef NOMMU_HACK_FMT
6620        /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<etc...> <vars...> <funcs...>
6621         * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL
6622         */
6623        cnt += 6;
6624        for (cur = G.top_var; cur; cur = cur->next) {
6625                if (!cur->flg_export || cur->flg_read_only)
6626                        cnt += 2;
6627        }
6628# if ENABLE_HUSH_FUNCTIONS
6629        for (funcp = G.top_func; funcp; funcp = funcp->next)
6630                cnt += 3;
6631# endif
6632        pp = g_argv;
6633        while (*pp++)
6634                cnt++;
6635        *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
6636        *pp++ = (char *) G.argv0_for_re_execing;
6637        *pp++ = param_buf;
6638        for (cur = G.top_var; cur; cur = cur->next) {
6639                if (strcmp(cur->varstr, hush_version_str) == 0)
6640                        continue;
6641                if (cur->flg_read_only) {
6642                        *pp++ = (char *) "-R";
6643                        *pp++ = cur->varstr;
6644                } else if (!cur->flg_export) {
6645                        *pp++ = (char *) "-V";
6646                        *pp++ = cur->varstr;
6647                }
6648        }
6649# if ENABLE_HUSH_FUNCTIONS
6650        for (funcp = G.top_func; funcp; funcp = funcp->next) {
6651                *pp++ = (char *) "-F";
6652                *pp++ = funcp->name;
6653                *pp++ = funcp->body_as_string;
6654        }
6655# endif
6656        /* We can pass activated traps here. Say, -Tnn:trap_string
6657         *
6658         * However, POSIX says that subshells reset signals with traps
6659         * to SIG_DFL.
6660         * I tested bash-3.2 and it not only does that with true subshells
6661         * of the form ( list ), but with any forked children shells.
6662         * I set trap "echo W" WINCH; and then tried:
6663         *
6664         * { echo 1; sleep 20; echo 2; } &
6665         * while true; do echo 1; sleep 20; echo 2; break; done &
6666         * true | { echo 1; sleep 20; echo 2; } | cat
6667         *
6668         * In all these cases sending SIGWINCH to the child shell
6669         * did not run the trap. If I add trap "echo V" WINCH;
6670         * _inside_ group (just before echo 1), it works.
6671         *
6672         * I conclude it means we don't need to pass active traps here.
6673         */
6674        *pp++ = (char *) "-c";
6675        *pp++ = (char *) s;
6676        if (builtin_argv) {
6677                while (*++builtin_argv)
6678                        *pp++ = *builtin_argv;
6679                *pp++ = (char *) "";
6680        }
6681        *pp++ = g_argv0;
6682        while (*g_argv)
6683                *pp++ = *g_argv++;
6684        /* *pp = NULL; - is already there */
6685        pp = environ;
6686
6687 do_exec:
6688        debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
6689        /* Don't propagate SIG_IGN to the child */
6690        if (SPECIAL_JOBSTOP_SIGS != 0)
6691                switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
6692        execve(bb_busybox_exec_path, argv, pp);
6693        /* Fallback. Useful for init=/bin/hush usage etc */
6694        if (argv[0][0] == '/')
6695                execve(argv[0], argv, pp);
6696        xfunc_error_retval = 127;
6697        bb_error_msg_and_die("can't re-execute the shell");
6698}
6699#endif  /* !BB_MMU */
6700
6701
6702static int run_and_free_list(struct pipe *pi);
6703
6704/* Executing from string: eval, sh -c '...'
6705 *          or from file: /etc/profile, . file, sh <script>, sh (intereactive)
6706 * end_trigger controls how often we stop parsing
6707 * NUL: parse all, execute, return
6708 * ';': parse till ';' or newline, execute, repeat till EOF
6709 */
6710static void parse_and_run_stream(struct in_str *inp, int end_trigger)
6711{
6712        /* Why we need empty flag?
6713         * An obscure corner case "false; ``; echo $?":
6714         * empty command in `` should still set $? to 0.
6715         * But we can't just set $? to 0 at the start,
6716         * this breaks "false; echo `echo $?`" case.
6717         */
6718        bool empty = 1;
6719        while (1) {
6720                struct pipe *pipe_list;
6721
6722#if ENABLE_HUSH_INTERACTIVE
6723                if (end_trigger == ';') {
6724                        G.promptmode = 0; /* PS1 */
6725                        debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
6726                }
6727#endif
6728                pipe_list = parse_stream(NULL, inp, end_trigger);
6729                if (!pipe_list || pipe_list == ERR_PTR) { /* EOF/error */
6730                        /* If we are in "big" script
6731                         * (not in `cmd` or something similar)...
6732                         */
6733                        if (pipe_list == ERR_PTR && end_trigger == ';') {
6734                                /* Discard cached input (rest of line) */
6735                                int ch = inp->last_char;
6736                                while (ch != EOF && ch != '\n') {
6737                                        //bb_error_msg("Discarded:'%c'", ch);
6738                                        ch = i_getch(inp);
6739                                }
6740                                /* Force prompt */
6741                                inp->p = NULL;
6742                                /* This stream isn't empty */
6743                                empty = 0;
6744                                continue;
6745                        }
6746                        if (!pipe_list && empty)
6747                                G.last_exitcode = 0;
6748                        break;
6749                }
6750                debug_print_tree(pipe_list, 0);
6751                debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
6752                run_and_free_list(pipe_list);
6753                empty = 0;
6754                if (G_flag_return_in_progress == 1)
6755                        break;
6756        }
6757}
6758
6759static void parse_and_run_string(const char *s)
6760{
6761        struct in_str input;
6762        //IF_HUSH_LINENO_VAR(unsigned sv = G.lineno;)
6763
6764        setup_string_in_str(&input, s);
6765        parse_and_run_stream(&input, '\0');
6766        //IF_HUSH_LINENO_VAR(G.lineno = sv;)
6767}
6768
6769static void parse_and_run_file(FILE *f)
6770{
6771        struct in_str input;
6772        IF_HUSH_LINENO_VAR(unsigned sv = G.lineno;)
6773
6774        IF_HUSH_LINENO_VAR(G.lineno = 1;)
6775        setup_file_in_str(&input, f);
6776        parse_and_run_stream(&input, ';');
6777        IF_HUSH_LINENO_VAR(G.lineno = sv;)
6778}
6779
6780#if ENABLE_HUSH_TICK
6781static FILE *generate_stream_from_string(const char *s, pid_t *pid_p)
6782{
6783        pid_t pid;
6784        int channel[2];
6785# if !BB_MMU
6786        char **to_free = NULL;
6787# endif
6788
6789        xpipe(channel);
6790        pid = BB_MMU ? xfork() : xvfork();
6791        if (pid == 0) { /* child */
6792                disable_restore_tty_pgrp_on_exit();
6793                /* Process substitution is not considered to be usual
6794                 * 'command execution'.
6795                 * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
6796                 */
6797                bb_signals(0
6798                        + (1 << SIGTSTP)
6799                        + (1 << SIGTTIN)
6800                        + (1 << SIGTTOU)
6801                        , SIG_IGN);
6802                CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
6803                close(channel[0]); /* NB: close _first_, then move fd! */
6804                xmove_fd(channel[1], 1);
6805                /* Prevent it from trying to handle ctrl-z etc */
6806                IF_HUSH_JOB(G.run_list_level = 1;)
6807# if ENABLE_HUSH_TRAP
6808                /* Awful hack for `trap` or $(trap).
6809                 *
6810                 * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
6811                 * contains an example where "trap" is executed in a subshell:
6812                 *
6813                 * save_traps=$(trap)
6814                 * ...
6815                 * eval "$save_traps"
6816                 *
6817                 * Standard does not say that "trap" in subshell shall print
6818                 * parent shell's traps. It only says that its output
6819                 * must have suitable form, but then, in the above example
6820                 * (which is not supposed to be normative), it implies that.
6821                 *
6822                 * bash (and probably other shell) does implement it
6823                 * (traps are reset to defaults, but "trap" still shows them),
6824                 * but as a result, "trap" logic is hopelessly messed up:
6825                 *
6826                 * # trap
6827                 * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
6828                 * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
6829                 * # true | trap   <--- trap is in subshell - no output (ditto)
6830                 * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
6831                 * trap -- 'echo Ho' SIGWINCH
6832                 * # echo `(trap)`         <--- in subshell in subshell - output
6833                 * trap -- 'echo Ho' SIGWINCH
6834                 * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
6835                 * trap -- 'echo Ho' SIGWINCH
6836                 *
6837                 * The rules when to forget and when to not forget traps
6838                 * get really complex and nonsensical.
6839                 *
6840                 * Our solution: ONLY bare $(trap) or `trap` is special.
6841                 */
6842                s = skip_whitespace(s);
6843                if (is_prefixed_with(s, "trap")
6844                 && skip_whitespace(s + 4)[0] == '\0'
6845                ) {
6846                        static const char *const argv[] = { NULL, NULL };
6847                        builtin_trap((char**)argv);
6848                        fflush_all(); /* important */
6849                        _exit(0);
6850                }
6851# endif
6852# if BB_MMU
6853                reset_traps_to_defaults();
6854                parse_and_run_string(s);
6855                _exit(G.last_exitcode);
6856# else
6857        /* We re-execute after vfork on NOMMU. This makes this script safe:
6858         * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG
6859         * huge=`cat BIG` # was blocking here forever
6860         * echo OK
6861         */
6862                re_execute_shell(&to_free,
6863                                s,
6864                                G.global_argv[0],
6865                                G.global_argv + 1,
6866                                NULL);
6867# endif
6868        }
6869
6870        /* parent */
6871        *pid_p = pid;
6872# if ENABLE_HUSH_FAST
6873        G.count_SIGCHLD++;
6874//bb_error_msg("[%d] fork in generate_stream_from_string:"
6875//              " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d",
6876//              getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
6877# endif
6878        enable_restore_tty_pgrp_on_exit();
6879# if !BB_MMU
6880        free(to_free);
6881# endif
6882        close(channel[1]);
6883        return remember_FILE(xfdopen_for_read(channel[0]));
6884}
6885
6886/* Return code is exit status of the process that is run. */
6887static int process_command_subs(o_string *dest, const char *s)
6888{
6889        FILE *fp;
6890        pid_t pid;
6891        int status, ch, eol_cnt;
6892
6893        fp = generate_stream_from_string(s, &pid);
6894
6895        /* Now send results of command back into original context */
6896        eol_cnt = 0;
6897        while ((ch = getc(fp)) != EOF) {
6898                if (ch == '\0')
6899                        continue;
6900                if (ch == '\n') {
6901                        eol_cnt++;
6902                        continue;
6903                }
6904                while (eol_cnt) {
6905                        o_addchr(dest, '\n');
6906                        eol_cnt--;
6907                }
6908                o_addQchr(dest, ch);
6909        }
6910
6911        debug_printf("done reading from `cmd` pipe, closing it\n");
6912        fclose_and_forget(fp);
6913        /* We need to extract exitcode. Test case
6914         * "true; echo `sleep 1; false` $?"
6915         * should print 1 */
6916        safe_waitpid(pid, &status, 0);
6917        debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status));
6918        return WEXITSTATUS(status);
6919}
6920#endif /* ENABLE_HUSH_TICK */
6921
6922
6923static void setup_heredoc(struct redir_struct *redir)
6924{
6925        struct fd_pair pair;
6926        pid_t pid;
6927        int len, written;
6928        /* the _body_ of heredoc (misleading field name) */
6929        const char *heredoc = redir->rd_filename;
6930        char *expanded;
6931#if !BB_MMU
6932        char **to_free;
6933#endif
6934
6935        expanded = NULL;
6936        if (!(redir->rd_dup & HEREDOC_QUOTED)) {
6937                expanded = encode_then_expand_string(heredoc, /*process_bkslash:*/ 1, /*unbackslash:*/ 1);
6938                if (expanded)
6939                        heredoc = expanded;
6940        }
6941        len = strlen(heredoc);
6942
6943        close(redir->rd_fd); /* often saves dup2+close in xmove_fd */
6944        xpiped_pair(pair);
6945        xmove_fd(pair.rd, redir->rd_fd);
6946
6947        /* Try writing without forking. Newer kernels have
6948         * dynamically growing pipes. Must use non-blocking write! */
6949        ndelay_on(pair.wr);
6950        while (1) {
6951                written = write(pair.wr, heredoc, len);
6952                if (written <= 0)
6953                        break;
6954                len -= written;
6955                if (len == 0) {
6956                        close(pair.wr);
6957                        free(expanded);
6958                        return;
6959                }
6960                heredoc += written;
6961        }
6962        ndelay_off(pair.wr);
6963
6964        /* Okay, pipe buffer was not big enough */
6965        /* Note: we must not create a stray child (bastard? :)
6966         * for the unsuspecting parent process. Child creates a grandchild
6967         * and exits before parent execs the process which consumes heredoc
6968         * (that exec happens after we return from this function) */
6969#if !BB_MMU
6970        to_free = NULL;
6971#endif
6972        pid = xvfork();
6973        if (pid == 0) {
6974                /* child */
6975                disable_restore_tty_pgrp_on_exit();
6976                pid = BB_MMU ? xfork() : xvfork();
6977                if (pid != 0)
6978                        _exit(0);
6979                /* grandchild */
6980                close(redir->rd_fd); /* read side of the pipe */
6981#if BB_MMU
6982                full_write(pair.wr, heredoc, len); /* may loop or block */
6983                _exit(0);
6984#else
6985                /* Delegate blocking writes to another process */
6986                xmove_fd(pair.wr, STDOUT_FILENO);
6987                re_execute_shell(&to_free, heredoc, NULL, NULL, NULL);
6988#endif
6989        }
6990        /* parent */
6991#if ENABLE_HUSH_FAST
6992        G.count_SIGCHLD++;
6993//bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
6994#endif
6995        enable_restore_tty_pgrp_on_exit();
6996#if !BB_MMU
6997        free(to_free);
6998#endif
6999        close(pair.wr);
7000        free(expanded);
7001        wait(NULL); /* wait till child has died */
7002}
7003
7004struct squirrel {
7005        int orig_fd;
7006        int moved_to;
7007        /* moved_to = n: fd was moved to n; restore back to orig_fd after redir */
7008        /* moved_to = -1: fd was opened by redirect; close orig_fd after redir */
7009};
7010
7011static struct squirrel *append_squirrel(struct squirrel *sq, int i, int orig, int moved)
7012{
7013        sq = xrealloc(sq, (i + 2) * sizeof(sq[0]));
7014        sq[i].orig_fd = orig;
7015        sq[i].moved_to = moved;
7016        sq[i+1].orig_fd = -1; /* end marker */
7017        return sq;
7018}
7019
7020static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
7021{
7022        int moved_to;
7023        int i;
7024
7025        i = 0;
7026        if (sq) for (; sq[i].orig_fd >= 0; i++) {
7027                /* If we collide with an already moved fd... */
7028                if (fd == sq[i].moved_to) {
7029                        sq[i].moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
7030                        debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, sq[i].moved_to);
7031                        if (sq[i].moved_to < 0) /* what? */
7032                                xfunc_die();
7033                        return sq;
7034                }
7035                if (fd == sq[i].orig_fd) {
7036                        /* Example: echo Hello >/dev/null 1>&2 */
7037                        debug_printf_redir("redirect_fd %d: already moved\n", fd);
7038                        return sq;
7039                }
7040        }
7041
7042        /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */
7043        moved_to = dup_CLOEXEC(fd, avoid_fd);
7044        debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to);
7045        if (moved_to < 0 && errno != EBADF)
7046                xfunc_die();
7047        return append_squirrel(sq, i, fd, moved_to);
7048}
7049
7050static struct squirrel *add_squirrel_closed(struct squirrel *sq, int fd)
7051{
7052        int i;
7053
7054        i = 0;
7055        if (sq) for (; sq[i].orig_fd >= 0; i++) {
7056                /* If we collide with an already moved fd... */
7057                if (fd == sq[i].orig_fd) {
7058                        /* Examples:
7059                         * "echo 3>FILE 3>&- 3>FILE"
7060                         * "echo 3>&- 3>FILE"
7061                         * No need for last redirect to insert
7062                         * another "need to close 3" indicator.
7063                         */
7064                        debug_printf_redir("redirect_fd %d: already moved or closed\n", fd);
7065                        return sq;
7066                }
7067        }
7068
7069        debug_printf_redir("redirect_fd %d: previous fd was closed\n", fd);
7070        return append_squirrel(sq, i, fd, -1);
7071}
7072
7073/* fd: redirect wants this fd to be used (e.g. 3>file).
7074 * Move all conflicting internally used fds,
7075 * and remember them so that we can restore them later.
7076 */
7077static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp)
7078{
7079        if (avoid_fd < 9) /* the important case here is that it can be -1 */
7080                avoid_fd = 9;
7081
7082#if ENABLE_HUSH_INTERACTIVE
7083        if (fd == G.interactive_fd) {
7084                /* Testcase: "ls -l /proc/$$/fd 255>&-" should work */
7085                G.interactive_fd = xdup_CLOEXEC_and_close(G.interactive_fd, avoid_fd);
7086                debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G.interactive_fd);
7087                return 1; /* "we closed fd" */
7088        }
7089#endif
7090        /* Are we called from setup_redirects(squirrel==NULL)? Two cases:
7091         * (1) Redirect in a forked child. No need to save FILEs' fds,
7092         * we aren't going to use them anymore, ok to trash.
7093         * (2) "exec 3>FILE". Bummer. We can save script FILEs' fds,
7094         * but how are we doing to restore them?
7095         * "fileno(fd) = new_fd" can't be done.
7096         */
7097        if (!sqp)
7098                return 0;
7099
7100        /* If this one of script's fds? */
7101        if (save_FILEs_on_redirect(fd, avoid_fd))
7102                return 1; /* yes. "we closed fd" */
7103
7104        /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
7105        *sqp = add_squirrel(*sqp, fd, avoid_fd);
7106        return 0; /* "we did not close fd" */
7107}
7108
7109static void restore_redirects(struct squirrel *sq)
7110{
7111        if (sq) {
7112                int i;
7113                for (i = 0; sq[i].orig_fd >= 0; i++) {
7114                        if (sq[i].moved_to >= 0) {
7115                                /* We simply die on error */
7116                                debug_printf_redir("restoring redirected fd from %d to %d\n", sq[i].moved_to, sq[i].orig_fd);
7117                                xmove_fd(sq[i].moved_to, sq[i].orig_fd);
7118                        } else {
7119                                /* cmd1 9>FILE; cmd2_should_see_fd9_closed */
7120                                debug_printf_redir("restoring redirected fd %d: closing it\n", sq[i].orig_fd);
7121                                close(sq[i].orig_fd);
7122                        }
7123                }
7124                free(sq);
7125        }
7126
7127        /* If moved, G.interactive_fd stays on new fd, not restoring it */
7128
7129        restore_redirected_FILEs();
7130}
7131
7132#if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
7133static void close_saved_fds_and_FILE_fds(void)
7134{
7135        if (G_interactive_fd)
7136                close(G_interactive_fd);
7137        close_all_FILE_list();
7138}
7139#endif
7140
7141static int internally_opened_fd(int fd, struct squirrel *sq)
7142{
7143        int i;
7144
7145#if ENABLE_HUSH_INTERACTIVE
7146        if (fd == G.interactive_fd)
7147                return 1;
7148#endif
7149        /* If this one of script's fds? */
7150        if (fd_in_FILEs(fd))
7151                return 1;
7152
7153        if (sq) for (i = 0; sq[i].orig_fd >= 0; i++) {
7154                if (fd == sq[i].moved_to)
7155                        return 1;
7156        }
7157        return 0;
7158}
7159
7160/* squirrel != NULL means we squirrel away copies of stdin, stdout,
7161 * and stderr if they are redirected. */
7162static int setup_redirects(struct command *prog, struct squirrel **sqp)
7163{
7164        struct redir_struct *redir;
7165
7166        for (redir = prog->redirects; redir; redir = redir->next) {
7167                int newfd;
7168                int closed;
7169
7170                if (redir->rd_type == REDIRECT_HEREDOC2) {
7171                        /* "rd_fd<<HERE" case */
7172                        save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp);
7173                        /* for REDIRECT_HEREDOC2, rd_filename holds _contents_
7174                         * of the heredoc */
7175                        debug_printf_parse("set heredoc '%s'\n",
7176                                        redir->rd_filename);
7177                        setup_heredoc(redir);
7178                        continue;
7179                }
7180
7181                if (redir->rd_dup == REDIRFD_TO_FILE) {
7182                        /* "rd_fd<*>file" case (<*> is <,>,>>,<>) */
7183                        char *p;
7184                        int mode;
7185
7186                        if (redir->rd_filename == NULL) {
7187                                /*
7188                                 * Examples:
7189                                 * "cmd >" (no filename)
7190                                 * "cmd > <file" (2nd redirect starts too early)
7191                                 */
7192                                syntax_error("invalid redirect");
7193                                continue;
7194                        }
7195                        mode = redir_table[redir->rd_type].mode;
7196                        p = expand_string_to_string(redir->rd_filename,
7197                                EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
7198                        newfd = open_or_warn(p, mode);
7199                        free(p);
7200                        if (newfd < 0) {
7201                                /* Error message from open_or_warn can be lost
7202                                 * if stderr has been redirected, but bash
7203                                 * and ash both lose it as well
7204                                 * (though zsh doesn't!)
7205                                 */
7206                                return 1;
7207                        }
7208                        if (newfd == redir->rd_fd && sqp) {
7209                                /* open() gave us precisely the fd we wanted.
7210                                 * This means that this fd was not busy
7211                                 * (not opened to anywhere).
7212                                 * Remember to close it on restore:
7213                                 */
7214                                *sqp = add_squirrel_closed(*sqp, newfd);
7215                                debug_printf_redir("redir to previously closed fd %d\n", newfd);
7216                        }
7217                } else {
7218                        /* "rd_fd>&rd_dup" or "rd_fd>&-" case */
7219                        newfd = redir->rd_dup;
7220                }
7221
7222                if (newfd == redir->rd_fd)
7223                        continue;
7224
7225                /* if "N>FILE": move newfd to redir->rd_fd */
7226                /* if "N>&M": dup newfd to redir->rd_fd */
7227                /* if "N>&-": close redir->rd_fd (newfd is REDIRFD_CLOSE) */
7228
7229                closed = save_fd_on_redirect(redir->rd_fd, /*avoid:*/ newfd, sqp);
7230                if (newfd == REDIRFD_CLOSE) {
7231                        /* "N>&-" means "close me" */
7232                        if (!closed) {
7233                                /* ^^^ optimization: saving may already
7234                                 * have closed it. If not... */
7235                                close(redir->rd_fd);
7236                        }
7237                        /* Sometimes we do another close on restore, getting EBADF.
7238                         * Consider "echo 3>FILE 3>&-"
7239                         * first redirect remembers "need to close 3",
7240                         * and second redirect closes 3! Restore code then closes 3 again.
7241                         */
7242                } else {
7243                        /* if newfd is a script fd or saved fd, simulate EBADF */
7244                        if (internally_opened_fd(newfd, sqp ? *sqp : NULL)) {
7245                                //errno = EBADF;
7246                                //bb_perror_msg_and_die("can't duplicate file descriptor");
7247                                newfd = -1; /* same effect as code above */
7248                        }
7249                        xdup2(newfd, redir->rd_fd);
7250                        if (redir->rd_dup == REDIRFD_TO_FILE)
7251                                /* "rd_fd > FILE" */
7252                                close(newfd);
7253                        /* else: "rd_fd > rd_dup" */
7254                }
7255        }
7256        return 0;
7257}
7258
7259static char *find_in_path(const char *arg)
7260{
7261        char *ret = NULL;
7262        const char *PATH = get_local_var_value("PATH");
7263
7264        if (!PATH)
7265                return NULL;
7266
7267        while (1) {
7268                const char *end = strchrnul(PATH, ':');
7269                int sz = end - PATH; /* must be int! */
7270
7271                free(ret);
7272                if (sz != 0) {
7273                        ret = xasprintf("%.*s/%s", sz, PATH, arg);
7274                } else {
7275                        /* We have xxx::yyyy in $PATH,
7276                         * it means "use current dir" */
7277                        ret = xstrdup(arg);
7278                }
7279                if (access(ret, F_OK) == 0)
7280                        break;
7281
7282                if (*end == '\0') {
7283                        free(ret);
7284                        return NULL;
7285                }
7286                PATH = end + 1;
7287        }
7288
7289        return ret;
7290}
7291
7292static const struct built_in_command *find_builtin_helper(const char *name,
7293                const struct built_in_command *x,
7294                const struct built_in_command *end)
7295{
7296        while (x != end) {
7297                if (strcmp(name, x->b_cmd) != 0) {
7298                        x++;
7299                        continue;
7300                }
7301                debug_printf_exec("found builtin '%s'\n", name);
7302                return x;
7303        }
7304        return NULL;
7305}
7306static const struct built_in_command *find_builtin1(const char *name)
7307{
7308        return find_builtin_helper(name, bltins1, &bltins1[ARRAY_SIZE(bltins1)]);
7309}
7310static const struct built_in_command *find_builtin(const char *name)
7311{
7312        const struct built_in_command *x = find_builtin1(name);
7313        if (x)
7314                return x;
7315        return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
7316}
7317
7318static void remove_nested_vars(void)
7319{
7320        struct variable *cur;
7321        struct variable **cur_pp;
7322
7323        cur_pp = &G.top_var;
7324        while ((cur = *cur_pp) != NULL) {
7325                if (cur->var_nest_level <= G.var_nest_level) {
7326                        cur_pp = &cur->next;
7327                        continue;
7328                }
7329                /* Unexport */
7330                if (cur->flg_export) {
7331                        debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7332                        bb_unsetenv(cur->varstr);
7333                }
7334                /* Remove from global list */
7335                *cur_pp = cur->next;
7336                /* Free */
7337                if (!cur->max_len) {
7338                        debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7339                        free(cur->varstr);
7340                }
7341                free(cur);
7342        }
7343}
7344
7345static void enter_var_nest_level(void)
7346{
7347        G.var_nest_level++;
7348        debug_printf_env("var_nest_level++ %u\n", G.var_nest_level);
7349
7350        /* Try: f() { echo -n .; f; }; f
7351         * struct variable::var_nest_level is uint16_t,
7352         * thus limiting recursion to < 2^16.
7353         * In any case, with 8 Mbyte stack SEGV happens
7354         * not too long after 2^16 recursions anyway.
7355         */
7356        if (G.var_nest_level > 0xff00)
7357                bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level);
7358}
7359
7360static void leave_var_nest_level(void)
7361{
7362        G.var_nest_level--;
7363        debug_printf_env("var_nest_level-- %u\n", G.var_nest_level);
7364        if (HUSH_DEBUG && (int)G.var_nest_level < 0)
7365                bb_error_msg_and_die("BUG: nesting underflow");
7366
7367        remove_nested_vars();
7368}
7369
7370#if ENABLE_HUSH_FUNCTIONS
7371static struct function **find_function_slot(const char *name)
7372{
7373        struct function *funcp;
7374        struct function **funcpp = &G.top_func;
7375
7376        while ((funcp = *funcpp) != NULL) {
7377                if (strcmp(name, funcp->name) == 0) {
7378                        debug_printf_exec("found function '%s'\n", name);
7379                        break;
7380                }
7381                funcpp = &funcp->next;
7382        }
7383        return funcpp;
7384}
7385
7386static ALWAYS_INLINE const struct function *find_function(const char *name)
7387{
7388        const struct function *funcp = *find_function_slot(name);
7389        return funcp;
7390}
7391
7392/* Note: takes ownership on name ptr */
7393static struct function *new_function(char *name)
7394{
7395        struct function **funcpp = find_function_slot(name);
7396        struct function *funcp = *funcpp;
7397
7398        if (funcp != NULL) {
7399                struct command *cmd = funcp->parent_cmd;
7400                debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd);
7401                if (!cmd) {
7402                        debug_printf_exec("freeing & replacing function '%s'\n", funcp->name);
7403                        free(funcp->name);
7404                        /* Note: if !funcp->body, do not free body_as_string!
7405                         * This is a special case of "-F name body" function:
7406                         * body_as_string was not malloced! */
7407                        if (funcp->body) {
7408                                free_pipe_list(funcp->body);
7409# if !BB_MMU
7410                                free(funcp->body_as_string);
7411# endif
7412                        }
7413                } else {
7414                        debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp->name);
7415                        cmd->argv[0] = funcp->name;
7416                        cmd->group = funcp->body;
7417# if !BB_MMU
7418                        cmd->group_as_string = funcp->body_as_string;
7419# endif
7420                }
7421        } else {
7422                debug_printf_exec("remembering new function '%s'\n", name);
7423                funcp = *funcpp = xzalloc(sizeof(*funcp));
7424                /*funcp->next = NULL;*/
7425        }
7426
7427        funcp->name = name;
7428        return funcp;
7429}
7430
7431# if ENABLE_HUSH_UNSET
7432static void unset_func(const char *name)
7433{
7434        struct function **funcpp = find_function_slot(name);
7435        struct function *funcp = *funcpp;
7436
7437        if (funcp != NULL) {
7438                debug_printf_exec("freeing function '%s'\n", funcp->name);
7439                *funcpp = funcp->next;
7440                /* funcp is unlinked now, deleting it.
7441                 * Note: if !funcp->body, the function was created by
7442                 * "-F name body", do not free ->body_as_string
7443                 * and ->name as they were not malloced. */
7444                if (funcp->body) {
7445                        free_pipe_list(funcp->body);
7446                        free(funcp->name);
7447#  if !BB_MMU
7448                        free(funcp->body_as_string);
7449#  endif
7450                }
7451                free(funcp);
7452        }
7453}
7454# endif
7455
7456# if BB_MMU
7457#define exec_function(to_free, funcp, argv) \
7458        exec_function(funcp, argv)
7459# endif
7460static void exec_function(char ***to_free,
7461                const struct function *funcp,
7462                char **argv) NORETURN;
7463static void exec_function(char ***to_free,
7464                const struct function *funcp,
7465                char **argv)
7466{
7467# if BB_MMU
7468        int n;
7469
7470        argv[0] = G.global_argv[0];
7471        G.global_argv = argv;
7472        G.global_argc = n = 1 + string_array_len(argv + 1);
7473
7474// Example when we are here: "cmd | func"
7475// func will run with saved-redirect fds open.
7476// $ f() { echo /proc/self/fd/*; }
7477// $ true | f
7478// /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
7479// stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ DIR fd for glob
7480// Same in script:
7481// $ . ./SCRIPT
7482// /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 /proc/self/fd/4
7483// stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ opened ./SCRIPT DIR fd for glob
7484// They are CLOEXEC so external programs won't see them, but
7485// for "more correctness" we might want to close those extra fds here:
7486//?     close_saved_fds_and_FILE_fds();
7487
7488        /* "we are in a function, ok to use return" */
7489        G_flag_return_in_progress = -1;
7490        enter_var_nest_level();
7491        IF_HUSH_LOCAL(G.func_nest_level++;)
7492
7493        /* On MMU, funcp->body is always non-NULL */
7494        n = run_list(funcp->body);
7495        fflush_all();
7496        _exit(n);
7497# else
7498//?     close_saved_fds_and_FILE_fds();
7499
7500//TODO: check whether "true | func_with_return" works
7501
7502        re_execute_shell(to_free,
7503                        funcp->body_as_string,
7504                        G.global_argv[0],
7505                        argv + 1,
7506                        NULL);
7507# endif
7508}
7509
7510static int run_function(const struct function *funcp, char **argv)
7511{
7512        int rc;
7513        save_arg_t sv;
7514        smallint sv_flg;
7515
7516        save_and_replace_G_args(&sv, argv);
7517
7518        /* "We are in function, ok to use return" */
7519        sv_flg = G_flag_return_in_progress;
7520        G_flag_return_in_progress = -1;
7521
7522        /* Make "local" variables properly shadow previous ones */
7523        IF_HUSH_LOCAL(enter_var_nest_level();)
7524        IF_HUSH_LOCAL(G.func_nest_level++;)
7525
7526        /* On MMU, funcp->body is always non-NULL */
7527# if !BB_MMU
7528        if (!funcp->body) {
7529                /* Function defined by -F */
7530                parse_and_run_string(funcp->body_as_string);
7531                rc = G.last_exitcode;
7532        } else
7533# endif
7534        {
7535                rc = run_list(funcp->body);
7536        }
7537
7538        IF_HUSH_LOCAL(G.func_nest_level--;)
7539        IF_HUSH_LOCAL(leave_var_nest_level();)
7540
7541        G_flag_return_in_progress = sv_flg;
7542
7543        restore_G_args(&sv, argv);
7544
7545        return rc;
7546}
7547#endif /* ENABLE_HUSH_FUNCTIONS */
7548
7549
7550#if BB_MMU
7551#define exec_builtin(to_free, x, argv) \
7552        exec_builtin(x, argv)
7553#else
7554#define exec_builtin(to_free, x, argv) \
7555        exec_builtin(to_free, argv)
7556#endif
7557static void exec_builtin(char ***to_free,
7558                const struct built_in_command *x,
7559                char **argv) NORETURN;
7560static void exec_builtin(char ***to_free,
7561                const struct built_in_command *x,
7562                char **argv)
7563{
7564#if BB_MMU
7565        int rcode;
7566        fflush_all();
7567//?     close_saved_fds_and_FILE_fds();
7568        rcode = x->b_function(argv);
7569        fflush_all();
7570        _exit(rcode);
7571#else
7572        fflush_all();
7573        /* On NOMMU, we must never block!
7574         * Example: { sleep 99 | read line; } & echo Ok
7575         */
7576        re_execute_shell(to_free,
7577                        argv[0],
7578                        G.global_argv[0],
7579                        G.global_argv + 1,
7580                        argv);
7581#endif
7582}
7583
7584
7585static void execvp_or_die(char **argv) NORETURN;
7586static void execvp_or_die(char **argv)
7587{
7588        int e;
7589        debug_printf_exec("execing '%s'\n", argv[0]);
7590        /* Don't propagate SIG_IGN to the child */
7591        if (SPECIAL_JOBSTOP_SIGS != 0)
7592                switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
7593        execvp(argv[0], argv);
7594        e = 2;
7595        if (errno == EACCES) e = 126;
7596        if (errno == ENOENT) e = 127;
7597        bb_perror_msg("can't execute '%s'", argv[0]);
7598        _exit(e);
7599}
7600
7601#if ENABLE_HUSH_MODE_X
7602static void dump_cmd_in_x_mode(char **argv)
7603{
7604        if (G_x_mode && argv) {
7605                /* We want to output the line in one write op */
7606                char *buf, *p;
7607                int len;
7608                int n;
7609
7610                len = 3;
7611                n = 0;
7612                while (argv[n])
7613                        len += strlen(argv[n++]) + 1;
7614                buf = xmalloc(len);
7615                buf[0] = '+';
7616                p = buf + 1;
7617                n = 0;
7618                while (argv[n])
7619                        p += sprintf(p, " %s", argv[n++]);
7620                *p++ = '\n';
7621                *p = '\0';
7622                fputs(buf, stderr);
7623                free(buf);
7624        }
7625}
7626#else
7627# define dump_cmd_in_x_mode(argv) ((void)0)
7628#endif
7629
7630#if ENABLE_HUSH_COMMAND
7631static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *explanation)
7632{
7633        char *to_free;
7634
7635        if (!opt_vV)
7636                return;
7637
7638        to_free = NULL;
7639        if (!explanation) {
7640                char *path = getenv("PATH");
7641                explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */
7642                if (!explanation)
7643                        _exit(1); /* PROG was not found */
7644                if (opt_vV != 'V')
7645                        cmd = to_free; /* -v PROG prints "/path/to/PROG" */
7646        }
7647        printf((opt_vV == 'V') ? "%s is %s\n" : "%s\n", cmd, explanation);
7648        free(to_free);
7649        fflush_all();
7650        _exit(0);
7651}
7652#else
7653# define if_command_vV_print_and_exit(a,b,c) ((void)0)
7654#endif
7655
7656#if BB_MMU
7657#define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
7658        pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
7659#define pseudo_exec(nommu_save, command, argv_expanded) \
7660        pseudo_exec(command, argv_expanded)
7661#endif
7662
7663/* Called after [v]fork() in run_pipe, or from builtin_exec.
7664 * Never returns.
7665 * Don't exit() here.  If you don't exec, use _exit instead.
7666 * The at_exit handlers apparently confuse the calling process,
7667 * in particular stdin handling. Not sure why? -- because of vfork! (vda)
7668 */
7669static void pseudo_exec_argv(nommu_save_t *nommu_save,
7670                char **argv, int assignment_cnt,
7671                char **argv_expanded) NORETURN;
7672static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
7673                char **argv, int assignment_cnt,
7674                char **argv_expanded)
7675{
7676        const struct built_in_command *x;
7677        struct variable **sv_shadowed;
7678        char **new_env;
7679        IF_HUSH_COMMAND(char opt_vV = 0;)
7680        IF_HUSH_FUNCTIONS(const struct function *funcp;)
7681
7682        new_env = expand_assignments(argv, assignment_cnt);
7683        dump_cmd_in_x_mode(new_env);
7684
7685        if (!argv[assignment_cnt]) {
7686                /* Case when we are here: ... | var=val | ...
7687                 * (note that we do not exit early, i.e., do not optimize out
7688                 * expand_assignments(): think about ... | var=`sleep 1` | ...
7689                 */
7690                free_strings(new_env);
7691                _exit(EXIT_SUCCESS);
7692        }
7693
7694        sv_shadowed = G.shadowed_vars_pp;
7695#if BB_MMU
7696        G.shadowed_vars_pp = NULL; /* "don't save, free them instead" */
7697#else
7698        G.shadowed_vars_pp = &nommu_save->old_vars;
7699        G.var_nest_level++;
7700#endif
7701        set_vars_and_save_old(new_env);
7702        G.shadowed_vars_pp = sv_shadowed;
7703
7704        if (argv_expanded) {
7705                argv = argv_expanded;
7706        } else {
7707                argv = expand_strvec_to_strvec(argv + assignment_cnt);
7708#if !BB_MMU
7709                nommu_save->argv = argv;
7710#endif
7711        }
7712        dump_cmd_in_x_mode(argv);
7713
7714#if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
7715        if (strchr(argv[0], '/') != NULL)
7716                goto skip;
7717#endif
7718
7719#if ENABLE_HUSH_FUNCTIONS
7720        /* Check if the command matches any functions (this goes before bltins) */
7721        funcp = find_function(argv[0]);
7722        if (funcp)
7723                exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
7724#endif
7725
7726#if ENABLE_HUSH_COMMAND
7727        /* "command BAR": run BAR without looking it up among functions
7728         * "command -v BAR": print "BAR" or "/path/to/BAR"; or exit 1
7729         * "command -V BAR": print "BAR is {a function,a shell builtin,/path/to/BAR}"
7730         */
7731        while (strcmp(argv[0], "command") == 0 && argv[1]) {
7732                char *p;
7733
7734                argv++;
7735                p = *argv;
7736                if (p[0] != '-' || !p[1])
7737                        continue; /* bash allows "command command command [-OPT] BAR" */
7738
7739                for (;;) {
7740                        p++;
7741                        switch (*p) {
7742                        case '\0':
7743                                argv++;
7744                                p = *argv;
7745                                if (p[0] != '-' || !p[1])
7746                                        goto after_opts;
7747                                continue; /* next arg is also -opts, process it too */
7748                        case 'v':
7749                        case 'V':
7750                                opt_vV = *p;
7751                                continue;
7752                        default:
7753                                bb_error_msg_and_die("%s: %s: invalid option", "command", argv[0]);
7754                        }
7755                }
7756        }
7757 after_opts:
7758# if ENABLE_HUSH_FUNCTIONS
7759        if (opt_vV && find_function(argv[0]))
7760                if_command_vV_print_and_exit(opt_vV, argv[0], "a function");
7761# endif
7762#endif
7763
7764        /* Check if the command matches any of the builtins.
7765         * Depending on context, this might be redundant.  But it's
7766         * easier to waste a few CPU cycles than it is to figure out
7767         * if this is one of those cases.
7768         */
7769        /* Why "BB_MMU ? :" difference in logic? -
7770         * On NOMMU, it is more expensive to re-execute shell
7771         * just in order to run echo or test builtin.
7772         * It's better to skip it here and run corresponding
7773         * non-builtin later. */
7774        x = BB_MMU ? find_builtin(argv[0]) : find_builtin1(argv[0]);
7775        if (x) {
7776                if_command_vV_print_and_exit(opt_vV, argv[0], "a shell builtin");
7777                exec_builtin(&nommu_save->argv_from_re_execing, x, argv);
7778        }
7779
7780#if ENABLE_FEATURE_SH_STANDALONE
7781        /* Check if the command matches any busybox applets */
7782        {
7783                int a = find_applet_by_name(argv[0]);
7784                if (a >= 0) {
7785                        if_command_vV_print_and_exit(opt_vV, argv[0], "an applet");
7786# if BB_MMU /* see above why on NOMMU it is not allowed */
7787                        if (APPLET_IS_NOEXEC(a)) {
7788                                /* Do not leak open fds from opened script files etc.
7789                                 * Testcase: interactive "ls -l /proc/self/fd"
7790                                 * should not show tty fd open.
7791                                 */
7792                                close_saved_fds_and_FILE_fds();
7793//FIXME: should also close saved redir fds
7794//This casuses test failures in
7795//redir_children_should_not_see_saved_fd_2.tests
7796//redir_children_should_not_see_saved_fd_3.tests
7797//if you replace "busybox find" with just "find" in them
7798                                /* Without this, "rm -i FILE" can't be ^C'ed: */
7799                                switch_off_special_sigs(G.special_sig_mask);
7800                                debug_printf_exec("running applet '%s'\n", argv[0]);
7801                                run_noexec_applet_and_exit(a, argv[0], argv);
7802                        }
7803# endif
7804                        /* Re-exec ourselves */
7805                        debug_printf_exec("re-execing applet '%s'\n", argv[0]);
7806                        /* Don't propagate SIG_IGN to the child */
7807                        if (SPECIAL_JOBSTOP_SIGS != 0)
7808                                switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
7809                        execv(bb_busybox_exec_path, argv);
7810                        /* If they called chroot or otherwise made the binary no longer
7811                         * executable, fall through */
7812                }
7813        }
7814#endif
7815
7816#if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
7817 skip:
7818#endif
7819        if_command_vV_print_and_exit(opt_vV, argv[0], NULL);
7820        execvp_or_die(argv);
7821}
7822
7823/* Called after [v]fork() in run_pipe
7824 */
7825static void pseudo_exec(nommu_save_t *nommu_save,
7826                struct command *command,
7827                char **argv_expanded) NORETURN;
7828static void pseudo_exec(nommu_save_t *nommu_save,
7829                struct command *command,
7830                char **argv_expanded)
7831{
7832#if ENABLE_HUSH_FUNCTIONS
7833        if (command->cmd_type == CMD_FUNCDEF) {
7834                /* Ignore funcdefs in pipes:
7835                 * true | f() { cmd }
7836                 */
7837                _exit(0);
7838        }
7839#endif
7840
7841        if (command->argv) {
7842                pseudo_exec_argv(nommu_save, command->argv,
7843                                command->assignment_cnt, argv_expanded);
7844        }
7845
7846        if (command->group) {
7847                /* Cases when we are here:
7848                 * ( list )
7849                 * { list } &
7850                 * ... | ( list ) | ...
7851                 * ... | { list } | ...
7852                 */
7853#if BB_MMU
7854                int rcode;
7855                debug_printf_exec("pseudo_exec: run_list\n");
7856                reset_traps_to_defaults();
7857                rcode = run_list(command->group);
7858                /* OK to leak memory by not calling free_pipe_list,
7859                 * since this process is about to exit */
7860                _exit(rcode);
7861#else
7862                re_execute_shell(&nommu_save->argv_from_re_execing,
7863                                command->group_as_string,
7864                                G.global_argv[0],
7865                                G.global_argv + 1,
7866                                NULL);
7867#endif
7868        }
7869
7870        /* Case when we are here: ... | >file */
7871        debug_printf_exec("pseudo_exec'ed null command\n");
7872        _exit(EXIT_SUCCESS);
7873}
7874
7875#if ENABLE_HUSH_JOB
7876static const char *get_cmdtext(struct pipe *pi)
7877{
7878        char **argv;
7879        char *p;
7880        int len;
7881
7882        /* This is subtle. ->cmdtext is created only on first backgrounding.
7883         * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
7884         * On subsequent bg argv is trashed, but we won't use it */
7885        if (pi->cmdtext)
7886                return pi->cmdtext;
7887
7888        argv = pi->cmds[0].argv;
7889        if (!argv) {
7890                pi->cmdtext = xzalloc(1);
7891                return pi->cmdtext;
7892        }
7893        len = 0;
7894        do {
7895                len += strlen(*argv) + 1;
7896        } while (*++argv);
7897        p = xmalloc(len);
7898        pi->cmdtext = p;
7899        argv = pi->cmds[0].argv;
7900        do {
7901                p = stpcpy(p, *argv);
7902                *p++ = ' ';
7903        } while (*++argv);
7904        p[-1] = '\0';
7905        return pi->cmdtext;
7906}
7907
7908static void remove_job_from_table(struct pipe *pi)
7909{
7910        struct pipe *prev_pipe;
7911
7912        if (pi == G.job_list) {
7913                G.job_list = pi->next;
7914        } else {
7915                prev_pipe = G.job_list;
7916                while (prev_pipe->next != pi)
7917                        prev_pipe = prev_pipe->next;
7918                prev_pipe->next = pi->next;
7919        }
7920        G.last_jobid = 0;
7921        if (G.job_list)
7922                G.last_jobid = G.job_list->jobid;
7923}
7924
7925static void delete_finished_job(struct pipe *pi)
7926{
7927        remove_job_from_table(pi);
7928        free_pipe(pi);
7929}
7930
7931static void clean_up_last_dead_job(void)
7932{
7933        if (G.job_list && !G.job_list->alive_cmds)
7934                delete_finished_job(G.job_list);
7935}
7936
7937static void insert_job_into_table(struct pipe *pi)
7938{
7939        struct pipe *job, **jobp;
7940        int i;
7941
7942        clean_up_last_dead_job();
7943
7944        /* Find the end of the list, and find next job ID to use */
7945        i = 0;
7946        jobp = &G.job_list;
7947        while ((job = *jobp) != NULL) {
7948                if (job->jobid > i)
7949                        i = job->jobid;
7950                jobp = &job->next;
7951        }
7952        pi->jobid = i + 1;
7953
7954        /* Create a new job struct at the end */
7955        job = *jobp = xmemdup(pi, sizeof(*pi));
7956        job->next = NULL;
7957        job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds);
7958        /* Cannot copy entire pi->cmds[] vector! This causes double frees */
7959        for (i = 0; i < pi->num_cmds; i++) {
7960                job->cmds[i].pid = pi->cmds[i].pid;
7961                /* all other fields are not used and stay zero */
7962        }
7963        job->cmdtext = xstrdup(get_cmdtext(pi));
7964
7965        if (G_interactive_fd)
7966                printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext);
7967        G.last_jobid = job->jobid;
7968}
7969#endif /* JOB */
7970
7971static int job_exited_or_stopped(struct pipe *pi)
7972{
7973        int rcode, i;
7974
7975        if (pi->alive_cmds != pi->stopped_cmds)
7976                return -1;
7977
7978        /* All processes in fg pipe have exited or stopped */
7979        rcode = 0;
7980        i = pi->num_cmds;
7981        while (--i >= 0) {
7982                rcode = pi->cmds[i].cmd_exitcode;
7983                /* usually last process gives overall exitstatus,
7984                 * but with "set -o pipefail", last *failed* process does */
7985                if (G.o_opt[OPT_O_PIPEFAIL] == 0 || rcode != 0)
7986                        break;
7987        }
7988        IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
7989        return rcode;
7990}
7991
7992static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status)
7993{
7994#if ENABLE_HUSH_JOB
7995        struct pipe *pi;
7996#endif
7997        int i, dead;
7998
7999        dead = WIFEXITED(status) || WIFSIGNALED(status);
8000
8001#if DEBUG_JOBS
8002        if (WIFSTOPPED(status))
8003                debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
8004                                childpid, WSTOPSIG(status), WEXITSTATUS(status));
8005        if (WIFSIGNALED(status))
8006                debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
8007                                childpid, WTERMSIG(status), WEXITSTATUS(status));
8008        if (WIFEXITED(status))
8009                debug_printf_jobs("pid %d exited, exitcode %d\n",
8010                                childpid, WEXITSTATUS(status));
8011#endif
8012        /* Were we asked to wait for a fg pipe? */
8013        if (fg_pipe) {
8014                i = fg_pipe->num_cmds;
8015
8016                while (--i >= 0) {
8017                        int rcode;
8018
8019                        debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
8020                        if (fg_pipe->cmds[i].pid != childpid)
8021                                continue;
8022                        if (dead) {
8023                                int ex;
8024                                fg_pipe->cmds[i].pid = 0;
8025                                fg_pipe->alive_cmds--;
8026                                ex = WEXITSTATUS(status);
8027                                /* bash prints killer signal's name for *last*
8028                                 * process in pipe (prints just newline for SIGINT/SIGPIPE).
8029                                 * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT)
8030                                 */
8031                                if (WIFSIGNALED(status)) {
8032                                        int sig = WTERMSIG(status);
8033                                        if (i == fg_pipe->num_cmds-1)
8034                                                /* TODO: use strsignal() instead for bash compat? but that's bloat... */
8035                                                puts(sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig));
8036                                        /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */
8037                                        /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here?
8038                                         * Maybe we need to use sig | 128? */
8039                                        ex = sig + 128;
8040                                }
8041                                fg_pipe->cmds[i].cmd_exitcode = ex;
8042                        } else {
8043                                fg_pipe->stopped_cmds++;
8044                        }
8045                        debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
8046                                        fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
8047                        rcode = job_exited_or_stopped(fg_pipe);
8048                        if (rcode >= 0) {
8049/* Note: *non-interactive* bash does not continue if all processes in fg pipe
8050 * are stopped. Testcase: "cat | cat" in a script (not on command line!)
8051 * and "killall -STOP cat" */
8052                                if (G_interactive_fd) {
8053#if ENABLE_HUSH_JOB
8054                                        if (fg_pipe->alive_cmds != 0)
8055                                                insert_job_into_table(fg_pipe);
8056#endif
8057                                        return rcode;
8058                                }
8059                                if (fg_pipe->alive_cmds == 0)
8060                                        return rcode;
8061                        }
8062                        /* There are still running processes in the fg_pipe */
8063                        return -1;
8064                }
8065                /* It wasn't in fg_pipe, look for process in bg pipes */
8066        }
8067
8068#if ENABLE_HUSH_JOB
8069        /* We were asked to wait for bg or orphaned children */
8070        /* No need to remember exitcode in this case */
8071        for (pi = G.job_list; pi; pi = pi->next) {
8072                for (i = 0; i < pi->num_cmds; i++) {
8073                        if (pi->cmds[i].pid == childpid)
8074                                goto found_pi_and_prognum;
8075                }
8076        }
8077        /* Happens when shell is used as init process (init=/bin/sh) */
8078        debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
8079        return -1; /* this wasn't a process from fg_pipe */
8080
8081 found_pi_and_prognum:
8082        if (dead) {
8083                /* child exited */
8084                int rcode = WEXITSTATUS(status);
8085                if (WIFSIGNALED(status))
8086                        rcode = 128 + WTERMSIG(status);
8087                pi->cmds[i].cmd_exitcode = rcode;
8088                if (G.last_bg_pid == pi->cmds[i].pid)
8089                        G.last_bg_pid_exitcode = rcode;
8090                pi->cmds[i].pid = 0;
8091                pi->alive_cmds--;
8092                if (!pi->alive_cmds) {
8093                        if (G_interactive_fd) {
8094                                printf(JOB_STATUS_FORMAT, pi->jobid,
8095                                                "Done", pi->cmdtext);
8096                                delete_finished_job(pi);
8097                        } else {
8098/*
8099 * bash deletes finished jobs from job table only in interactive mode,
8100 * after "jobs" cmd, or if pid of a new process matches one of the old ones
8101 * (see cleanup_dead_jobs(), delete_old_job(), J_NOTIFIED in bash source).
8102 * Testcase script: "(exit 3) & sleep 1; wait %1; echo $?" prints 3 in bash.
8103 * We only retain one "dead" job, if it's the single job on the list.
8104 * This covers most of real-world scenarios where this is useful.
8105 */
8106                                if (pi != G.job_list)
8107                                        delete_finished_job(pi);
8108                        }
8109                }
8110        } else {
8111                /* child stopped */
8112                pi->stopped_cmds++;
8113        }
8114#endif
8115        return -1; /* this wasn't a process from fg_pipe */
8116}
8117
8118/* Check to see if any processes have exited -- if they have,
8119 * figure out why and see if a job has completed.
8120 *
8121 * If non-NULL fg_pipe: wait for its completion or stop.
8122 * Return its exitcode or zero if stopped.
8123 *
8124 * Alternatively (fg_pipe == NULL, waitfor_pid != 0):
8125 * waitpid(WNOHANG), if waitfor_pid exits or stops, return exitcode+1,
8126 * else return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8127 * or 0 if no children changed status.
8128 *
8129 * Alternatively (fg_pipe == NULL, waitfor_pid == 0),
8130 * return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8131 * or 0 if no children changed status.
8132 */
8133static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
8134{
8135        int attributes;
8136        int status;
8137        int rcode = 0;
8138
8139        debug_printf_jobs("checkjobs %p\n", fg_pipe);
8140
8141        attributes = WUNTRACED;
8142        if (fg_pipe == NULL)
8143                attributes |= WNOHANG;
8144
8145        errno = 0;
8146#if ENABLE_HUSH_FAST
8147        if (G.handled_SIGCHLD == G.count_SIGCHLD) {
8148//bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p",
8149//getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe);
8150                /* There was neither fork nor SIGCHLD since last waitpid */
8151                /* Avoid doing waitpid syscall if possible */
8152                if (!G.we_have_children) {
8153                        errno = ECHILD;
8154                        return -1;
8155                }
8156                if (fg_pipe == NULL) { /* is WNOHANG set? */
8157                        /* We have children, but they did not exit
8158                         * or stop yet (we saw no SIGCHLD) */
8159                        return 0;
8160                }
8161                /* else: !WNOHANG, waitpid will block, can't short-circuit */
8162        }
8163#endif
8164
8165/* Do we do this right?
8166 * bash-3.00# sleep 20 | false
8167 * <ctrl-Z pressed>
8168 * [3]+  Stopped          sleep 20 | false
8169 * bash-3.00# echo $?
8170 * 1   <========== bg pipe is not fully done, but exitcode is already known!
8171 * [hush 1.14.0: yes we do it right]
8172 */
8173        while (1) {
8174                pid_t childpid;
8175#if ENABLE_HUSH_FAST
8176                int i;
8177                i = G.count_SIGCHLD;
8178#endif
8179                childpid = waitpid(-1, &status, attributes);
8180                if (childpid <= 0) {
8181                        if (childpid && errno != ECHILD)
8182                                bb_perror_msg("waitpid");
8183#if ENABLE_HUSH_FAST
8184                        else { /* Until next SIGCHLD, waitpid's are useless */
8185                                G.we_have_children = (childpid == 0);
8186                                G.handled_SIGCHLD = i;
8187//bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
8188                        }
8189#endif
8190                        /* ECHILD (no children), or 0 (no change in children status) */
8191                        rcode = childpid;
8192                        break;
8193                }
8194                rcode = process_wait_result(fg_pipe, childpid, status);
8195                if (rcode >= 0) {
8196                        /* fg_pipe exited or stopped */
8197                        break;
8198                }
8199                if (childpid == waitfor_pid) {
8200                        debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status);
8201                        rcode = WEXITSTATUS(status);
8202                        if (WIFSIGNALED(status))
8203                                rcode = 128 + WTERMSIG(status);
8204                        if (WIFSTOPPED(status))
8205                                /* bash: "cmd & wait $!" and cmd stops: $? = 128 + stopsig */
8206                                rcode = 128 + WSTOPSIG(status);
8207                        rcode++;
8208                        break; /* "wait PID" called us, give it exitcode+1 */
8209                }
8210                /* This wasn't one of our processes, or */
8211                /* fg_pipe still has running processes, do waitpid again */
8212        } /* while (waitpid succeeds)... */
8213
8214        return rcode;
8215}
8216
8217#if ENABLE_HUSH_JOB
8218static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
8219{
8220        pid_t p;
8221        int rcode = checkjobs(fg_pipe, 0 /*(no pid to wait for)*/);
8222        if (G_saved_tty_pgrp) {
8223                /* Job finished, move the shell to the foreground */
8224                p = getpgrp(); /* our process group id */
8225                debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p);
8226                tcsetpgrp(G_interactive_fd, p);
8227        }
8228        return rcode;
8229}
8230#endif
8231
8232/* Start all the jobs, but don't wait for anything to finish.
8233 * See checkjobs().
8234 *
8235 * Return code is normally -1, when the caller has to wait for children
8236 * to finish to determine the exit status of the pipe.  If the pipe
8237 * is a simple builtin command, however, the action is done by the
8238 * time run_pipe returns, and the exit code is provided as the
8239 * return value.
8240 *
8241 * Returns -1 only if started some children. IOW: we have to
8242 * mask out retvals of builtins etc with 0xff!
8243 *
8244 * The only case when we do not need to [v]fork is when the pipe
8245 * is single, non-backgrounded, non-subshell command. Examples:
8246 * cmd ; ...   { list } ; ...
8247 * cmd && ...  { list } && ...
8248 * cmd || ...  { list } || ...
8249 * If it is, then we can run cmd as a builtin, NOFORK,
8250 * or (if SH_STANDALONE) an applet, and we can run the { list }
8251 * with run_list. If it isn't one of these, we fork and exec cmd.
8252 *
8253 * Cases when we must fork:
8254 * non-single:   cmd | cmd
8255 * backgrounded: cmd &     { list } &
8256 * subshell:     ( list ) [&]
8257 */
8258#if !ENABLE_HUSH_MODE_X
8259#define redirect_and_varexp_helper(command, squirrel, argv_expanded) \
8260        redirect_and_varexp_helper(command, squirrel)
8261#endif
8262static int redirect_and_varexp_helper(
8263                struct command *command,
8264                struct squirrel **sqp,
8265                char **argv_expanded)
8266{
8267        /* Assignments occur before redirects. Try:
8268         * a=`sleep 1` sleep 2 3>/qwe/rty
8269         */
8270
8271        char **new_env = expand_assignments(command->argv, command->assignment_cnt);
8272        dump_cmd_in_x_mode(new_env);
8273        dump_cmd_in_x_mode(argv_expanded);
8274        /* this takes ownership of new_env[i] elements, and frees new_env: */
8275        set_vars_and_save_old(new_env);
8276
8277        /* setup_redirects acts on file descriptors, not FILEs.
8278         * This is perfect for work that comes after exec().
8279         * Is it really safe for inline use?  Experimentally,
8280         * things seem to work. */
8281        return setup_redirects(command, sqp);
8282}
8283static NOINLINE int run_pipe(struct pipe *pi)
8284{
8285        static const char *const null_ptr = NULL;
8286
8287        int cmd_no;
8288        int next_infd;
8289        struct command *command;
8290        char **argv_expanded;
8291        char **argv;
8292        struct squirrel *squirrel = NULL;
8293        int rcode;
8294
8295        debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds);
8296        debug_enter();
8297
8298        /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*"
8299         * Result should be 3 lines: q w e, qwe, q w e
8300         */
8301        if (G.ifs_whitespace != G.ifs)
8302                free(G.ifs_whitespace);
8303        G.ifs = get_local_var_value("IFS");
8304        if (G.ifs) {
8305                char *p;
8306                G.ifs_whitespace = (char*)G.ifs;
8307                p = skip_whitespace(G.ifs);
8308                if (*p) {
8309                        /* Not all $IFS is whitespace */
8310                        char *d;
8311                        int len = p - G.ifs;
8312                        p = skip_non_whitespace(p);
8313                        G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */
8314                        d = mempcpy(G.ifs_whitespace, G.ifs, len);
8315                        while (*p) {
8316                                if (isspace(*p))
8317                                        *d++ = *p;
8318                                p++;
8319                        }
8320                        *d = '\0';
8321                }
8322        } else {
8323                G.ifs = defifs;
8324                G.ifs_whitespace = (char*)G.ifs;
8325        }
8326
8327        IF_HUSH_JOB(pi->pgrp = -1;)
8328        pi->stopped_cmds = 0;
8329        command = &pi->cmds[0];
8330        argv_expanded = NULL;
8331
8332        if (pi->num_cmds != 1
8333         || pi->followup == PIPE_BG
8334         || command->cmd_type == CMD_SUBSHELL
8335        ) {
8336                goto must_fork;
8337        }
8338
8339        pi->alive_cmds = 1;
8340
8341        debug_printf_exec(": group:%p argv:'%s'\n",
8342                command->group, command->argv ? command->argv[0] : "NONE");
8343
8344        if (command->group) {
8345#if ENABLE_HUSH_FUNCTIONS
8346                if (command->cmd_type == CMD_FUNCDEF) {
8347                        /* "executing" func () { list } */
8348                        struct function *funcp;
8349
8350                        funcp = new_function(command->argv[0]);
8351                        /* funcp->name is already set to argv[0] */
8352                        funcp->body = command->group;
8353# if !BB_MMU
8354                        funcp->body_as_string = command->group_as_string;
8355                        command->group_as_string = NULL;
8356# endif
8357                        command->group = NULL;
8358                        command->argv[0] = NULL;
8359                        debug_printf_exec("cmd %p has child func at %p\n", command, funcp);
8360                        funcp->parent_cmd = command;
8361                        command->child_func = funcp;
8362
8363                        debug_printf_exec("run_pipe: return EXIT_SUCCESS\n");
8364                        debug_leave();
8365                        return EXIT_SUCCESS;
8366                }
8367#endif
8368                /* { list } */
8369                debug_printf("non-subshell group\n");
8370                rcode = 1; /* exitcode if redir failed */
8371                if (setup_redirects(command, &squirrel) == 0) {
8372                        debug_printf_exec(": run_list\n");
8373//FIXME: we need to pass squirrel down into run_list()
8374//for SH_STANDALONE case, or else this construct:
8375// { find /proc/self/fd; true; } >FILE; cmd2
8376//has no way of closing saved fd#1 for "find",
8377//and in SH_STANDALONE mode, "find" is not execed,
8378//therefore CLOEXEC on saved fd does not help.
8379                        rcode = run_list(command->group) & 0xff;
8380                }
8381                restore_redirects(squirrel);
8382                IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8383                debug_leave();
8384                debug_printf_exec("run_pipe: return %d\n", rcode);
8385                return rcode;
8386        }
8387
8388        argv = command->argv ? command->argv : (char **) &null_ptr;
8389        {
8390                const struct built_in_command *x;
8391                IF_HUSH_FUNCTIONS(const struct function *funcp;)
8392                IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };)
8393                struct variable **sv_shadowed;
8394                struct variable *old_vars;
8395
8396#if ENABLE_HUSH_LINENO_VAR
8397                if (G.lineno_var)
8398                        strcpy(G.lineno_var + sizeof("LINENO=")-1, utoa(command->lineno));
8399#endif
8400
8401                if (argv[command->assignment_cnt] == NULL) {
8402                        /* Assignments, but no command.
8403                         * Ensure redirects take effect (that is, create files).
8404                         * Try "a=t >file"
8405                         */
8406                        unsigned i;
8407                        G.expand_exitcode = 0;
8408 only_assignments:
8409                        rcode = setup_redirects(command, &squirrel);
8410                        restore_redirects(squirrel);
8411
8412                        /* Set shell variables */
8413                        if (G_x_mode)
8414                                bb_putchar_stderr('+');
8415                        i = 0;
8416                        while (i < command->assignment_cnt) {
8417                                char *p = expand_string_to_string(argv[i],
8418                                                EXP_FLAG_ESC_GLOB_CHARS,
8419                                                /*unbackslash:*/ 1
8420                                );
8421                                if (G_x_mode)
8422                                        fprintf(stderr, " %s", p);
8423                                debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
8424                                if (set_local_var(p, /*flag:*/ 0)) {
8425                                        /* assignment to readonly var / putenv error? */
8426                                        rcode = 1;
8427                                }
8428                                i++;
8429                        }
8430                        if (G_x_mode)
8431                                bb_putchar_stderr('\n');
8432                        /* Redirect error sets $? to 1. Otherwise,
8433                         * if evaluating assignment value set $?, retain it.
8434                         * Else, clear $?:
8435                         *  false; q=`exit 2`; echo $? - should print 2
8436                         *  false; x=1; echo $? - should print 0
8437                         * Because of the 2nd case, we can't just use G.last_exitcode.
8438                         */
8439                        if (rcode == 0)
8440                                rcode = G.expand_exitcode;
8441                        IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8442                        debug_leave();
8443                        debug_printf_exec("run_pipe: return %d\n", rcode);
8444                        return rcode;
8445                }
8446
8447                /* Expand the rest into (possibly) many strings each */
8448#if defined(CMD_SINGLEWORD_NOGLOB)
8449                if (command->cmd_type == CMD_SINGLEWORD_NOGLOB)
8450                        argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
8451                else
8452#endif
8453                        argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
8454
8455                /* If someone gives us an empty string: `cmd with empty output` */
8456                if (!argv_expanded[0]) {
8457                        free(argv_expanded);
8458                        /* `false` still has to set exitcode 1 */
8459                        G.expand_exitcode = G.last_exitcode;
8460                        goto only_assignments;
8461                }
8462
8463                old_vars = NULL;
8464                sv_shadowed = G.shadowed_vars_pp;
8465
8466                /* Check if argv[0] matches any functions (this goes before bltins) */
8467                IF_HUSH_FUNCTIONS(funcp = find_function(argv_expanded[0]);)
8468                IF_HUSH_FUNCTIONS(x = NULL;)
8469                IF_HUSH_FUNCTIONS(if (!funcp))
8470                        x = find_builtin(argv_expanded[0]);
8471                if (x || funcp) {
8472                        if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) {
8473                                debug_printf("exec with redirects only\n");
8474                                /*
8475                                 * Variable assignments are executed, but then "forgotten":
8476                                 *  a=`sleep 1;echo A` exec 3>&-; echo $a
8477                                 * sleeps, but prints nothing.
8478                                 */
8479                                enter_var_nest_level();
8480                                G.shadowed_vars_pp = &old_vars;
8481                                rcode = redirect_and_varexp_helper(command, /*squirrel:*/ NULL, argv_expanded);
8482                                G.shadowed_vars_pp = sv_shadowed;
8483                                /* rcode=1 can be if redir file can't be opened */
8484
8485                                goto clean_up_and_ret1;
8486                        }
8487
8488                        /* Bump var nesting, or this will leak exported $a:
8489                         * a=b true; env | grep ^a=
8490                         */
8491                        enter_var_nest_level();
8492                        /* Collect all variables "shadowed" by helper
8493                         * (IOW: old vars overridden by "var1=val1 var2=val2 cmd..." syntax)
8494                         * into old_vars list:
8495                         */
8496                        G.shadowed_vars_pp = &old_vars;
8497                        rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
8498                        if (rcode == 0) {
8499                                if (!funcp) {
8500                                        /* Do not collect *to old_vars list* vars shadowed
8501                                         * by e.g. "local VAR" builtin (collect them
8502                                         * in the previously nested list instead):
8503                                         * don't want them to be restored immediately
8504                                         * after "local" completes.
8505                                         */
8506                                        G.shadowed_vars_pp = sv_shadowed;
8507
8508                                        debug_printf_exec(": builtin '%s' '%s'...\n",
8509                                                x->b_cmd, argv_expanded[1]);
8510                                        fflush_all();
8511                                        rcode = x->b_function(argv_expanded) & 0xff;
8512                                        fflush_all();
8513                                }
8514#if ENABLE_HUSH_FUNCTIONS
8515                                else {
8516                                        debug_printf_exec(": function '%s' '%s'...\n",
8517                                                funcp->name, argv_expanded[1]);
8518                                        rcode = run_function(funcp, argv_expanded) & 0xff;
8519                                        /*
8520                                         * But do collect *to old_vars list* vars shadowed
8521                                         * within function execution. To that end, restore
8522                                         * this pointer _after_ function run:
8523                                         */
8524                                        G.shadowed_vars_pp = sv_shadowed;
8525                                }
8526#endif
8527                        }
8528                } else
8529                if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) {
8530                        int n = find_applet_by_name(argv_expanded[0]);
8531                        if (n < 0 || !APPLET_IS_NOFORK(n))
8532                                goto must_fork;
8533
8534                        enter_var_nest_level();
8535                        /* Collect all variables "shadowed" by helper into old_vars list */
8536                        G.shadowed_vars_pp = &old_vars;
8537                        rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
8538                        G.shadowed_vars_pp = sv_shadowed;
8539
8540                        if (rcode == 0) {
8541                                debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
8542                                        argv_expanded[0], argv_expanded[1]);
8543                                /*
8544                                 * Note: signals (^C) can't interrupt here.
8545                                 * We remember them and they will be acted upon
8546                                 * after applet returns.
8547                                 * This makes applets which can run for a long time
8548                                 * and/or wait for user input ineligible for NOFORK:
8549                                 * for example, "yes" or "rm" (rm -i waits for input).
8550                                 */
8551                                rcode = run_nofork_applet(n, argv_expanded);
8552                        }
8553                } else
8554                        goto must_fork;
8555
8556                restore_redirects(squirrel);
8557 clean_up_and_ret1:
8558                leave_var_nest_level();
8559                add_vars(old_vars);
8560
8561                /*
8562                 * Try "usleep 99999999" + ^C + "echo $?"
8563                 * with FEATURE_SH_NOFORK=y.
8564                 */
8565                if (!funcp) {
8566                        /* It was builtin or nofork.
8567                         * if this would be a real fork/execed program,
8568                         * it should have died if a fatal sig was received.
8569                         * But OTOH, there was no separate process,
8570                         * the sig was sent to _shell_, not to non-existing
8571                         * child.
8572                         * Let's just handle ^C only, this one is obvious:
8573                         * we aren't ok with exitcode 0 when ^C was pressed
8574                         * during builtin/nofork.
8575                         */
8576                        if (sigismember(&G.pending_set, SIGINT))
8577                                rcode = 128 + SIGINT;
8578                }
8579                free(argv_expanded);
8580                IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8581                debug_leave();
8582                debug_printf_exec("run_pipe return %d\n", rcode);
8583                return rcode;
8584        }
8585
8586 must_fork:
8587        /* NB: argv_expanded may already be created, and that
8588         * might include `cmd` runs! Do not rerun it! We *must*
8589         * use argv_expanded if it's non-NULL */
8590
8591        /* Going to fork a child per each pipe member */
8592        pi->alive_cmds = 0;
8593        next_infd = 0;
8594
8595        cmd_no = 0;
8596        while (cmd_no < pi->num_cmds) {
8597                struct fd_pair pipefds;
8598#if !BB_MMU
8599                int sv_var_nest_level = G.var_nest_level;
8600                volatile nommu_save_t nommu_save;
8601                nommu_save.old_vars = NULL;
8602                nommu_save.argv = NULL;
8603                nommu_save.argv_from_re_execing = NULL;
8604#endif
8605                command = &pi->cmds[cmd_no];
8606                cmd_no++;
8607                if (command->argv) {
8608                        debug_printf_exec(": pipe member '%s' '%s'...\n",
8609                                        command->argv[0], command->argv[1]);
8610                } else {
8611                        debug_printf_exec(": pipe member with no argv\n");
8612                }
8613
8614                /* pipes are inserted between pairs of commands */
8615                pipefds.rd = 0;
8616                pipefds.wr = 1;
8617                if (cmd_no < pi->num_cmds)
8618                        xpiped_pair(pipefds);
8619
8620#if ENABLE_HUSH_LINENO_VAR
8621                if (G.lineno_var)
8622                        strcpy(G.lineno_var + sizeof("LINENO=")-1, utoa(command->lineno));
8623#endif
8624
8625                command->pid = BB_MMU ? fork() : vfork();
8626                if (!command->pid) { /* child */
8627#if ENABLE_HUSH_JOB
8628                        disable_restore_tty_pgrp_on_exit();
8629                        CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
8630
8631                        /* Every child adds itself to new process group
8632                         * with pgid == pid_of_first_child_in_pipe */
8633                        if (G.run_list_level == 1 && G_interactive_fd) {
8634                                pid_t pgrp;
8635                                pgrp = pi->pgrp;
8636                                if (pgrp < 0) /* true for 1st process only */
8637                                        pgrp = getpid();
8638                                if (setpgid(0, pgrp) == 0
8639                                 && pi->followup != PIPE_BG
8640                                 && G_saved_tty_pgrp /* we have ctty */
8641                                ) {
8642                                        /* We do it in *every* child, not just first,
8643                                         * to avoid races */
8644                                        tcsetpgrp(G_interactive_fd, pgrp);
8645                                }
8646                        }
8647#endif
8648                        if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) {
8649                                /* 1st cmd in backgrounded pipe
8650                                 * should have its stdin /dev/null'ed */
8651                                close(0);
8652                                if (open(bb_dev_null, O_RDONLY))
8653                                        xopen("/", O_RDONLY);
8654                        } else {
8655                                xmove_fd(next_infd, 0);
8656                        }
8657                        xmove_fd(pipefds.wr, 1);
8658                        if (pipefds.rd > 1)
8659                                close(pipefds.rd);
8660                        /* Like bash, explicit redirects override pipes,
8661                         * and the pipe fd (fd#1) is available for dup'ing:
8662                         * "cmd1 2>&1 | cmd2": fd#1 is duped to fd#2, thus stderr
8663                         * of cmd1 goes into pipe.
8664                         */
8665                        if (setup_redirects(command, NULL)) {
8666                                /* Happens when redir file can't be opened:
8667                                 * $ hush -c 'echo FOO >&2 | echo BAR 3>/qwe/rty; echo BAZ'
8668                                 * FOO
8669                                 * hush: can't open '/qwe/rty': No such file or directory
8670                                 * BAZ
8671                                 * (echo BAR is not executed, it hits _exit(1) below)
8672                                 */
8673                                _exit(1);
8674                        }
8675
8676                        /* Stores to nommu_save list of env vars putenv'ed
8677                         * (NOMMU, on MMU we don't need that) */
8678                        /* cast away volatility... */
8679                        pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded);
8680                        /* pseudo_exec() does not return */
8681                }
8682
8683                /* parent or error */
8684#if ENABLE_HUSH_FAST
8685                G.count_SIGCHLD++;
8686//bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
8687#endif
8688                enable_restore_tty_pgrp_on_exit();
8689#if !BB_MMU
8690                /* Clean up after vforked child */
8691                free(nommu_save.argv);
8692                free(nommu_save.argv_from_re_execing);
8693                G.var_nest_level = sv_var_nest_level;
8694                remove_nested_vars();
8695                add_vars(nommu_save.old_vars);
8696#endif
8697                free(argv_expanded);
8698                argv_expanded = NULL;
8699                if (command->pid < 0) { /* [v]fork failed */
8700                        /* Clearly indicate, was it fork or vfork */
8701                        bb_perror_msg(BB_MMU ? "vfork"+1 : "vfork");
8702                } else {
8703                        pi->alive_cmds++;
8704#if ENABLE_HUSH_JOB
8705                        /* Second and next children need to know pid of first one */
8706                        if (pi->pgrp < 0)
8707                                pi->pgrp = command->pid;
8708#endif
8709                }
8710
8711                if (cmd_no > 1)
8712                        close(next_infd);
8713                if (cmd_no < pi->num_cmds)
8714                        close(pipefds.wr);
8715                /* Pass read (output) pipe end to next iteration */
8716                next_infd = pipefds.rd;
8717        }
8718
8719        if (!pi->alive_cmds) {
8720                debug_leave();
8721                debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
8722                return 1;
8723        }
8724
8725        debug_leave();
8726        debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds);
8727        return -1;
8728}
8729
8730/* NB: called by pseudo_exec, and therefore must not modify any
8731 * global data until exec/_exit (we can be a child after vfork!) */
8732static int run_list(struct pipe *pi)
8733{
8734#if ENABLE_HUSH_CASE
8735        char *case_word = NULL;
8736#endif
8737#if ENABLE_HUSH_LOOPS
8738        struct pipe *loop_top = NULL;
8739        char **for_lcur = NULL;
8740        char **for_list = NULL;
8741#endif
8742        smallint last_followup;
8743        smalluint rcode;
8744#if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
8745        smalluint cond_code = 0;
8746#else
8747        enum { cond_code = 0 };
8748#endif
8749#if HAS_KEYWORDS
8750        smallint rword;      /* RES_foo */
8751        smallint last_rword; /* ditto */
8752#endif
8753
8754        debug_printf_exec("run_list start lvl %d\n", G.run_list_level);
8755        debug_enter();
8756
8757#if ENABLE_HUSH_LOOPS
8758        /* Check syntax for "for" */
8759        {
8760                struct pipe *cpipe;
8761                for (cpipe = pi; cpipe; cpipe = cpipe->next) {
8762                        if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN)
8763                                continue;
8764                        /* current word is FOR or IN (BOLD in comments below) */
8765                        if (cpipe->next == NULL) {
8766                                syntax_error("malformed for");
8767                                debug_leave();
8768                                debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
8769                                return 1;
8770                        }
8771                        /* "FOR v; do ..." and "for v IN a b; do..." are ok */
8772                        if (cpipe->next->res_word == RES_DO)
8773                                continue;
8774                        /* next word is not "do". It must be "in" then ("FOR v in ...") */
8775                        if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */
8776                         || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */
8777                        ) {
8778                                syntax_error("malformed for");
8779                                debug_leave();
8780                                debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
8781                                return 1;
8782                        }
8783                }
8784        }
8785#endif
8786
8787        /* Past this point, all code paths should jump to ret: label
8788         * in order to return, no direct "return" statements please.
8789         * This helps to ensure that no memory is leaked. */
8790
8791#if ENABLE_HUSH_JOB
8792        G.run_list_level++;
8793#endif
8794
8795#if HAS_KEYWORDS
8796        rword = RES_NONE;
8797        last_rword = RES_XXXX;
8798#endif
8799        last_followup = PIPE_SEQ;
8800        rcode = G.last_exitcode;
8801
8802        /* Go through list of pipes, (maybe) executing them. */
8803        for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) {
8804                int r;
8805                int sv_errexit_depth;
8806
8807                if (G.flag_SIGINT)
8808                        break;
8809                if (G_flag_return_in_progress == 1)
8810                        break;
8811
8812                IF_HAS_KEYWORDS(rword = pi->res_word;)
8813                debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n",
8814                                rword, cond_code, last_rword);
8815
8816                sv_errexit_depth = G.errexit_depth;
8817                if (
8818#if ENABLE_HUSH_IF
8819                    rword == RES_IF || rword == RES_ELIF ||
8820#endif
8821                    pi->followup != PIPE_SEQ
8822                ) {
8823                        G.errexit_depth++;
8824                }
8825#if ENABLE_HUSH_LOOPS
8826                if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR)
8827                 && loop_top == NULL /* avoid bumping G.depth_of_loop twice */
8828                ) {
8829                        /* start of a loop: remember where loop starts */
8830                        loop_top = pi;
8831                        G.depth_of_loop++;
8832                }
8833#endif
8834                /* Still in the same "if...", "then..." or "do..." branch? */
8835                if (IF_HAS_KEYWORDS(rword == last_rword &&) 1) {
8836                        if ((rcode == 0 && last_followup == PIPE_OR)
8837                         || (rcode != 0 && last_followup == PIPE_AND)
8838                        ) {
8839                                /* It is "<true> || CMD" or "<false> && CMD"
8840                                 * and we should not execute CMD */
8841                                debug_printf_exec("skipped cmd because of || or &&\n");
8842                                last_followup = pi->followup;
8843                                goto dont_check_jobs_but_continue;
8844                        }
8845                }
8846                last_followup = pi->followup;
8847                IF_HAS_KEYWORDS(last_rword = rword;)
8848#if ENABLE_HUSH_IF
8849                if (cond_code) {
8850                        if (rword == RES_THEN) {
8851                                /* if false; then ... fi has exitcode 0! */
8852                                G.last_exitcode = rcode = EXIT_SUCCESS;
8853                                /* "if <false> THEN cmd": skip cmd */
8854                                continue;
8855                        }
8856                } else {
8857                        if (rword == RES_ELSE || rword == RES_ELIF) {
8858                                /* "if <true> then ... ELSE/ELIF cmd":
8859                                 * skip cmd and all following ones */
8860                                break;
8861                        }
8862                }
8863#endif
8864#if ENABLE_HUSH_LOOPS
8865                if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */
8866                        if (!for_lcur) {
8867                                /* first loop through for */
8868
8869                                static const char encoded_dollar_at[] ALIGN1 = {
8870                                        SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
8871                                }; /* encoded representation of "$@" */
8872                                static const char *const encoded_dollar_at_argv[] = {
8873                                        encoded_dollar_at, NULL
8874                                }; /* argv list with one element: "$@" */
8875                                char **vals;
8876
8877                                vals = (char**)encoded_dollar_at_argv;
8878                                if (pi->next->res_word == RES_IN) {
8879                                        /* if no variable values after "in" we skip "for" */
8880                                        if (!pi->next->cmds[0].argv) {
8881                                                G.last_exitcode = rcode = EXIT_SUCCESS;
8882                                                debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n");
8883                                                break;
8884                                        }
8885                                        vals = pi->next->cmds[0].argv;
8886                                } /* else: "for var; do..." -> assume "$@" list */
8887                                /* create list of variable values */
8888                                debug_print_strings("for_list made from", vals);
8889                                for_list = expand_strvec_to_strvec(vals);
8890                                for_lcur = for_list;
8891                                debug_print_strings("for_list", for_list);
8892                        }
8893                        if (!*for_lcur) {
8894                                /* "for" loop is over, clean up */
8895                                free(for_list);
8896                                for_list = NULL;
8897                                for_lcur = NULL;
8898                                break;
8899                        }
8900                        /* Insert next value from for_lcur */
8901                        /* note: *for_lcur already has quotes removed, $var expanded, etc */
8902                        set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), /*flag:*/ 0);
8903                        continue;
8904                }
8905                if (rword == RES_IN) {
8906                        continue; /* "for v IN list;..." - "in" has no cmds anyway */
8907                }
8908                if (rword == RES_DONE) {
8909                        continue; /* "done" has no cmds too */
8910                }
8911#endif
8912#if ENABLE_HUSH_CASE
8913                if (rword == RES_CASE) {
8914                        debug_printf_exec("CASE cond_code:%d\n", cond_code);
8915                        case_word = expand_string_to_string(pi->cmds->argv[0],
8916                                EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
8917                        debug_printf_exec("CASE word1:'%s'\n", case_word);
8918                        //unbackslash(case_word);
8919                        //debug_printf_exec("CASE word2:'%s'\n", case_word);
8920                        continue;
8921                }
8922                if (rword == RES_MATCH) {
8923                        char **argv;
8924
8925                        debug_printf_exec("MATCH cond_code:%d\n", cond_code);
8926                        if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
8927                                break;
8928                        /* all prev words didn't match, does this one match? */
8929                        argv = pi->cmds->argv;
8930                        while (*argv) {
8931                                char *pattern;
8932                                debug_printf_exec("expand_string_to_string('%s')\n", *argv);
8933                                pattern = expand_string_to_string(*argv,
8934                                                EXP_FLAG_ESC_GLOB_CHARS,
8935                                                /*unbackslash:*/ 0
8936                                );
8937                                /* TODO: which FNM_xxx flags to use? */
8938                                cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
8939                                debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n",
8940                                                pattern, case_word, cond_code);
8941                                free(pattern);
8942                                if (cond_code == 0) {
8943                                        /* match! we will execute this branch */
8944                                        free(case_word);
8945                                        case_word = NULL; /* make future "word)" stop */
8946                                        break;
8947                                }
8948                                argv++;
8949                        }
8950                        continue;
8951                }
8952                if (rword == RES_CASE_BODY) { /* inside of a case branch */
8953                        debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code);
8954                        if (cond_code != 0)
8955                                continue; /* not matched yet, skip this pipe */
8956                }
8957                if (rword == RES_ESAC) {
8958                        debug_printf_exec("ESAC cond_code:%d\n", cond_code);
8959                        if (case_word) {
8960                                /* "case" did not match anything: still set $? (to 0) */
8961                                G.last_exitcode = rcode = EXIT_SUCCESS;
8962                        }
8963                }
8964#endif
8965                /* Just pressing <enter> in shell should check for jobs.
8966                 * OTOH, in non-interactive shell this is useless
8967                 * and only leads to extra job checks */
8968                if (pi->num_cmds == 0) {
8969                        if (G_interactive_fd)
8970                                goto check_jobs_and_continue;
8971                        continue;
8972                }
8973
8974                /* After analyzing all keywords and conditions, we decided
8975                 * to execute this pipe. NB: have to do checkjobs(NULL)
8976                 * after run_pipe to collect any background children,
8977                 * even if list execution is to be stopped. */
8978                debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds);
8979#if ENABLE_HUSH_LOOPS
8980                G.flag_break_continue = 0;
8981#endif
8982                rcode = r = run_pipe(pi); /* NB: rcode is a smalluint, r is int */
8983                if (r != -1) {
8984                        /* We ran a builtin, function, or group.
8985                         * rcode is already known
8986                         * and we don't need to wait for anything. */
8987                        debug_printf_exec(": builtin/func exitcode %d\n", rcode);
8988                        G.last_exitcode = rcode;
8989                        check_and_run_traps();
8990#if ENABLE_HUSH_LOOPS
8991                        /* Was it "break" or "continue"? */
8992                        if (G.flag_break_continue) {
8993                                smallint fbc = G.flag_break_continue;
8994                                /* We might fall into outer *loop*,
8995                                 * don't want to break it too */
8996                                if (loop_top) {
8997                                        G.depth_break_continue--;
8998                                        if (G.depth_break_continue == 0)
8999                                                G.flag_break_continue = 0;
9000                                        /* else: e.g. "continue 2" should *break* once, *then* continue */
9001                                } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
9002                                if (G.depth_break_continue != 0 || fbc == BC_BREAK) {
9003                                        checkjobs(NULL, 0 /*(no pid to wait for)*/);
9004                                        break;
9005                                }
9006                                /* "continue": simulate end of loop */
9007                                rword = RES_DONE;
9008                                continue;
9009                        }
9010#endif
9011                        if (G_flag_return_in_progress == 1) {
9012                                checkjobs(NULL, 0 /*(no pid to wait for)*/);
9013                                break;
9014                        }
9015                } else if (pi->followup == PIPE_BG) {
9016                        /* What does bash do with attempts to background builtins? */
9017                        /* even bash 3.2 doesn't do that well with nested bg:
9018                         * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
9019                         * I'm NOT treating inner &'s as jobs */
9020#if ENABLE_HUSH_JOB
9021                        if (G.run_list_level == 1)
9022                                insert_job_into_table(pi);
9023#endif
9024                        /* Last command's pid goes to $! */
9025                        G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid;
9026                        G.last_bg_pid_exitcode = 0;
9027                        debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
9028/* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash say 0 */
9029                        rcode = EXIT_SUCCESS;
9030                        goto check_traps;
9031                } else {
9032#if ENABLE_HUSH_JOB
9033                        if (G.run_list_level == 1 && G_interactive_fd) {
9034                                /* Waits for completion, then fg's main shell */
9035                                rcode = checkjobs_and_fg_shell(pi);
9036                                debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode);
9037                                goto check_traps;
9038                        }
9039#endif
9040                        /* This one just waits for completion */
9041                        rcode = checkjobs(pi, 0 /*(no pid to wait for)*/);
9042                        debug_printf_exec(": checkjobs exitcode %d\n", rcode);
9043 check_traps:
9044                        G.last_exitcode = rcode;
9045                        check_and_run_traps();
9046                }
9047
9048                /* Handle "set -e" */
9049                if (rcode != 0 && G.o_opt[OPT_O_ERREXIT]) {
9050                        debug_printf_exec("ERREXIT:1 errexit_depth:%d\n", G.errexit_depth);
9051                        if (G.errexit_depth == 0)
9052                                hush_exit(rcode);
9053                }
9054                G.errexit_depth = sv_errexit_depth;
9055
9056                /* Analyze how result affects subsequent commands */
9057#if ENABLE_HUSH_IF
9058                if (rword == RES_IF || rword == RES_ELIF)
9059                        cond_code = rcode;
9060#endif
9061 check_jobs_and_continue:
9062                checkjobs(NULL, 0 /*(no pid to wait for)*/);
9063 dont_check_jobs_but_continue: ;
9064#if ENABLE_HUSH_LOOPS
9065                /* Beware of "while false; true; do ..."! */
9066                if (pi->next
9067                 && (pi->next->res_word == RES_DO || pi->next->res_word == RES_DONE)
9068                 /* check for RES_DONE is needed for "while ...; do \n done" case */
9069                ) {
9070                        if (rword == RES_WHILE) {
9071                                if (rcode) {
9072                                        /* "while false; do...done" - exitcode 0 */
9073                                        G.last_exitcode = rcode = EXIT_SUCCESS;
9074                                        debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
9075                                        break;
9076                                }
9077                        }
9078                        if (rword == RES_UNTIL) {
9079                                if (!rcode) {
9080                                        debug_printf_exec(": until expr is true: breaking\n");
9081                                        break;
9082                                }
9083                        }
9084                }
9085#endif
9086        } /* for (pi) */
9087
9088#if ENABLE_HUSH_JOB
9089        G.run_list_level--;
9090#endif
9091#if ENABLE_HUSH_LOOPS
9092        if (loop_top)
9093                G.depth_of_loop--;
9094        free(for_list);
9095#endif
9096#if ENABLE_HUSH_CASE
9097        free(case_word);
9098#endif
9099        debug_leave();
9100        debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode);
9101        return rcode;
9102}
9103
9104/* Select which version we will use */
9105static int run_and_free_list(struct pipe *pi)
9106{
9107        int rcode = 0;
9108        debug_printf_exec("run_and_free_list entered\n");
9109        if (!G.o_opt[OPT_O_NOEXEC]) {
9110                debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds);
9111                rcode = run_list(pi);
9112        }
9113        /* free_pipe_list has the side effect of clearing memory.
9114         * In the long run that function can be merged with run_list,
9115         * but doing that now would hobble the debugging effort. */
9116        free_pipe_list(pi);
9117        debug_printf_exec("run_and_free_list return %d\n", rcode);
9118        return rcode;
9119}
9120
9121
9122static void install_sighandlers(unsigned mask)
9123{
9124        sighandler_t old_handler;
9125        unsigned sig = 0;
9126        while ((mask >>= 1) != 0) {
9127                sig++;
9128                if (!(mask & 1))
9129                        continue;
9130                old_handler = install_sighandler(sig, pick_sighandler(sig));
9131                /* POSIX allows shell to re-enable SIGCHLD
9132                 * even if it was SIG_IGN on entry.
9133                 * Therefore we skip IGN check for it:
9134                 */
9135                if (sig == SIGCHLD)
9136                        continue;
9137                /* bash re-enables SIGHUP which is SIG_IGNed on entry.
9138                 * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
9139                 */
9140                //if (sig == SIGHUP) continue; - TODO?
9141                if (old_handler == SIG_IGN) {
9142                        /* oops... restore back to IGN, and record this fact */
9143                        install_sighandler(sig, old_handler);
9144#if ENABLE_HUSH_TRAP
9145                        if (!G_traps)
9146                                G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
9147                        free(G_traps[sig]);
9148                        G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
9149#endif
9150                }
9151        }
9152}
9153
9154/* Called a few times only (or even once if "sh -c") */
9155static void install_special_sighandlers(void)
9156{
9157        unsigned mask;
9158
9159        /* Which signals are shell-special? */
9160        mask = (1 << SIGQUIT) | (1 << SIGCHLD);
9161        if (G_interactive_fd) {
9162                mask |= SPECIAL_INTERACTIVE_SIGS;
9163                if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */
9164                        mask |= SPECIAL_JOBSTOP_SIGS;
9165        }
9166        /* Careful, do not re-install handlers we already installed */
9167        if (G.special_sig_mask != mask) {
9168                unsigned diff = mask & ~G.special_sig_mask;
9169                G.special_sig_mask = mask;
9170                install_sighandlers(diff);
9171        }
9172}
9173
9174#if ENABLE_HUSH_JOB
9175/* helper */
9176/* Set handlers to restore tty pgrp and exit */
9177static void install_fatal_sighandlers(void)
9178{
9179        unsigned mask;
9180
9181        /* We will restore tty pgrp on these signals */
9182        mask = 0
9183                /*+ (1 << SIGILL ) * HUSH_DEBUG*/
9184                /*+ (1 << SIGFPE ) * HUSH_DEBUG*/
9185                + (1 << SIGBUS ) * HUSH_DEBUG
9186                + (1 << SIGSEGV) * HUSH_DEBUG
9187                /*+ (1 << SIGTRAP) * HUSH_DEBUG*/
9188                + (1 << SIGABRT)
9189        /* bash 3.2 seems to handle these just like 'fatal' ones */
9190                + (1 << SIGPIPE)
9191                + (1 << SIGALRM)
9192        /* if we are interactive, SIGHUP, SIGTERM and SIGINT are special sigs.
9193         * if we aren't interactive... but in this case
9194         * we never want to restore pgrp on exit, and this fn is not called
9195         */
9196                /*+ (1 << SIGHUP )*/
9197                /*+ (1 << SIGTERM)*/
9198                /*+ (1 << SIGINT )*/
9199        ;
9200        G_fatal_sig_mask = mask;
9201
9202        install_sighandlers(mask);
9203}
9204#endif
9205
9206static int set_mode(int state, char mode, const char *o_opt)
9207{
9208        int idx;
9209        switch (mode) {
9210        case 'n':
9211                G.o_opt[OPT_O_NOEXEC] = state;
9212                break;
9213        case 'x':
9214                IF_HUSH_MODE_X(G_x_mode = state;)
9215                break;
9216        case 'o':
9217                if (!o_opt) {
9218                        /* "set -+o" without parameter.
9219                         * in bash, set -o produces this output:
9220                         *  pipefail        off
9221                         * and set +o:
9222                         *  set +o pipefail
9223                         * We always use the second form.
9224                         */
9225                        const char *p = o_opt_strings;
9226                        idx = 0;
9227                        while (*p) {
9228                                printf("set %co %s\n", (G.o_opt[idx] ? '-' : '+'), p);
9229                                idx++;
9230                                p += strlen(p) + 1;
9231                        }
9232                        break;
9233                }
9234                idx = index_in_strings(o_opt_strings, o_opt);
9235                if (idx >= 0) {
9236                        G.o_opt[idx] = state;
9237                        break;
9238                }
9239        case 'e':
9240                G.o_opt[OPT_O_ERREXIT] = state;
9241                break;
9242        default:
9243                return EXIT_FAILURE;
9244        }
9245        return EXIT_SUCCESS;
9246}
9247
9248int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
9249int hush_main(int argc, char **argv)
9250{
9251        enum {
9252                OPT_login = (1 << 0),
9253                OPT_s     = (1 << 1),
9254        };
9255        unsigned flags;
9256        unsigned builtin_argc;
9257        char **e;
9258        struct variable *cur_var;
9259        struct variable *shell_ver;
9260
9261        INIT_G();
9262        if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */
9263                G.last_exitcode = EXIT_SUCCESS;
9264
9265#if ENABLE_HUSH_FAST
9266        G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */
9267#endif
9268#if !BB_MMU
9269        G.argv0_for_re_execing = argv[0];
9270#endif
9271
9272        /* Deal with HUSH_VERSION */
9273        debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
9274        unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
9275        shell_ver = xzalloc(sizeof(*shell_ver));
9276        shell_ver->flg_export = 1;
9277        shell_ver->flg_read_only = 1;
9278        /* Code which handles ${var<op>...} needs writable values for all variables,
9279         * therefore we xstrdup: */
9280        shell_ver->varstr = xstrdup(hush_version_str);
9281
9282        /* Create shell local variables from the values
9283         * currently living in the environment */
9284        G.top_var = shell_ver;
9285        cur_var = G.top_var;
9286        e = environ;
9287        if (e) while (*e) {
9288                char *value = strchr(*e, '=');
9289                if (value) { /* paranoia */
9290                        cur_var->next = xzalloc(sizeof(*cur_var));
9291                        cur_var = cur_var->next;
9292                        cur_var->varstr = *e;
9293                        cur_var->max_len = strlen(*e);
9294                        cur_var->flg_export = 1;
9295                }
9296                e++;
9297        }
9298        /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */
9299        debug_printf_env("putenv '%s'\n", shell_ver->varstr);
9300        putenv(shell_ver->varstr);
9301
9302        /* Export PWD */
9303        set_pwd_var(SETFLAG_EXPORT);
9304
9305#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
9306        /* Set (but not export) PS1/2 unless already set */
9307        if (!get_local_var_value("PS1"))
9308                set_local_var_from_halves("PS1", "\\w \\$ ");
9309        if (!get_local_var_value("PS2"))
9310                set_local_var_from_halves("PS2", "> ");
9311#endif
9312
9313#if BASH_HOSTNAME_VAR
9314        /* Set (but not export) HOSTNAME unless already set */
9315        if (!get_local_var_value("HOSTNAME")) {
9316                struct utsname uts;
9317                uname(&uts);
9318                set_local_var_from_halves("HOSTNAME", uts.nodename);
9319        }
9320        /* bash also exports SHLVL and _,
9321         * and sets (but doesn't export) the following variables:
9322         * BASH=/bin/bash
9323         * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu")
9324         * BASH_VERSION='3.2.0(1)-release'
9325         * HOSTTYPE=i386
9326         * MACHTYPE=i386-pc-linux-gnu
9327         * OSTYPE=linux-gnu
9328         * PPID=<NNNNN> - we also do it elsewhere
9329         * EUID=<NNNNN>
9330         * UID=<NNNNN>
9331         * GROUPS=()
9332         * LINES=<NNN>
9333         * COLUMNS=<NNN>
9334         * BASH_ARGC=()
9335         * BASH_ARGV=()
9336         * BASH_LINENO=()
9337         * BASH_SOURCE=()
9338         * DIRSTACK=()
9339         * PIPESTATUS=([0]="0")
9340         * HISTFILE=/<xxx>/.bash_history
9341         * HISTFILESIZE=500
9342         * HISTSIZE=500
9343         * MAILCHECK=60
9344         * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
9345         * SHELL=/bin/bash
9346         * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
9347         * TERM=dumb
9348         * OPTERR=1
9349         * OPTIND=1
9350         * IFS=$' \t\n'
9351         * PS4='+ '
9352         */
9353#endif
9354
9355#if ENABLE_HUSH_LINENO_VAR
9356        if (ENABLE_HUSH_LINENO_VAR) {
9357                char *p = xasprintf("LINENO=%*s", (int)(sizeof(int)*3), "");
9358                set_local_var(p, /*flags*/ 0);
9359                G.lineno_var = p; /* can't assign before set_local_var("LINENO=...") */
9360        }
9361#endif
9362
9363#if ENABLE_FEATURE_EDITING
9364        G.line_input_state = new_line_input_t(FOR_SHELL);
9365#endif
9366
9367        /* Initialize some more globals to non-zero values */
9368        cmdedit_update_prompt();
9369
9370        die_func = restore_ttypgrp_and__exit;
9371
9372        /* Shell is non-interactive at first. We need to call
9373         * install_special_sighandlers() if we are going to execute "sh <script>",
9374         * "sh -c <cmds>" or login shell's /etc/profile and friends.
9375         * If we later decide that we are interactive, we run install_special_sighandlers()
9376         * in order to intercept (more) signals.
9377         */
9378
9379        /* Parse options */
9380        /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
9381        flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
9382        builtin_argc = 0;
9383        while (1) {
9384                int opt = getopt(argc, argv, "+c:exinsl"
9385#if !BB_MMU
9386                                "<:$:R:V:"
9387# if ENABLE_HUSH_FUNCTIONS
9388                                "F:"
9389# endif
9390#endif
9391                );
9392                if (opt <= 0)
9393                        break;
9394                switch (opt) {
9395                case 'c':
9396                        /* Possibilities:
9397                         * sh ... -c 'script'
9398                         * sh ... -c 'script' ARG0 [ARG1...]
9399                         * On NOMMU, if builtin_argc != 0,
9400                         * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...]
9401                         * "" needs to be replaced with NULL
9402                         * and BARGV vector fed to builtin function.
9403                         * Note: the form without ARG0 never happens:
9404                         * sh ... -c 'builtin' BARGV... ""
9405                         */
9406                        if (!G.root_pid) {
9407                                G.root_pid = getpid();
9408                                G.root_ppid = getppid();
9409                        }
9410                        G.global_argv = argv + optind;
9411                        G.global_argc = argc - optind;
9412                        if (builtin_argc) {
9413                                /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */
9414                                const struct built_in_command *x;
9415
9416                                install_special_sighandlers();
9417                                x = find_builtin(optarg);
9418                                if (x) { /* paranoia */
9419                                        G.global_argc -= builtin_argc; /* skip [BARGV...] "" */
9420                                        G.global_argv += builtin_argc;
9421                                        G.global_argv[-1] = NULL; /* replace "" */
9422                                        fflush_all();
9423                                        G.last_exitcode = x->b_function(argv + optind - 1);
9424                                }
9425                                goto final_return;
9426                        }
9427                        if (!G.global_argv[0]) {
9428                                /* -c 'script' (no params): prevent empty $0 */
9429                                G.global_argv--; /* points to argv[i] of 'script' */
9430                                G.global_argv[0] = argv[0];
9431                                G.global_argc++;
9432                        } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */
9433                        install_special_sighandlers();
9434                        parse_and_run_string(optarg);
9435                        goto final_return;
9436                case 'i':
9437                        /* Well, we cannot just declare interactiveness,
9438                         * we have to have some stuff (ctty, etc) */
9439                        /* G_interactive_fd++; */
9440                        break;
9441                case 's':
9442                        flags |= OPT_s;
9443                        break;
9444                case 'l':
9445                        flags |= OPT_login;
9446                        break;
9447#if !BB_MMU
9448                case '<': /* "big heredoc" support */
9449                        full_write1_str(optarg);
9450                        _exit(0);
9451                case '$': {
9452                        unsigned long long empty_trap_mask;
9453
9454                        G.root_pid = bb_strtou(optarg, &optarg, 16);
9455                        optarg++;
9456                        G.root_ppid = bb_strtou(optarg, &optarg, 16);
9457                        optarg++;
9458                        G.last_bg_pid = bb_strtou(optarg, &optarg, 16);
9459                        optarg++;
9460                        G.last_exitcode = bb_strtou(optarg, &optarg, 16);
9461                        optarg++;
9462                        builtin_argc = bb_strtou(optarg, &optarg, 16);
9463                        optarg++;
9464                        empty_trap_mask = bb_strtoull(optarg, &optarg, 16);
9465                        if (empty_trap_mask != 0) {
9466                                IF_HUSH_TRAP(int sig;)
9467                                install_special_sighandlers();
9468# if ENABLE_HUSH_TRAP
9469                                G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
9470                                for (sig = 1; sig < NSIG; sig++) {
9471                                        if (empty_trap_mask & (1LL << sig)) {
9472                                                G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
9473                                                install_sighandler(sig, SIG_IGN);
9474                                        }
9475                                }
9476# endif
9477                        }
9478# if ENABLE_HUSH_LOOPS
9479                        optarg++;
9480                        G.depth_of_loop = bb_strtou(optarg, &optarg, 16);
9481# endif
9482# if ENABLE_HUSH_FUNCTIONS
9483                        /* nommu uses re-exec trick for "... | func | ...",
9484                         * should allow "return".
9485                         * This accidentally allows returns in subshells.
9486                         */
9487                        G_flag_return_in_progress = -1;
9488# endif
9489                        break;
9490                }
9491                case 'R':
9492                case 'V':
9493                        set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0);
9494                        break;
9495# if ENABLE_HUSH_FUNCTIONS
9496                case 'F': {
9497                        struct function *funcp = new_function(optarg);
9498                        /* funcp->name is already set to optarg */
9499                        /* funcp->body is set to NULL. It's a special case. */
9500                        funcp->body_as_string = argv[optind];
9501                        optind++;
9502                        break;
9503                }
9504# endif
9505#endif
9506                case 'n':
9507                case 'x':
9508                case 'e':
9509                        if (set_mode(1, opt, NULL) == 0) /* no error */
9510                                break;
9511                default:
9512#ifndef BB_VER
9513                        fprintf(stderr, "Usage: sh [FILE]...\n"
9514                                        "   or: sh -c command [args]...\n\n");
9515                        exit(EXIT_FAILURE);
9516#else
9517                        bb_show_usage();
9518#endif
9519                }
9520        } /* option parsing loop */
9521
9522        /* Skip options. Try "hush -l": $1 should not be "-l"! */
9523        G.global_argc = argc - (optind - 1);
9524        G.global_argv = argv + (optind - 1);
9525        G.global_argv[0] = argv[0];
9526
9527        if (!G.root_pid) {
9528                G.root_pid = getpid();
9529                G.root_ppid = getppid();
9530        }
9531
9532        /* If we are login shell... */
9533        if (flags & OPT_login) {
9534                FILE *input;
9535                debug_printf("sourcing /etc/profile\n");
9536                input = fopen_for_read("/etc/profile");
9537                if (input != NULL) {
9538                        remember_FILE(input);
9539                        install_special_sighandlers();
9540                        parse_and_run_file(input);
9541                        fclose_and_forget(input);
9542                }
9543                /* bash: after sourcing /etc/profile,
9544                 * tries to source (in the given order):
9545                 * ~/.bash_profile, ~/.bash_login, ~/.profile,
9546                 * stopping on first found. --noprofile turns this off.
9547                 * bash also sources ~/.bash_logout on exit.
9548                 * If called as sh, skips .bash_XXX files.
9549                 */
9550        }
9551
9552        /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
9553        if (!(flags & OPT_s) && G.global_argv[1]) {
9554                FILE *input;
9555                /*
9556                 * "bash <script>" (which is never interactive (unless -i?))
9557                 * sources $BASH_ENV here (without scanning $PATH).
9558                 * If called as sh, does the same but with $ENV.
9559                 * Also NB, per POSIX, $ENV should undergo parameter expansion.
9560                 */
9561                G.global_argc--;
9562                G.global_argv++;
9563                debug_printf("running script '%s'\n", G.global_argv[0]);
9564                xfunc_error_retval = 127; /* for "hush /does/not/exist" case */
9565                input = xfopen_for_read(G.global_argv[0]);
9566                xfunc_error_retval = 1;
9567                remember_FILE(input);
9568                install_special_sighandlers();
9569                parse_and_run_file(input);
9570#if ENABLE_FEATURE_CLEAN_UP
9571                fclose_and_forget(input);
9572#endif
9573                goto final_return;
9574        }
9575
9576        /* Up to here, shell was non-interactive. Now it may become one.
9577         * NB: don't forget to (re)run install_special_sighandlers() as needed.
9578         */
9579
9580        /* A shell is interactive if the '-i' flag was given,
9581         * or if all of the following conditions are met:
9582         *    no -c command
9583         *    no arguments remaining or the -s flag given
9584         *    standard input is a terminal
9585         *    standard output is a terminal
9586         * Refer to Posix.2, the description of the 'sh' utility.
9587         */
9588#if ENABLE_HUSH_JOB
9589        if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
9590                G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
9591                debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp);
9592                if (G_saved_tty_pgrp < 0)
9593                        G_saved_tty_pgrp = 0;
9594
9595                /* try to dup stdin to high fd#, >= 255 */
9596                G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
9597                if (G_interactive_fd < 0) {
9598                        /* try to dup to any fd */
9599                        G_interactive_fd = dup(STDIN_FILENO);
9600                        if (G_interactive_fd < 0) {
9601                                /* give up */
9602                                G_interactive_fd = 0;
9603                                G_saved_tty_pgrp = 0;
9604                        }
9605                }
9606// TODO: track & disallow any attempts of user
9607// to (inadvertently) close/redirect G_interactive_fd
9608        }
9609        debug_printf("interactive_fd:%d\n", G_interactive_fd);
9610        if (G_interactive_fd) {
9611                close_on_exec_on(G_interactive_fd);
9612
9613                if (G_saved_tty_pgrp) {
9614                        /* If we were run as 'hush &', sleep until we are
9615                         * in the foreground (tty pgrp == our pgrp).
9616                         * If we get started under a job aware app (like bash),
9617                         * make sure we are now in charge so we don't fight over
9618                         * who gets the foreground */
9619                        while (1) {
9620                                pid_t shell_pgrp = getpgrp();
9621                                G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd);
9622                                if (G_saved_tty_pgrp == shell_pgrp)
9623                                        break;
9624                                /* send TTIN to ourself (should stop us) */
9625                                kill(- shell_pgrp, SIGTTIN);
9626                        }
9627                }
9628
9629                /* Install more signal handlers */
9630                install_special_sighandlers();
9631
9632                if (G_saved_tty_pgrp) {
9633                        /* Set other signals to restore saved_tty_pgrp */
9634                        install_fatal_sighandlers();
9635                        /* Put ourselves in our own process group
9636                         * (bash, too, does this only if ctty is available) */
9637                        bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
9638                        /* Grab control of the terminal */
9639                        tcsetpgrp(G_interactive_fd, getpid());
9640                }
9641                enable_restore_tty_pgrp_on_exit();
9642
9643# if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
9644                {
9645                        const char *hp = get_local_var_value("HISTFILE");
9646                        if (!hp) {
9647                                hp = get_local_var_value("HOME");
9648                                if (hp)
9649                                        hp = concat_path_file(hp, ".hush_history");
9650                        } else {
9651                                hp = xstrdup(hp);
9652                        }
9653                        if (hp) {
9654                                G.line_input_state->hist_file = hp;
9655                                //set_local_var(xasprintf("HISTFILE=%s", ...));
9656                        }
9657#  if ENABLE_FEATURE_SH_HISTFILESIZE
9658                        hp = get_local_var_value("HISTFILESIZE");
9659                        G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
9660#  endif
9661                }
9662# endif
9663        } else {
9664                install_special_sighandlers();
9665        }
9666#elif ENABLE_HUSH_INTERACTIVE
9667        /* No job control compiled in, only prompt/line editing */
9668        if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
9669                G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
9670                if (G_interactive_fd < 0) {
9671                        /* try to dup to any fd */
9672                        G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1);
9673                        if (G_interactive_fd < 0)
9674                                /* give up */
9675                                G_interactive_fd = 0;
9676                }
9677        }
9678        if (G_interactive_fd) {
9679                close_on_exec_on(G_interactive_fd);
9680        }
9681        install_special_sighandlers();
9682#else
9683        /* We have interactiveness code disabled */
9684        install_special_sighandlers();
9685#endif
9686        /* bash:
9687         * if interactive but not a login shell, sources ~/.bashrc
9688         * (--norc turns this off, --rcfile <file> overrides)
9689         */
9690
9691        if (!ENABLE_FEATURE_SH_EXTRA_QUIET && G_interactive_fd) {
9692                /* note: ash and hush share this string */
9693                printf("\n\n%s %s\n"
9694                        IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n")
9695                        "\n",
9696                        bb_banner,
9697                        "hush - the humble shell"
9698                );
9699        }
9700
9701        parse_and_run_file(stdin);
9702
9703 final_return:
9704        hush_exit(G.last_exitcode);
9705}
9706
9707
9708/*
9709 * Built-ins
9710 */
9711static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM)
9712{
9713        return 0;
9714}
9715
9716#if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL
9717static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv))
9718{
9719        int argc = string_array_len(argv);
9720        return applet_main_func(argc, argv);
9721}
9722#endif
9723#if ENABLE_HUSH_TEST || BASH_TEST2
9724static int FAST_FUNC builtin_test(char **argv)
9725{
9726        return run_applet_main(argv, test_main);
9727}
9728#endif
9729#if ENABLE_HUSH_ECHO
9730static int FAST_FUNC builtin_echo(char **argv)
9731{
9732        return run_applet_main(argv, echo_main);
9733}
9734#endif
9735#if ENABLE_HUSH_PRINTF
9736static int FAST_FUNC builtin_printf(char **argv)
9737{
9738        return run_applet_main(argv, printf_main);
9739}
9740#endif
9741
9742#if ENABLE_HUSH_HELP
9743static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
9744{
9745        const struct built_in_command *x;
9746
9747        printf(
9748                "Built-in commands:\n"
9749                "------------------\n");
9750        for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
9751                if (x->b_descr)
9752                        printf("%-10s%s\n", x->b_cmd, x->b_descr);
9753        }
9754        return EXIT_SUCCESS;
9755}
9756#endif
9757
9758#if MAX_HISTORY && ENABLE_FEATURE_EDITING
9759static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM)
9760{
9761        show_history(G.line_input_state);
9762        return EXIT_SUCCESS;
9763}
9764#endif
9765
9766static char **skip_dash_dash(char **argv)
9767{
9768        argv++;
9769        if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0')
9770                argv++;
9771        return argv;
9772}
9773
9774static int FAST_FUNC builtin_cd(char **argv)
9775{
9776        const char *newdir;
9777
9778        argv = skip_dash_dash(argv);
9779        newdir = argv[0];
9780        if (newdir == NULL) {
9781                /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
9782                 * bash says "bash: cd: HOME not set" and does nothing
9783                 * (exitcode 1)
9784                 */
9785                const char *home = get_local_var_value("HOME");
9786                newdir = home ? home : "/";
9787        }
9788        if (chdir(newdir)) {
9789                /* Mimic bash message exactly */
9790                bb_perror_msg("cd: %s", newdir);
9791                return EXIT_FAILURE;
9792        }
9793        /* Read current dir (get_cwd(1) is inside) and set PWD.
9794         * Note: do not enforce exporting. If PWD was unset or unexported,
9795         * set it again, but do not export. bash does the same.
9796         */
9797        set_pwd_var(/*flag:*/ 0);
9798        return EXIT_SUCCESS;
9799}
9800
9801static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM)
9802{
9803        puts(get_cwd(0));
9804        return EXIT_SUCCESS;
9805}
9806
9807static int FAST_FUNC builtin_eval(char **argv)
9808{
9809        int rcode = EXIT_SUCCESS;
9810
9811        argv = skip_dash_dash(argv);
9812        if (argv[0]) {
9813                char *str = NULL;
9814
9815                if (argv[1]) {
9816                        /* "The eval utility shall construct a command by
9817                         * concatenating arguments together, separating
9818                         * each with a <space> character."
9819                         */
9820                        char *p;
9821                        unsigned len = 0;
9822                        char **pp = argv;
9823                        do
9824                                len += strlen(*pp) + 1;
9825                        while (*++pp);
9826                        str = p = xmalloc(len);
9827                        pp = argv;
9828                        do {
9829                                p = stpcpy(p, *pp);
9830                                *p++ = ' ';
9831                        } while (*++pp);
9832                        p[-1] = '\0';
9833                }
9834
9835                /* bash:
9836                 * eval "echo Hi; done" ("done" is syntax error):
9837                 * "echo Hi" will not execute too.
9838                 */
9839                parse_and_run_string(str ? str : argv[0]);
9840                free(str);
9841                rcode = G.last_exitcode;
9842        }
9843        return rcode;
9844}
9845
9846static int FAST_FUNC builtin_exec(char **argv)
9847{
9848        argv = skip_dash_dash(argv);
9849        if (argv[0] == NULL)
9850                return EXIT_SUCCESS; /* bash does this */
9851
9852        /* Careful: we can end up here after [v]fork. Do not restore
9853         * tty pgrp then, only top-level shell process does that */
9854        if (G_saved_tty_pgrp && getpid() == G.root_pid)
9855                tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
9856
9857        /* Saved-redirect fds, script fds and G_interactive_fd are still
9858         * open here. However, they are all CLOEXEC, and execv below
9859         * closes them. Try interactive "exec ls -l /proc/self/fd",
9860         * it should show no extra open fds in the "ls" process.
9861         * If we'd try to run builtins/NOEXECs, this would need improving.
9862         */
9863        //close_saved_fds_and_FILE_fds();
9864
9865        /* TODO: if exec fails, bash does NOT exit! We do.
9866         * We'll need to undo trap cleanup (it's inside execvp_or_die)
9867         * and tcsetpgrp, and this is inherently racy.
9868         */
9869        execvp_or_die(argv);
9870}
9871
9872static int FAST_FUNC builtin_exit(char **argv)
9873{
9874        debug_printf_exec("%s()\n", __func__);
9875
9876        /* interactive bash:
9877         * # trap "echo EEE" EXIT
9878         * # exit
9879         * exit
9880         * There are stopped jobs.
9881         * (if there are _stopped_ jobs, running ones don't count)
9882         * # exit
9883         * exit
9884         * EEE (then bash exits)
9885         *
9886         * TODO: we can use G.exiting = -1 as indicator "last cmd was exit"
9887         */
9888
9889        /* note: EXIT trap is run by hush_exit */
9890        argv = skip_dash_dash(argv);
9891        if (argv[0] == NULL)
9892                hush_exit(G.last_exitcode);
9893        /* mimic bash: exit 123abc == exit 255 + error msg */
9894        xfunc_error_retval = 255;
9895        /* bash: exit -2 == exit 254, no error msg */
9896        hush_exit(xatoi(argv[0]) & 0xff);
9897}
9898
9899#if ENABLE_HUSH_TYPE
9900/* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
9901static int FAST_FUNC builtin_type(char **argv)
9902{
9903        int ret = EXIT_SUCCESS;
9904
9905        while (*++argv) {
9906                const char *type;
9907                char *path = NULL;
9908
9909                if (0) {} /* make conditional compile easier below */
9910                /*else if (find_alias(*argv))
9911                        type = "an alias";*/
9912#if ENABLE_HUSH_FUNCTIONS
9913                else if (find_function(*argv))
9914                        type = "a function";
9915#endif
9916                else if (find_builtin(*argv))
9917                        type = "a shell builtin";
9918                else if ((path = find_in_path(*argv)) != NULL)
9919                        type = path;
9920                else {
9921                        bb_error_msg("type: %s: not found", *argv);
9922                        ret = EXIT_FAILURE;
9923                        continue;
9924                }
9925
9926                printf("%s is %s\n", *argv, type);
9927                free(path);
9928        }
9929
9930        return ret;
9931}
9932#endif
9933
9934#if ENABLE_HUSH_READ
9935/* Interruptibility of read builtin in bash
9936 * (tested on bash-4.2.8 by sending signals (not by ^C)):
9937 *
9938 * Empty trap makes read ignore corresponding signal, for any signal.
9939 *
9940 * SIGINT:
9941 * - terminates non-interactive shell;
9942 * - interrupts read in interactive shell;
9943 * if it has non-empty trap:
9944 * - executes trap and returns to command prompt in interactive shell;
9945 * - executes trap and returns to read in non-interactive shell;
9946 * SIGTERM:
9947 * - is ignored (does not interrupt) read in interactive shell;
9948 * - terminates non-interactive shell;
9949 * if it has non-empty trap:
9950 * - executes trap and returns to read;
9951 * SIGHUP:
9952 * - terminates shell (regardless of interactivity);
9953 * if it has non-empty trap:
9954 * - executes trap and returns to read;
9955 * SIGCHLD from children:
9956 * - does not interrupt read regardless of interactivity:
9957 *   try: sleep 1 & read x; echo $x
9958 */
9959static int FAST_FUNC builtin_read(char **argv)
9960{
9961        const char *r;
9962        char *opt_n = NULL;
9963        char *opt_p = NULL;
9964        char *opt_t = NULL;
9965        char *opt_u = NULL;
9966        char *opt_d = NULL; /* optimized out if !BASH */
9967        const char *ifs;
9968        int read_flags;
9969
9970        /* "!": do not abort on errors.
9971         * Option string must start with "sr" to match BUILTIN_READ_xxx
9972         */
9973        read_flags = getopt32(argv,
9974#if BASH_READ_D
9975                "!srn:p:t:u:d:", &opt_n, &opt_p, &opt_t, &opt_u, &opt_d
9976#else
9977                "!srn:p:t:u:", &opt_n, &opt_p, &opt_t, &opt_u
9978#endif
9979        );
9980        if (read_flags == (uint32_t)-1)
9981                return EXIT_FAILURE;
9982        argv += optind;
9983        ifs = get_local_var_value("IFS"); /* can be NULL */
9984
9985 again:
9986        r = shell_builtin_read(set_local_var_from_halves,
9987                argv,
9988                ifs,
9989                read_flags,
9990                opt_n,
9991                opt_p,
9992                opt_t,
9993                opt_u,
9994                opt_d
9995        );
9996
9997        if ((uintptr_t)r == 1 && errno == EINTR) {
9998                unsigned sig = check_and_run_traps();
9999                if (sig != SIGINT)
10000                        goto again;
10001        }
10002
10003        if ((uintptr_t)r > 1) {
10004                bb_error_msg("%s", r);
10005                r = (char*)(uintptr_t)1;
10006        }
10007
10008        return (uintptr_t)r;
10009}
10010#endif
10011
10012#if ENABLE_HUSH_UMASK
10013static int FAST_FUNC builtin_umask(char **argv)
10014{
10015        int rc;
10016        mode_t mask;
10017
10018        rc = 1;
10019        mask = umask(0);
10020        argv = skip_dash_dash(argv);
10021        if (argv[0]) {
10022                mode_t old_mask = mask;
10023
10024                /* numeric umasks are taken as-is */
10025                /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
10026                if (!isdigit(argv[0][0]))
10027                        mask ^= 0777;
10028                mask = bb_parse_mode(argv[0], mask);
10029                if (!isdigit(argv[0][0]))
10030                        mask ^= 0777;
10031                if ((unsigned)mask > 0777) {
10032                        mask = old_mask;
10033                        /* bash messages:
10034                         * bash: umask: 'q': invalid symbolic mode operator
10035                         * bash: umask: 999: octal number out of range
10036                         */
10037                        bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]);
10038                        rc = 0;
10039                }
10040        } else {
10041                /* Mimic bash */
10042                printf("%04o\n", (unsigned) mask);
10043                /* fall through and restore mask which we set to 0 */
10044        }
10045        umask(mask);
10046
10047        return !rc; /* rc != 0 - success */
10048}
10049#endif
10050
10051#if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP
10052static void print_escaped(const char *s)
10053{
10054        if (*s == '\'')
10055                goto squote;
10056        do {
10057                const char *p = strchrnul(s, '\'');
10058                /* print 'xxxx', possibly just '' */
10059                printf("'%.*s'", (int)(p - s), s);
10060                if (*p == '\0')
10061                        break;
10062                s = p;
10063 squote:
10064                /* s points to '; print "'''...'''" */
10065                putchar('"');
10066                do putchar('\''); while (*++s == '\'');
10067                putchar('"');
10068        } while (*s);
10069}
10070#endif
10071
10072#if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY
10073static int helper_export_local(char **argv, unsigned flags)
10074{
10075        do {
10076                char *name = *argv;
10077                char *name_end = strchrnul(name, '=');
10078
10079                /* So far we do not check that name is valid (TODO?) */
10080
10081                if (*name_end == '\0') {
10082                        struct variable *var, **vpp;
10083
10084                        vpp = get_ptr_to_local_var(name, name_end - name);
10085                        var = vpp ? *vpp : NULL;
10086
10087                        if (flags & SETFLAG_UNEXPORT) {
10088                                /* export -n NAME (without =VALUE) */
10089                                if (var) {
10090                                        var->flg_export = 0;
10091                                        debug_printf_env("%s: unsetenv '%s'\n", __func__, name);
10092                                        unsetenv(name);
10093                                } /* else: export -n NOT_EXISTING_VAR: no-op */
10094                                continue;
10095                        }
10096                        if (flags & SETFLAG_EXPORT) {
10097                                /* export NAME (without =VALUE) */
10098                                if (var) {
10099                                        var->flg_export = 1;
10100                                        debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
10101                                        putenv(var->varstr);
10102                                        continue;
10103                                }
10104                        }
10105                        if (flags & SETFLAG_MAKE_RO) {
10106                                /* readonly NAME (without =VALUE) */
10107                                if (var) {
10108                                        var->flg_read_only = 1;
10109                                        continue;
10110                                }
10111                        }
10112# if ENABLE_HUSH_LOCAL
10113                        /* Is this "local" bltin? */
10114                        if (!(flags & (SETFLAG_EXPORT|SETFLAG_UNEXPORT|SETFLAG_MAKE_RO))) {
10115                                unsigned lvl = flags >> SETFLAG_VARLVL_SHIFT;
10116                                if (var && var->var_nest_level == lvl) {
10117                                        /* "local x=abc; ...; local x" - ignore second local decl */
10118                                        continue;
10119                                }
10120                        }
10121# endif
10122                        /* Exporting non-existing variable.
10123                         * bash does not put it in environment,
10124                         * but remembers that it is exported,
10125                         * and does put it in env when it is set later.
10126                         * We just set it to "" and export.
10127                         */
10128                        /* Or, it's "local NAME" (without =VALUE).
10129                         * bash sets the value to "".
10130                         */
10131                        /* Or, it's "readonly NAME" (without =VALUE).
10132                         * bash remembers NAME and disallows its creation
10133                         * in the future.
10134                         */
10135                        name = xasprintf("%s=", name);
10136                } else {
10137                        /* (Un)exporting/making local NAME=VALUE */
10138                        name = xstrdup(name);
10139                }
10140                debug_printf_env("%s: set_local_var('%s')\n", __func__, name);
10141                if (set_local_var(name, flags))
10142                        return EXIT_FAILURE;
10143        } while (*++argv);
10144        return EXIT_SUCCESS;
10145}
10146#endif
10147
10148#if ENABLE_HUSH_EXPORT
10149static int FAST_FUNC builtin_export(char **argv)
10150{
10151        unsigned opt_unexport;
10152
10153#if ENABLE_HUSH_EXPORT_N
10154        /* "!": do not abort on errors */
10155        opt_unexport = getopt32(argv, "!n");
10156        if (opt_unexport == (uint32_t)-1)
10157                return EXIT_FAILURE;
10158        argv += optind;
10159#else
10160        opt_unexport = 0;
10161        argv++;
10162#endif
10163
10164        if (argv[0] == NULL) {
10165                char **e = environ;
10166                if (e) {
10167                        while (*e) {
10168#if 0
10169                                puts(*e++);
10170#else
10171                                /* ash emits: export VAR='VAL'
10172                                 * bash: declare -x VAR="VAL"
10173                                 * we follow ash example */
10174                                const char *s = *e++;
10175                                const char *p = strchr(s, '=');
10176
10177                                if (!p) /* wtf? take next variable */
10178                                        continue;
10179                                /* export var= */
10180                                printf("export %.*s", (int)(p - s) + 1, s);
10181                                print_escaped(p + 1);
10182                                putchar('\n');
10183#endif
10184                        }
10185                        /*fflush_all(); - done after each builtin anyway */
10186                }
10187                return EXIT_SUCCESS;
10188        }
10189
10190        return helper_export_local(argv, opt_unexport ? SETFLAG_UNEXPORT : SETFLAG_EXPORT);
10191}
10192#endif
10193
10194#if ENABLE_HUSH_LOCAL
10195static int FAST_FUNC builtin_local(char **argv)
10196{
10197        if (G.func_nest_level == 0) {
10198                bb_error_msg("%s: not in a function", argv[0]);
10199                return EXIT_FAILURE; /* bash compat */
10200        }
10201        argv++;
10202        /* Since all builtins run in a nested variable level,
10203         * need to use level - 1 here. Or else the variable will be removed at once
10204         * after builtin returns.
10205         */
10206        return helper_export_local(argv, (G.var_nest_level - 1) << SETFLAG_VARLVL_SHIFT);
10207}
10208#endif
10209
10210#if ENABLE_HUSH_READONLY
10211static int FAST_FUNC builtin_readonly(char **argv)
10212{
10213        argv++;
10214        if (*argv == NULL) {
10215                /* bash: readonly [-p]: list all readonly VARs
10216                 * (-p has no effect in bash)
10217                 */
10218                struct variable *e;
10219                for (e = G.top_var; e; e = e->next) {
10220                        if (e->flg_read_only) {
10221//TODO: quote value: readonly VAR='VAL'
10222                                printf("readonly %s\n", e->varstr);
10223                        }
10224                }
10225                return EXIT_SUCCESS;
10226        }
10227        return helper_export_local(argv, SETFLAG_MAKE_RO);
10228}
10229#endif
10230
10231#if ENABLE_HUSH_UNSET
10232/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
10233static int FAST_FUNC builtin_unset(char **argv)
10234{
10235        int ret;
10236        unsigned opts;
10237
10238        /* "!": do not abort on errors */
10239        /* "+": stop at 1st non-option */
10240        opts = getopt32(argv, "!+vf");
10241        if (opts == (unsigned)-1)
10242                return EXIT_FAILURE;
10243        if (opts == 3) {
10244                bb_error_msg("unset: -v and -f are exclusive");
10245                return EXIT_FAILURE;
10246        }
10247        argv += optind;
10248
10249        ret = EXIT_SUCCESS;
10250        while (*argv) {
10251                if (!(opts & 2)) { /* not -f */
10252                        if (unset_local_var(*argv)) {
10253                                /* unset <nonexistent_var> doesn't fail.
10254                                 * Error is when one tries to unset RO var.
10255                                 * Message was printed by unset_local_var. */
10256                                ret = EXIT_FAILURE;
10257                        }
10258                }
10259# if ENABLE_HUSH_FUNCTIONS
10260                else {
10261                        unset_func(*argv);
10262                }
10263# endif
10264                argv++;
10265        }
10266        return ret;
10267}
10268#endif
10269
10270#if ENABLE_HUSH_SET
10271/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
10272 * built-in 'set' handler
10273 * SUSv3 says:
10274 * set [-abCefhmnuvx] [-o option] [argument...]
10275 * set [+abCefhmnuvx] [+o option] [argument...]
10276 * set -- [argument...]
10277 * set -o
10278 * set +o
10279 * Implementations shall support the options in both their hyphen and
10280 * plus-sign forms. These options can also be specified as options to sh.
10281 * Examples:
10282 * Write out all variables and their values: set
10283 * Set $1, $2, and $3 and set "$#" to 3: set c a b
10284 * Turn on the -x and -v options: set -xv
10285 * Unset all positional parameters: set --
10286 * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
10287 * Set the positional parameters to the expansion of x, even if x expands
10288 * with a leading '-' or '+': set -- $x
10289 *
10290 * So far, we only support "set -- [argument...]" and some of the short names.
10291 */
10292static int FAST_FUNC builtin_set(char **argv)
10293{
10294        int n;
10295        char **pp, **g_argv;
10296        char *arg = *++argv;
10297
10298        if (arg == NULL) {
10299                struct variable *e;
10300                for (e = G.top_var; e; e = e->next)
10301                        puts(e->varstr);
10302                return EXIT_SUCCESS;
10303        }
10304
10305        do {
10306                if (strcmp(arg, "--") == 0) {
10307                        ++argv;
10308                        goto set_argv;
10309                }
10310                if (arg[0] != '+' && arg[0] != '-')
10311                        break;
10312                for (n = 1; arg[n]; ++n) {
10313                        if (set_mode((arg[0] == '-'), arg[n], argv[1]))
10314                                goto error;
10315                        if (arg[n] == 'o' && argv[1])
10316                                argv++;
10317                }
10318        } while ((arg = *++argv) != NULL);
10319        /* Now argv[0] is 1st argument */
10320
10321        if (arg == NULL)
10322                return EXIT_SUCCESS;
10323 set_argv:
10324
10325        /* NB: G.global_argv[0] ($0) is never freed/changed */
10326        g_argv = G.global_argv;
10327        if (G.global_args_malloced) {
10328                pp = g_argv;
10329                while (*++pp)
10330                        free(*pp);
10331                g_argv[1] = NULL;
10332        } else {
10333                G.global_args_malloced = 1;
10334                pp = xzalloc(sizeof(pp[0]) * 2);
10335                pp[0] = g_argv[0]; /* retain $0 */
10336                g_argv = pp;
10337        }
10338        /* This realloc's G.global_argv */
10339        G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1);
10340
10341        G.global_argc = 1 + string_array_len(pp + 1);
10342
10343        return EXIT_SUCCESS;
10344
10345        /* Nothing known, so abort */
10346 error:
10347        bb_error_msg("%s: %s: invalid option", "set", arg);
10348        return EXIT_FAILURE;
10349}
10350#endif
10351
10352static int FAST_FUNC builtin_shift(char **argv)
10353{
10354        int n = 1;
10355        argv = skip_dash_dash(argv);
10356        if (argv[0]) {
10357                n = bb_strtou(argv[0], NULL, 10);
10358                if (errno || n < 0) {
10359                        /* shared string with ash.c */
10360                        bb_error_msg("Illegal number: %s", argv[0]);
10361                        /*
10362                         * ash aborts in this case.
10363                         * bash prints error message and set $? to 1.
10364                         * Interestingly, for "shift 99999" bash does not
10365                         * print error message, but does set $? to 1
10366                         * (and does no shifting at all).
10367                         */
10368                }
10369        }
10370        if (n >= 0 && n < G.global_argc) {
10371                if (G_global_args_malloced) {
10372                        int m = 1;
10373                        while (m <= n)
10374                                free(G.global_argv[m++]);
10375                }
10376                G.global_argc -= n;
10377                memmove(&G.global_argv[1], &G.global_argv[n+1],
10378                                G.global_argc * sizeof(G.global_argv[0]));
10379                return EXIT_SUCCESS;
10380        }
10381        return EXIT_FAILURE;
10382}
10383
10384#if ENABLE_HUSH_GETOPTS
10385static int FAST_FUNC builtin_getopts(char **argv)
10386{
10387/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
10388
10389TODO:
10390If a required argument is not found, and getopts is not silent,
10391a question mark (?) is placed in VAR, OPTARG is unset, and a
10392diagnostic message is printed.  If getopts is silent, then a
10393colon (:) is placed in VAR and OPTARG is set to the option
10394character found.
10395
10396Test that VAR is a valid variable name?
10397
10398"Whenever the shell is invoked, OPTIND shall be initialized to 1"
10399*/
10400        char cbuf[2];
10401        const char *cp, *optstring, *var;
10402        int c, n, exitcode, my_opterr;
10403        unsigned count;
10404
10405        optstring = *++argv;
10406        if (!optstring || !(var = *++argv)) {
10407                bb_error_msg("usage: getopts OPTSTRING VAR [ARGS]");
10408                return EXIT_FAILURE;
10409        }
10410
10411        if (argv[1])
10412                argv[0] = G.global_argv[0]; /* for error messages in getopt() */
10413        else
10414                argv = G.global_argv;
10415        cbuf[1] = '\0';
10416
10417        my_opterr = 0;
10418        if (optstring[0] != ':') {
10419                cp = get_local_var_value("OPTERR");
10420                /* 0 if "OPTERR=0", 1 otherwise */
10421                my_opterr = (!cp || NOT_LONE_CHAR(cp, '0'));
10422        }
10423
10424        /* getopts stops on first non-option. Add "+" to force that */
10425        /*if (optstring[0] != '+')*/ {
10426                char *s = alloca(strlen(optstring) + 2);
10427                sprintf(s, "+%s", optstring);
10428                optstring = s;
10429        }
10430
10431        /* Naively, now we should just
10432         *      cp = get_local_var_value("OPTIND");
10433         *      optind = cp ? atoi(cp) : 0;
10434         *      optarg = NULL;
10435         *      opterr = my_opterr;
10436         *      c = getopt(string_array_len(argv), argv, optstring);
10437         * and be done? Not so fast...
10438         * Unlike normal getopt() usage in C programs, here
10439         * each successive call will (usually) have the same argv[] CONTENTS,
10440         * but not the ADDRESSES. Worse yet, it's possible that between
10441         * invocations of "getopts", there will be calls to shell builtins
10442         * which use getopt() internally. Example:
10443         *      while getopts "abc" RES -a -bc -abc de; do
10444         *              unset -ff func
10445         *      done
10446         * This would not work correctly: getopt() call inside "unset"
10447         * modifies internal libc state which is tracking position in
10448         * multi-option strings ("-abc"). At best, it can skip options
10449         * or return the same option infinitely. With glibc implementation
10450         * of getopt(), it would use outright invalid pointers and return
10451         * garbage even _without_ "unset" mangling internal state.
10452         *
10453         * We resort to resetting getopt() state and calling it N times,
10454         * until we get Nth result (or failure).
10455         * (N == G.getopt_count is reset to 0 whenever OPTIND is [un]set).
10456         */
10457        GETOPT_RESET();
10458        count = 0;
10459        n = string_array_len(argv);
10460        do {
10461                optarg = NULL;
10462                opterr = (count < G.getopt_count) ? 0 : my_opterr;
10463                c = getopt(n, argv, optstring);
10464                if (c < 0)
10465                        break;
10466                count++;
10467        } while (count <= G.getopt_count);
10468
10469        /* Set OPTIND. Prevent resetting of the magic counter! */
10470        set_local_var_from_halves("OPTIND", utoa(optind));
10471        G.getopt_count = count; /* "next time, give me N+1'th result" */
10472        GETOPT_RESET(); /* just in case */
10473
10474        /* Set OPTARG */
10475        /* Always set or unset, never left as-is, even on exit/error:
10476         * "If no option was found, or if the option that was found
10477         * does not have an option-argument, OPTARG shall be unset."
10478         */
10479        cp = optarg;
10480        if (c == '?') {
10481                /* If ":optstring" and unknown option is seen,
10482                 * it is stored to OPTARG.
10483                 */
10484                if (optstring[1] == ':') {
10485                        cbuf[0] = optopt;
10486                        cp = cbuf;
10487                }
10488        }
10489        if (cp)
10490                set_local_var_from_halves("OPTARG", cp);
10491        else
10492                unset_local_var("OPTARG");
10493
10494        /* Convert -1 to "?" */
10495        exitcode = EXIT_SUCCESS;
10496        if (c < 0) { /* -1: end of options */
10497                exitcode = EXIT_FAILURE;
10498                c = '?';
10499        }
10500
10501        /* Set VAR */
10502        cbuf[0] = c;
10503        set_local_var_from_halves(var, cbuf);
10504
10505        return exitcode;
10506}
10507#endif
10508
10509static int FAST_FUNC builtin_source(char **argv)
10510{
10511        char *arg_path, *filename;
10512        FILE *input;
10513        save_arg_t sv;
10514        char *args_need_save;
10515#if ENABLE_HUSH_FUNCTIONS
10516        smallint sv_flg;
10517#endif
10518
10519        argv = skip_dash_dash(argv);
10520        filename = argv[0];
10521        if (!filename) {
10522                /* bash says: "bash: .: filename argument required" */
10523                return 2; /* bash compat */
10524        }
10525        arg_path = NULL;
10526        if (!strchr(filename, '/')) {
10527                arg_path = find_in_path(filename);
10528                if (arg_path)
10529                        filename = arg_path;
10530                else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) {
10531                        errno = ENOENT;
10532                        bb_simple_perror_msg(filename);
10533                        return EXIT_FAILURE;
10534                }
10535        }
10536        input = remember_FILE(fopen_or_warn(filename, "r"));
10537        free(arg_path);
10538        if (!input) {
10539                /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
10540                /* POSIX: non-interactive shell should abort here,
10541                 * not merely fail. So far no one complained :)
10542                 */
10543                return EXIT_FAILURE;
10544        }
10545
10546#if ENABLE_HUSH_FUNCTIONS
10547        sv_flg = G_flag_return_in_progress;
10548        /* "we are inside sourced file, ok to use return" */
10549        G_flag_return_in_progress = -1;
10550#endif
10551        args_need_save = argv[1]; /* used as a boolean variable */
10552        if (args_need_save)
10553                save_and_replace_G_args(&sv, argv);
10554
10555        /* "false; . ./empty_line; echo Zero:$?" should print 0 */
10556        G.last_exitcode = 0;
10557        parse_and_run_file(input);
10558        fclose_and_forget(input);
10559
10560        if (args_need_save) /* can't use argv[1] instead: "shift" can mangle it */
10561                restore_G_args(&sv, argv);
10562#if ENABLE_HUSH_FUNCTIONS
10563        G_flag_return_in_progress = sv_flg;
10564#endif
10565
10566        return G.last_exitcode;
10567}
10568
10569#if ENABLE_HUSH_TRAP
10570static int FAST_FUNC builtin_trap(char **argv)
10571{
10572        int sig;
10573        char *new_cmd;
10574
10575        if (!G_traps)
10576                G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
10577
10578        argv++;
10579        if (!*argv) {
10580                int i;
10581                /* No args: print all trapped */
10582                for (i = 0; i < NSIG; ++i) {
10583                        if (G_traps[i]) {
10584                                printf("trap -- ");
10585                                print_escaped(G_traps[i]);
10586                                /* note: bash adds "SIG", but only if invoked
10587                                 * as "bash". If called as "sh", or if set -o posix,
10588                                 * then it prints short signal names.
10589                                 * We are printing short names: */
10590                                printf(" %s\n", get_signame(i));
10591                        }
10592                }
10593                /*fflush_all(); - done after each builtin anyway */
10594                return EXIT_SUCCESS;
10595        }
10596
10597        new_cmd = NULL;
10598        /* If first arg is a number: reset all specified signals */
10599        sig = bb_strtou(*argv, NULL, 10);
10600        if (errno == 0) {
10601                int ret;
10602 process_sig_list:
10603                ret = EXIT_SUCCESS;
10604                while (*argv) {
10605                        sighandler_t handler;
10606
10607                        sig = get_signum(*argv++);
10608                        if (sig < 0) {
10609                                ret = EXIT_FAILURE;
10610                                /* Mimic bash message exactly */
10611                                bb_error_msg("trap: %s: invalid signal specification", argv[-1]);
10612                                continue;
10613                        }
10614
10615                        free(G_traps[sig]);
10616                        G_traps[sig] = xstrdup(new_cmd);
10617
10618                        debug_printf("trap: setting SIG%s (%i) to '%s'\n",
10619                                get_signame(sig), sig, G_traps[sig]);
10620
10621                        /* There is no signal for 0 (EXIT) */
10622                        if (sig == 0)
10623                                continue;
10624
10625                        if (new_cmd)
10626                                handler = (new_cmd[0] ? record_pending_signo : SIG_IGN);
10627                        else
10628                                /* We are removing trap handler */
10629                                handler = pick_sighandler(sig);
10630                        install_sighandler(sig, handler);
10631                }
10632                return ret;
10633        }
10634
10635        if (!argv[1]) { /* no second arg */
10636                bb_error_msg("trap: invalid arguments");
10637                return EXIT_FAILURE;
10638        }
10639
10640        /* First arg is "-": reset all specified to default */
10641        /* First arg is "--": skip it, the rest is "handler SIGs..." */
10642        /* Everything else: set arg as signal handler
10643         * (includes "" case, which ignores signal) */
10644        if (argv[0][0] == '-') {
10645                if (argv[0][1] == '\0') { /* "-" */
10646                        /* new_cmd remains NULL: "reset these sigs" */
10647                        goto reset_traps;
10648                }
10649                if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */
10650                        argv++;
10651                }
10652                /* else: "-something", no special meaning */
10653        }
10654        new_cmd = *argv;
10655 reset_traps:
10656        argv++;
10657        goto process_sig_list;
10658}
10659#endif
10660
10661#if ENABLE_HUSH_JOB
10662static struct pipe *parse_jobspec(const char *str)
10663{
10664        struct pipe *pi;
10665        unsigned jobnum;
10666
10667        if (sscanf(str, "%%%u", &jobnum) != 1) {
10668                if (str[0] != '%'
10669                 || (str[1] != '%' && str[1] != '+' && str[1] != '\0')
10670                ) {
10671                        bb_error_msg("bad argument '%s'", str);
10672                        return NULL;
10673                }
10674                /* It is "%%", "%+" or "%" - current job */
10675                jobnum = G.last_jobid;
10676                if (jobnum == 0) {
10677                        bb_error_msg("no current job");
10678                        return NULL;
10679                }
10680        }
10681        for (pi = G.job_list; pi; pi = pi->next) {
10682                if (pi->jobid == jobnum) {
10683                        return pi;
10684                }
10685        }
10686        bb_error_msg("%u: no such job", jobnum);
10687        return NULL;
10688}
10689
10690static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM)
10691{
10692        struct pipe *job;
10693        const char *status_string;
10694
10695        checkjobs(NULL, 0 /*(no pid to wait for)*/);
10696        for (job = G.job_list; job; job = job->next) {
10697                if (job->alive_cmds == job->stopped_cmds)
10698                        status_string = "Stopped";
10699                else
10700                        status_string = "Running";
10701
10702                printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
10703        }
10704
10705        clean_up_last_dead_job();
10706
10707        return EXIT_SUCCESS;
10708}
10709
10710/* built-in 'fg' and 'bg' handler */
10711static int FAST_FUNC builtin_fg_bg(char **argv)
10712{
10713        int i;
10714        struct pipe *pi;
10715
10716        if (!G_interactive_fd)
10717                return EXIT_FAILURE;
10718
10719        /* If they gave us no args, assume they want the last backgrounded task */
10720        if (!argv[1]) {
10721                for (pi = G.job_list; pi; pi = pi->next) {
10722                        if (pi->jobid == G.last_jobid) {
10723                                goto found;
10724                        }
10725                }
10726                bb_error_msg("%s: no current job", argv[0]);
10727                return EXIT_FAILURE;
10728        }
10729
10730        pi = parse_jobspec(argv[1]);
10731        if (!pi)
10732                return EXIT_FAILURE;
10733 found:
10734        /* TODO: bash prints a string representation
10735         * of job being foregrounded (like "sleep 1 | cat") */
10736        if (argv[0][0] == 'f' && G_saved_tty_pgrp) {
10737                /* Put the job into the foreground.  */
10738                tcsetpgrp(G_interactive_fd, pi->pgrp);
10739        }
10740
10741        /* Restart the processes in the job */
10742        debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp);
10743        for (i = 0; i < pi->num_cmds; i++) {
10744                debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid);
10745        }
10746        pi->stopped_cmds = 0;
10747
10748        i = kill(- pi->pgrp, SIGCONT);
10749        if (i < 0) {
10750                if (errno == ESRCH) {
10751                        delete_finished_job(pi);
10752                        return EXIT_SUCCESS;
10753                }
10754                bb_perror_msg("kill (SIGCONT)");
10755        }
10756
10757        if (argv[0][0] == 'f') {
10758                remove_job_from_table(pi); /* FG job shouldn't be in job table */
10759                return checkjobs_and_fg_shell(pi);
10760        }
10761        return EXIT_SUCCESS;
10762}
10763#endif
10764
10765#if ENABLE_HUSH_KILL
10766static int FAST_FUNC builtin_kill(char **argv)
10767{
10768        int ret = 0;
10769
10770# if ENABLE_HUSH_JOB
10771        if (argv[1] && strcmp(argv[1], "-l") != 0) {
10772                int i = 1;
10773
10774                do {
10775                        struct pipe *pi;
10776                        char *dst;
10777                        int j, n;
10778
10779                        if (argv[i][0] != '%')
10780                                continue;
10781                        /*
10782                         * "kill %N" - job kill
10783                         * Converting to pgrp / pid kill
10784                         */
10785                        pi = parse_jobspec(argv[i]);
10786                        if (!pi) {
10787                                /* Eat bad jobspec */
10788                                j = i;
10789                                do {
10790                                        j++;
10791                                        argv[j - 1] = argv[j];
10792                                } while (argv[j]);
10793                                ret = 1;
10794                                i--;
10795                                continue;
10796                        }
10797                        /*
10798                         * In jobs started under job control, we signal
10799                         * entire process group by kill -PGRP_ID.
10800                         * This happens, f.e., in interactive shell.
10801                         *
10802                         * Otherwise, we signal each child via
10803                         * kill PID1 PID2 PID3.
10804                         * Testcases:
10805                         * sh -c 'sleep 1|sleep 1 & kill %1'
10806                         * sh -c 'true|sleep 2 & sleep 1; kill %1'
10807                         * sh -c 'true|sleep 1 & sleep 2; kill %1'
10808                         */
10809                        n = G_interactive_fd ? 1 : pi->num_cmds;
10810                        dst = alloca(n * sizeof(int)*4);
10811                        argv[i] = dst;
10812                        if (G_interactive_fd)
10813                                dst += sprintf(dst, " -%u", (int)pi->pgrp);
10814                        else for (j = 0; j < n; j++) {
10815                                struct command *cmd = &pi->cmds[j];
10816                                /* Skip exited members of the job */
10817                                if (cmd->pid == 0)
10818                                        continue;
10819                                /*
10820                                 * kill_main has matching code to expect
10821                                 * leading space. Needed to not confuse
10822                                 * negative pids with "kill -SIGNAL_NO" syntax
10823                                 */
10824                                dst += sprintf(dst, " %u", (int)cmd->pid);
10825                        }
10826                        *dst = '\0';
10827                } while (argv[++i]);
10828        }
10829# endif
10830
10831        if (argv[1] || ret == 0) {
10832                ret = run_applet_main(argv, kill_main);
10833        }
10834        /* else: ret = 1, "kill %bad_jobspec" case */
10835        return ret;
10836}
10837#endif
10838
10839#if ENABLE_HUSH_WAIT
10840/* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
10841#if !ENABLE_HUSH_JOB
10842# define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid)
10843#endif
10844static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid)
10845{
10846        int ret = 0;
10847        for (;;) {
10848                int sig;
10849                sigset_t oldset;
10850
10851                if (!sigisemptyset(&G.pending_set))
10852                        goto check_sig;
10853
10854                /* waitpid is not interruptible by SA_RESTARTed
10855                 * signals which we use. Thus, this ugly dance:
10856                 */
10857
10858                /* Make sure possible SIGCHLD is stored in kernel's
10859                 * pending signal mask before we call waitpid.
10860                 * Or else we may race with SIGCHLD, lose it,
10861                 * and get stuck in sigsuspend...
10862                 */
10863                sigfillset(&oldset); /* block all signals, remember old set */
10864                sigprocmask(SIG_SETMASK, &oldset, &oldset);
10865
10866                if (!sigisemptyset(&G.pending_set)) {
10867                        /* Crap! we raced with some signal! */
10868                        goto restore;
10869                }
10870
10871                /*errno = 0; - checkjobs does this */
10872/* Can't pass waitfor_pipe into checkjobs(): it won't be interruptible */
10873                ret = checkjobs(NULL, waitfor_pid); /* waitpid(WNOHANG) inside */
10874                debug_printf_exec("checkjobs:%d\n", ret);
10875#if ENABLE_HUSH_JOB
10876                if (waitfor_pipe) {
10877                        int rcode = job_exited_or_stopped(waitfor_pipe);
10878                        debug_printf_exec("job_exited_or_stopped:%d\n", rcode);
10879                        if (rcode >= 0) {
10880                                ret = rcode;
10881                                sigprocmask(SIG_SETMASK, &oldset, NULL);
10882                                break;
10883                        }
10884                }
10885#endif
10886                /* if ECHILD, there are no children (ret is -1 or 0) */
10887                /* if ret == 0, no children changed state */
10888                /* if ret != 0, it's exitcode+1 of exited waitfor_pid child */
10889                if (errno == ECHILD || ret) {
10890                        ret--;
10891                        if (ret < 0) /* if ECHILD, may need to fix "ret" */
10892                                ret = 0;
10893                        sigprocmask(SIG_SETMASK, &oldset, NULL);
10894                        break;
10895                }
10896                /* Wait for SIGCHLD or any other signal */
10897                /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */
10898                /* Note: sigsuspend invokes signal handler */
10899                sigsuspend(&oldset);
10900 restore:
10901                sigprocmask(SIG_SETMASK, &oldset, NULL);
10902 check_sig:
10903                /* So, did we get a signal? */
10904                sig = check_and_run_traps();
10905                if (sig /*&& sig != SIGCHLD - always true */) {
10906                        /* Do this for any (non-ignored) signal, not only for ^C */
10907                        ret = 128 + sig;
10908                        break;
10909                }
10910                /* SIGCHLD, or no signal, or ignored one, such as SIGQUIT. Repeat */
10911        }
10912        return ret;
10913}
10914
10915static int FAST_FUNC builtin_wait(char **argv)
10916{
10917        int ret;
10918        int status;
10919
10920        argv = skip_dash_dash(argv);
10921        if (argv[0] == NULL) {
10922                /* Don't care about wait results */
10923                /* Note 1: must wait until there are no more children */
10924                /* Note 2: must be interruptible */
10925                /* Examples:
10926                 * $ sleep 3 & sleep 6 & wait
10927                 * [1] 30934 sleep 3
10928                 * [2] 30935 sleep 6
10929                 * [1] Done                   sleep 3
10930                 * [2] Done                   sleep 6
10931                 * $ sleep 3 & sleep 6 & wait
10932                 * [1] 30936 sleep 3
10933                 * [2] 30937 sleep 6
10934                 * [1] Done                   sleep 3
10935                 * ^C <-- after ~4 sec from keyboard
10936                 * $
10937                 */
10938                return wait_for_child_or_signal(NULL, 0 /*(no job and no pid to wait for)*/);
10939        }
10940
10941        do {
10942                pid_t pid = bb_strtou(*argv, NULL, 10);
10943                if (errno || pid <= 0) {
10944#if ENABLE_HUSH_JOB
10945                        if (argv[0][0] == '%') {
10946                                struct pipe *wait_pipe;
10947                                ret = 127; /* bash compat for bad jobspecs */
10948                                wait_pipe = parse_jobspec(*argv);
10949                                if (wait_pipe) {
10950                                        ret = job_exited_or_stopped(wait_pipe);
10951                                        if (ret < 0) {
10952                                                ret = wait_for_child_or_signal(wait_pipe, 0);
10953                                        } else {
10954                                                /* waiting on "last dead job" removes it */
10955                                                clean_up_last_dead_job();
10956                                        }
10957                                }
10958                                /* else: parse_jobspec() already emitted error msg */
10959                                continue;
10960                        }
10961#endif
10962                        /* mimic bash message */
10963                        bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
10964                        ret = EXIT_FAILURE;
10965                        continue; /* bash checks all argv[] */
10966                }
10967
10968                /* Do we have such child? */
10969                ret = waitpid(pid, &status, WNOHANG);
10970                if (ret < 0) {
10971                        /* No */
10972                        ret = 127;
10973                        if (errno == ECHILD) {
10974                                if (pid == G.last_bg_pid) {
10975                                        /* "wait $!" but last bg task has already exited. Try:
10976                                         * (sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?
10977                                         * In bash it prints exitcode 0, then 3.
10978                                         * In dash, it is 127.
10979                                         */
10980                                        ret = G.last_bg_pid_exitcode;
10981                                } else {
10982                                        /* Example: "wait 1". mimic bash message */
10983                                        bb_error_msg("wait: pid %d is not a child of this shell", (int)pid);
10984                                }
10985                        } else {
10986                                /* ??? */
10987                                bb_perror_msg("wait %s", *argv);
10988                        }
10989                        continue; /* bash checks all argv[] */
10990                }
10991                if (ret == 0) {
10992                        /* Yes, and it still runs */
10993                        ret = wait_for_child_or_signal(NULL, pid);
10994                } else {
10995                        /* Yes, and it just exited */
10996                        process_wait_result(NULL, pid, status);
10997                        ret = WEXITSTATUS(status);
10998                        if (WIFSIGNALED(status))
10999                                ret = 128 + WTERMSIG(status);
11000                }
11001        } while (*++argv);
11002
11003        return ret;
11004}
11005#endif
11006
11007#if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS
11008static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min)
11009{
11010        if (argv[1]) {
11011                def = bb_strtou(argv[1], NULL, 10);
11012                if (errno || def < def_min || argv[2]) {
11013                        bb_error_msg("%s: bad arguments", argv[0]);
11014                        def = UINT_MAX;
11015                }
11016        }
11017        return def;
11018}
11019#endif
11020
11021#if ENABLE_HUSH_LOOPS
11022static int FAST_FUNC builtin_break(char **argv)
11023{
11024        unsigned depth;
11025        if (G.depth_of_loop == 0) {
11026                bb_error_msg("%s: only meaningful in a loop", argv[0]);
11027                /* if we came from builtin_continue(), need to undo "= 1" */
11028                G.flag_break_continue = 0;
11029                return EXIT_SUCCESS; /* bash compat */
11030        }
11031        G.flag_break_continue++; /* BC_BREAK = 1, or BC_CONTINUE = 2 */
11032
11033        G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1);
11034        if (depth == UINT_MAX)
11035                G.flag_break_continue = BC_BREAK;
11036        if (G.depth_of_loop < depth)
11037                G.depth_break_continue = G.depth_of_loop;
11038
11039        return EXIT_SUCCESS;
11040}
11041
11042static int FAST_FUNC builtin_continue(char **argv)
11043{
11044        G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */
11045        return builtin_break(argv);
11046}
11047#endif
11048
11049#if ENABLE_HUSH_FUNCTIONS
11050static int FAST_FUNC builtin_return(char **argv)
11051{
11052        int rc;
11053
11054        if (G_flag_return_in_progress != -1) {
11055                bb_error_msg("%s: not in a function or sourced script", argv[0]);
11056                return EXIT_FAILURE; /* bash compat */
11057        }
11058
11059        G_flag_return_in_progress = 1;
11060
11061        /* bash:
11062         * out of range: wraps around at 256, does not error out
11063         * non-numeric param:
11064         * f() { false; return qwe; }; f; echo $?
11065         * bash: return: qwe: numeric argument required  <== we do this
11066         * 255  <== we also do this
11067         */
11068        rc = parse_numeric_argv1(argv, G.last_exitcode, 0);
11069        return rc;
11070}
11071#endif
11072
11073#if ENABLE_HUSH_TIMES
11074static int FAST_FUNC builtin_times(char **argv UNUSED_PARAM)
11075{
11076        static const uint8_t times_tbl[] ALIGN1 = {
11077                ' ',  offsetof(struct tms, tms_utime),
11078                '\n', offsetof(struct tms, tms_stime),
11079                ' ',  offsetof(struct tms, tms_cutime),
11080                '\n', offsetof(struct tms, tms_cstime),
11081                0
11082        };
11083        const uint8_t *p;
11084        unsigned clk_tck;
11085        struct tms buf;
11086
11087        clk_tck = bb_clk_tck();
11088
11089        times(&buf);
11090        p = times_tbl;
11091        do {
11092                unsigned sec, frac;
11093                unsigned long t;
11094                t = *(clock_t *)(((char *) &buf) + p[1]);
11095                sec = t / clk_tck;
11096                frac = t % clk_tck;
11097                printf("%um%u.%03us%c",
11098                        sec / 60, sec % 60,
11099                        (frac * 1000) / clk_tck,
11100                        p[0]);
11101                p += 2;
11102        } while (*p);
11103
11104        return EXIT_SUCCESS;
11105}
11106#endif
11107
11108#if ENABLE_HUSH_MEMLEAK
11109static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM)
11110{
11111        void *p;
11112        unsigned long l;
11113
11114# ifdef M_TRIM_THRESHOLD
11115        /* Optional. Reduces probability of false positives */
11116        malloc_trim(0);
11117# endif
11118        /* Crude attempt to find where "free memory" starts,
11119         * sans fragmentation. */
11120        p = malloc(240);
11121        l = (unsigned long)p;
11122        free(p);
11123        p = malloc(3400);
11124        if (l < (unsigned long)p) l = (unsigned long)p;
11125        free(p);
11126
11127
11128# if 0  /* debug */
11129        {
11130                struct mallinfo mi = mallinfo();
11131                printf("top alloc:0x%lx malloced:%d+%d=%d\n", l,
11132                        mi.arena, mi.hblkhd, mi.arena + mi.hblkhd);
11133        }
11134# endif
11135
11136        if (!G.memleak_value)
11137                G.memleak_value = l;
11138
11139        l -= G.memleak_value;
11140        if ((long)l < 0)
11141                l = 0;
11142        l /= 1024;
11143        if (l > 127)
11144                l = 127;
11145
11146        /* Exitcode is "how many kilobytes we leaked since 1st call" */
11147        return l;
11148}
11149#endif
11150