busybox/shell/ash.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * ash shell port for busybox
   4 *
   5 * This code is derived from software contributed to Berkeley by
   6 * Kenneth Almquist.
   7 *
   8 * Original BSD copyright notice is retained at the end of this file.
   9 *
  10 * Copyright (c) 1989, 1991, 1993, 1994
  11 *      The Regents of the University of California.  All rights reserved.
  12 *
  13 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
  14 * was re-ported from NetBSD and debianized.
  15 *
  16 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  17 */
  18//config:config ASH
  19//config:       bool "ash (78 kb)"
  20//config:       default y
  21//config:       depends on !NOMMU
  22//config:       help
  23//config:       The most complete and most pedantically correct shell included with
  24//config:       busybox. This shell is actually a derivative of the Debian 'dash'
  25//config:       shell (by Herbert Xu), which was created by porting the 'ash' shell
  26//config:       (written by Kenneth Almquist) from NetBSD.
  27//config:
  28//config:# ash options
  29//config:# note: Don't remove !NOMMU part in the next line; it would break
  30//config:# menuconfig's indenting.
  31//config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH)
  32//config:
  33//config:config ASH_OPTIMIZE_FOR_SIZE
  34//config:       bool "Optimize for size instead of speed"
  35//config:       default y
  36//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
  37//config:
  38//config:config ASH_INTERNAL_GLOB
  39//config:       bool "Use internal glob() implementation"
  40//config:       default y       # Y is bigger, but because of uclibc glob() bug, let Y be default for now
  41//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
  42//config:       help
  43//config:       Do not use glob() function from libc, use internal implementation.
  44//config:       Use this if you are getting "glob.h: No such file or directory"
  45//config:       or similar build errors.
  46//config:       Note that as of now (2017-01), uclibc and musl glob() both have bugs
  47//config:       which would break ash if you select N here.
  48//config:
  49//config:config ASH_BASH_COMPAT
  50//config:       bool "bash-compatible extensions"
  51//config:       default y
  52//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
  53//config:
  54//config:config ASH_BASH_SOURCE_CURDIR
  55//config:       bool "'source' and '.' builtins search current directory after $PATH"
  56//config:       default n   # do not encourage non-standard behavior
  57//config:       depends on ASH_BASH_COMPAT
  58//config:       help
  59//config:       This is not compliant with standards. Avoid if possible.
  60//config:
  61//config:config ASH_BASH_NOT_FOUND_HOOK
  62//config:       bool "command_not_found_handle hook support"
  63//config:       default y
  64//config:       depends on ASH_BASH_COMPAT
  65//config:       help
  66//config:       Enable support for the 'command_not_found_handle' hook function,
  67//config:       from GNU bash, which allows for alternative command not found
  68//config:       handling.
  69//config:
  70//config:config ASH_JOB_CONTROL
  71//config:       bool "Job control"
  72//config:       default y
  73//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
  74//config:
  75//config:config ASH_ALIAS
  76//config:       bool "Alias support"
  77//config:       default y
  78//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
  79//config:
  80//config:config ASH_RANDOM_SUPPORT
  81//config:       bool "Pseudorandom generator and $RANDOM variable"
  82//config:       default y
  83//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
  84//config:       help
  85//config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
  86//config:       Each read of "$RANDOM" will generate a new pseudorandom value.
  87//config:       You can reset the generator by using a specified start value.
  88//config:       After "unset RANDOM" the generator will switch off and this
  89//config:       variable will no longer have special treatment.
  90//config:
  91//config:config ASH_EXPAND_PRMT
  92//config:       bool "Expand prompt string"
  93//config:       default y
  94//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
  95//config:       help
  96//config:       $PS# may contain volatile content, such as backquote commands.
  97//config:       This option recreates the prompt string from the environment
  98//config:       variable each time it is displayed.
  99//config:
 100//config:config ASH_IDLE_TIMEOUT
 101//config:       bool "Idle timeout variable $TMOUT"
 102//config:       default y
 103//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 104//config:       help
 105//config:       Enable bash-like auto-logout after $TMOUT seconds of idle time.
 106//config:
 107//config:config ASH_MAIL
 108//config:       bool "Check for new mail in interactive shell"
 109//config:       default y
 110//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 111//config:       help
 112//config:       Enable "check for new mail" function:
 113//config:       if set, $MAIL file and $MAILPATH list of files
 114//config:       are checked for mtime changes, and "you have mail"
 115//config:       message is printed if change is detected.
 116//config:
 117//config:config ASH_ECHO
 118//config:       bool "echo builtin"
 119//config:       default y
 120//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 121//config:
 122//config:config ASH_PRINTF
 123//config:       bool "printf builtin"
 124//config:       default y
 125//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 126//config:
 127//config:config ASH_TEST
 128//config:       bool "test builtin"
 129//config:       default y
 130//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 131//config:
 132//config:config ASH_HELP
 133//config:       bool "help builtin"
 134//config:       default y
 135//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 136//config:
 137//config:config ASH_GETOPTS
 138//config:       bool "getopts builtin"
 139//config:       default y
 140//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 141//config:
 142//config:config ASH_CMDCMD
 143//config:       bool "command builtin"
 144//config:       default y
 145//config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
 146//config:       help
 147//config:       Enable support for the 'command' builtin, which allows
 148//config:       you to run the specified command or builtin,
 149//config:       even when there is a function with the same name.
 150//config:
 151//config:endif # ash options
 152
 153//applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
 154//                      APPLET_ODDNAME:name  main location    suid_type     help
 155//applet:IF_SH_IS_ASH(  APPLET_ODDNAME(sh,   ash, BB_DIR_BIN, BB_SUID_DROP, ash))
 156//applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
 157
 158//kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
 159//kbuild:lib-$(CONFIG_SH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
 160//kbuild:lib-$(CONFIG_BASH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
 161//kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
 162
 163/*
 164 * DEBUG=1 to compile in debugging ('set -o debug' turns on)
 165 * DEBUG=2 to compile in and turn on debugging.
 166 * When debugging is on ("set -o debug" was executed, or DEBUG=2),
 167 * debugging info is written to ./trace, quit signal generates core dump.
 168 */
 169#define DEBUG 0
 170/* Tweak debug output verbosity here */
 171#define DEBUG_TIME 0
 172#define DEBUG_PID 1
 173#define DEBUG_SIG 1
 174#define DEBUG_INTONOFF 0
 175
 176#define PROFILE 0
 177
 178#define JOBS ENABLE_ASH_JOB_CONTROL
 179
 180#include <fnmatch.h>
 181#include <sys/times.h>
 182#include <sys/utsname.h> /* for setting $HOSTNAME */
 183#include "busybox.h" /* for applet_names */
 184#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
 185# include "embedded_scripts.h"
 186#else
 187# define NUM_SCRIPTS 0
 188#endif
 189
 190/* So far, all bash compat is controlled by one config option */
 191/* Separate defines document which part of code implements what */
 192/* function keyword */
 193#define    BASH_FUNCTION        ENABLE_ASH_BASH_COMPAT
 194#define IF_BASH_FUNCTION            IF_ASH_BASH_COMPAT
 195/* &>file */
 196#define    BASH_REDIR_OUTPUT    ENABLE_ASH_BASH_COMPAT
 197#define IF_BASH_REDIR_OUTPUT        IF_ASH_BASH_COMPAT
 198/* $'...' */
 199#define    BASH_DOLLAR_SQUOTE   ENABLE_ASH_BASH_COMPAT
 200#define IF_BASH_DOLLAR_SQUOTE       IF_ASH_BASH_COMPAT
 201#define    BASH_PATTERN_SUBST   ENABLE_ASH_BASH_COMPAT
 202#define IF_BASH_PATTERN_SUBST       IF_ASH_BASH_COMPAT
 203#define    BASH_SUBSTR          ENABLE_ASH_BASH_COMPAT
 204#define IF_BASH_SUBSTR              IF_ASH_BASH_COMPAT
 205/* BASH_TEST2: [[ EXPR ]]
 206 * Status of [[ support:
 207 * We replace && and || with -a and -o
 208 * TODO:
 209 * singleword+noglob expansion:
 210 *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
 211 *   [[ /bin/n* ]]; echo 0:$?
 212 * -a/-o are not AND/OR ops! (they are just strings)
 213 * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
 214 * = is glob match operator, not equality operator: STR = GLOB
 215 * (in GLOB, quoting is significant on char-by-char basis: a*cd"*")
 216 * == same as =
 217 * add =~ regex match operator: STR =~ REGEX
 218 */
 219#define    BASH_TEST2           (ENABLE_ASH_BASH_COMPAT * ENABLE_ASH_TEST)
 220#define    BASH_SOURCE          ENABLE_ASH_BASH_COMPAT
 221#define    BASH_PIPEFAIL        ENABLE_ASH_BASH_COMPAT
 222#define    BASH_HOSTNAME_VAR    ENABLE_ASH_BASH_COMPAT
 223#define    BASH_EPOCH_VARS      ENABLE_ASH_BASH_COMPAT
 224#define    BASH_SHLVL_VAR       ENABLE_ASH_BASH_COMPAT
 225#define    BASH_XTRACEFD        ENABLE_ASH_BASH_COMPAT
 226#define    BASH_READ_D          ENABLE_ASH_BASH_COMPAT
 227#define IF_BASH_READ_D              IF_ASH_BASH_COMPAT
 228#define    BASH_WAIT_N          ENABLE_ASH_BASH_COMPAT
 229
 230#if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
 231/* Bionic at least up to version 24 has no glob() */
 232# undef  ENABLE_ASH_INTERNAL_GLOB
 233# define ENABLE_ASH_INTERNAL_GLOB 1
 234#endif
 235
 236#if !ENABLE_ASH_INTERNAL_GLOB && defined(__UCLIBC__)
 237# error uClibc glob() is buggy, use ASH_INTERNAL_GLOB.
 238# error The bug is: for "$PWD"/<pattern> ash will escape e.g. dashes in "$PWD"
 239# error with backslash, even ones which do not need to be: "/a-b" -> "/a\-b"
 240# error glob() should unbackslash them and match. uClibc does not unbackslash,
 241# error fails to match dirname, subsequently not expanding <pattern> in it.
 242// Testcase:
 243// if (glob("/etc/polkit\\-1", 0, NULL, &pglob)) - this returns 0 on uclibc, no bug
 244// if (glob("/etc/polkit\\-1/*", 0, NULL, &pglob)) printf("uclibc bug!\n");
 245#endif
 246
 247#if !ENABLE_ASH_INTERNAL_GLOB
 248# include <glob.h>
 249#endif
 250
 251#include "unicode.h"
 252#include "shell_common.h"
 253#if ENABLE_FEATURE_SH_MATH
 254# include "math.h"
 255#else
 256typedef long arith_t;
 257# define ARITH_FMT "%ld"
 258#endif
 259#if ENABLE_ASH_RANDOM_SUPPORT
 260# include "random.h"
 261#else
 262# define CLEAR_RANDOM_T(rnd) ((void)0)
 263#endif
 264
 265#include "NUM_APPLETS.h"
 266#if NUM_APPLETS == 1
 267/* STANDALONE does not make sense, and won't compile */
 268# undef CONFIG_FEATURE_SH_STANDALONE
 269# undef ENABLE_FEATURE_SH_STANDALONE
 270# undef IF_FEATURE_SH_STANDALONE
 271# undef IF_NOT_FEATURE_SH_STANDALONE
 272# define ENABLE_FEATURE_SH_STANDALONE 0
 273# define IF_FEATURE_SH_STANDALONE(...)
 274# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
 275#endif
 276
 277#ifndef F_DUPFD_CLOEXEC
 278# define F_DUPFD_CLOEXEC F_DUPFD
 279#endif
 280#ifndef O_CLOEXEC
 281# define O_CLOEXEC 0
 282#endif
 283#ifndef PIPE_BUF
 284# define PIPE_BUF 4096           /* amount of buffering in a pipe */
 285#endif
 286
 287#if !BB_MMU
 288# error "Do not even bother, ash will not run on NOMMU machine"
 289#endif
 290
 291/* We use a trick to have more optimized code (fewer pointer reloads):
 292 *  ash.c:   extern struct globals *const ash_ptr_to_globals;
 293 *  ash_ptr_hack.c: struct globals *ash_ptr_to_globals;
 294 * This way, compiler in ash.c knows the pointer can not change.
 295 *
 296 * However, this may break on weird arches or toolchains. In this case,
 297 * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable
 298 * this optimization.
 299 */
 300#ifndef BB_GLOBAL_CONST
 301# define BB_GLOBAL_CONST const
 302#endif
 303
 304
 305/* ============ Hash table sizes. Configurable. */
 306
 307#define VTABSIZE 39
 308#define ATABSIZE 39
 309#define CMDTABLESIZE 31         /* should be prime */
 310
 311
 312/* ============ Shell options */
 313
 314static const char *const optletters_optnames[] = {
 315        "e"   "errexit",
 316        "f"   "noglob",
 317        "I"   "ignoreeof",
 318/* The below allowed this invocation:
 319 * ash -c 'set -i; echo $-; sleep 5; echo $-'
 320 * to be ^C-ed and get to interactive ash prompt.
 321 * bash does not support such "set -i".
 322 * In our code, this is denoted by empty long name:
 323 */
 324        "i"   "",
 325        "m"   "monitor",
 326        "n"   "noexec",
 327/* Ditto: bash has no "set -s" */
 328        "s"   "",
 329        "c"   "",
 330        "x"   "xtrace",
 331        "v"   "verbose",
 332        "C"   "noclobber",
 333        "a"   "allexport",
 334        "b"   "notify",
 335        "u"   "nounset",
 336        "\0"  "vi"
 337#if BASH_PIPEFAIL
 338        ,"\0"  "pipefail"
 339#endif
 340#if DEBUG
 341        ,"\0"  "nolog"
 342        ,"\0"  "debug"
 343#endif
 344};
 345//bash 4.4.23 also has these opts (with these defaults):
 346//braceexpand           on
 347//emacs                 on
 348//errtrace              off
 349//functrace             off
 350//hashall               on
 351//histexpand            off
 352//history               on
 353//interactive-comments  on
 354//keyword               off
 355//onecmd                off
 356//physical              off
 357//posix                 off
 358//privileged            off
 359
 360#define optletters(n)  optletters_optnames[n][0]
 361#define optnames(n)   (optletters_optnames[n] + 1)
 362
 363enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
 364
 365
 366/* ============ Misc data */
 367
 368#define msg_illnum "Illegal number: %s"
 369
 370/*
 371 * We enclose jmp_buf in a structure so that we can declare pointers to
 372 * jump locations.  The global variable handler contains the location to
 373 * jump to when an exception occurs, and the global variable exception_type
 374 * contains a code identifying the exception.  To implement nested
 375 * exception handlers, the user should save the value of handler on entry
 376 * to an inner scope, set handler to point to a jmploc structure for the
 377 * inner scope, and restore handler on exit from the scope.
 378 */
 379struct jmploc {
 380        jmp_buf loc;
 381};
 382
 383struct globals_misc {
 384        uint8_t exitstatus;     /* exit status of last command */
 385        uint8_t back_exitstatus;/* exit status of backquoted command */
 386        smallint job_warning;   /* user was warned about stopped jobs (can be 2, 1 or 0). */
 387        int rootpid;            /* pid of main shell */
 388        /* shell level: 0 for the main shell, 1 for its children, and so on */
 389        int shlvl;
 390#define rootshell (!shlvl)
 391        int errlinno;
 392
 393        char *minusc;  /* argument to -c option */
 394
 395        char *curdir; // = nullstr;     /* current working directory */
 396        char *physdir; // = nullstr;    /* physical working directory */
 397
 398        char *arg0; /* value of $0 */
 399
 400        struct jmploc *exception_handler;
 401
 402        volatile int suppress_int; /* counter */
 403        volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
 404        volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */
 405        volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */
 406        smallint exception_type; /* kind of exception (0..5) */
 407        /* exceptions */
 408#define EXINT 0         /* SIGINT received */
 409#define EXERROR 1       /* a generic error */
 410#define EXEXIT 4        /* exit the shell */
 411
 412        char nullstr[1];        /* zero length string */
 413
 414        char optlist[NOPTS];
 415#define eflag optlist[0]
 416#define fflag optlist[1]
 417#define Iflag optlist[2]
 418#define iflag optlist[3]
 419#define mflag optlist[4]
 420#define nflag optlist[5]
 421#define sflag optlist[6]
 422#define cflag optlist[7]
 423#define xflag optlist[8]
 424#define vflag optlist[9]
 425#define Cflag optlist[10]
 426#define aflag optlist[11]
 427#define bflag optlist[12]
 428#define uflag optlist[13]
 429#define viflag optlist[14]
 430#if BASH_PIPEFAIL
 431# define pipefail optlist[15]
 432#else
 433# define pipefail 0
 434#endif
 435#if DEBUG
 436# define nolog optlist[15 + BASH_PIPEFAIL]
 437# define debug optlist[16 + BASH_PIPEFAIL]
 438#endif
 439
 440        /* trap handler commands */
 441        /*
 442         * Sigmode records the current value of the signal handlers for the various
 443         * modes.  A value of zero means that the current handler is not known.
 444         * S_HARD_IGN indicates that the signal was ignored on entry to the shell.
 445         */
 446        char sigmode[NSIG - 1];
 447#define S_DFL      1            /* default signal handling (SIG_DFL) */
 448#define S_CATCH    2            /* signal is caught */
 449#define S_IGN      3            /* signal is ignored (SIG_IGN) */
 450#define S_HARD_IGN 4            /* signal is ignored permanently (it was SIG_IGN on entry to shell) */
 451
 452        /* indicates specified signal received */
 453        uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
 454        uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */
 455        char *trap[NSIG];
 456        char **trap_ptr;        /* used only by "trap hack" */
 457
 458        /* Rarely referenced stuff */
 459#if ENABLE_ASH_RANDOM_SUPPORT
 460        random_t random_gen;
 461#endif
 462        pid_t backgndpid;        /* pid of last background process */
 463};
 464extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
 465#define G_misc (*ash_ptr_to_globals_misc)
 466#define exitstatus        (G_misc.exitstatus )
 467#define back_exitstatus   (G_misc.back_exitstatus )
 468#define job_warning       (G_misc.job_warning)
 469#define rootpid     (G_misc.rootpid    )
 470#define shlvl       (G_misc.shlvl      )
 471#define errlinno    (G_misc.errlinno   )
 472#define minusc      (G_misc.minusc     )
 473#define curdir      (G_misc.curdir     )
 474#define physdir     (G_misc.physdir    )
 475#define arg0        (G_misc.arg0       )
 476#define exception_handler (G_misc.exception_handler)
 477#define exception_type    (G_misc.exception_type   )
 478#define suppress_int      (G_misc.suppress_int     )
 479#define pending_int       (G_misc.pending_int      )
 480#define got_sigchld       (G_misc.got_sigchld      )
 481#define pending_sig       (G_misc.pending_sig      )
 482#define nullstr     (G_misc.nullstr    )
 483#define optlist     (G_misc.optlist    )
 484#define sigmode     (G_misc.sigmode    )
 485#define gotsig      (G_misc.gotsig     )
 486#define may_have_traps    (G_misc.may_have_traps   )
 487#define trap        (G_misc.trap       )
 488#define trap_ptr    (G_misc.trap_ptr   )
 489#define random_gen  (G_misc.random_gen )
 490#define backgndpid  (G_misc.backgndpid )
 491#define INIT_G_misc() do { \
 492        (*(struct globals_misc**)&ash_ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \
 493        barrier(); \
 494        curdir = nullstr; \
 495        physdir = nullstr; \
 496        trap_ptr = trap; \
 497} while (0)
 498
 499
 500/* ============ DEBUG */
 501#if DEBUG
 502static void trace_printf(const char *fmt, ...);
 503static void trace_vprintf(const char *fmt, va_list va);
 504# define TRACE(param)    trace_printf param
 505# define TRACEV(param)   trace_vprintf param
 506# define close(fd) do { \
 507        int dfd = (fd); \
 508        if (close(dfd) < 0) \
 509                bb_error_msg("bug on %d: closing %d(0x%x)", \
 510                        __LINE__, dfd, dfd); \
 511} while (0)
 512#else
 513# define TRACE(param)
 514# define TRACEV(param)
 515#endif
 516
 517
 518/* ============ Utility functions */
 519#define is_name(c)      ((c) == '_' || isalpha((unsigned char)(c)))
 520#define is_in_name(c)   ((c) == '_' || isalnum((unsigned char)(c)))
 521
 522static int
 523isdigit_str9(const char *str)
 524{
 525        int maxlen = 9 + 1; /* max 9 digits: 999999999 */
 526        while (--maxlen && isdigit(*str))
 527                str++;
 528        return (*str == '\0');
 529}
 530
 531static const char *
 532var_end(const char *var)
 533{
 534        while (*var)
 535                if (*var++ == '=')
 536                        break;
 537        return var;
 538}
 539
 540
 541/* ============ Interrupts / exceptions */
 542
 543static void exitshell(void) NORETURN;
 544
 545/*
 546 * These macros allow the user to suspend the handling of interrupt signals
 547 * over a period of time.  This is similar to SIGHOLD or to sigblock, but
 548 * much more efficient and portable.  (But hacking the kernel is so much
 549 * more fun than worrying about efficiency and portability. :-))
 550 */
 551#if DEBUG_INTONOFF
 552# define INT_OFF do { \
 553        TRACE(("%s:%d INT_OFF(%d)\n", __func__, __LINE__, suppress_int)); \
 554        suppress_int++; \
 555        barrier(); \
 556} while (0)
 557#else
 558# define INT_OFF do { \
 559        suppress_int++; \
 560        barrier(); \
 561} while (0)
 562#endif
 563
 564/*
 565 * Called to raise an exception.  Since C doesn't include exceptions, we
 566 * just do a longjmp to the exception handler.  The type of exception is
 567 * stored in the global variable "exception_type".
 568 */
 569static void raise_exception(int) NORETURN;
 570static void
 571raise_exception(int e)
 572{
 573#if DEBUG
 574        if (exception_handler == NULL)
 575                abort();
 576#endif
 577        INT_OFF;
 578        exception_type = e;
 579        longjmp(exception_handler->loc, 1);
 580}
 581#if DEBUG
 582#define raise_exception(e) do { \
 583        TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
 584        raise_exception(e); \
 585} while (0)
 586#endif
 587
 588/*
 589 * Called when a SIGINT is received.  (If the user specifies
 590 * that SIGINT is to be trapped or ignored using the trap builtin, then
 591 * this routine is not called.)  Suppressint is nonzero when interrupts
 592 * are held using the INT_OFF macro.  (The test for iflag is just
 593 * defensive programming.)
 594 */
 595static void raise_interrupt(void) NORETURN;
 596static void
 597raise_interrupt(void)
 598{
 599        pending_int = 0;
 600        /* Signal is not automatically unmasked after it is raised,
 601         * do it ourself - unmask all signals */
 602        sigprocmask_allsigs(SIG_UNBLOCK);
 603        /* pending_sig = 0; - now done in signal_handler() */
 604
 605        if (!(rootshell && iflag)) {
 606                /* Kill ourself with SIGINT */
 607                signal(SIGINT, SIG_DFL);
 608                raise(SIGINT);
 609        }
 610        /* bash: ^C even on empty command line sets $? */
 611        exitstatus = SIGINT + 128;
 612        raise_exception(EXINT);
 613        /* NOTREACHED */
 614}
 615#if DEBUG
 616#define raise_interrupt() do { \
 617        TRACE(("raising interrupt on line %d\n", __LINE__)); \
 618        raise_interrupt(); \
 619} while (0)
 620#endif
 621
 622static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
 623int_on(void)
 624{
 625        barrier();
 626        if (--suppress_int == 0 && pending_int) {
 627                raise_interrupt();
 628        }
 629}
 630#if DEBUG_INTONOFF
 631# define INT_ON do { \
 632        TRACE(("%s:%d INT_ON(%d)\n", __func__, __LINE__, suppress_int-1)); \
 633        int_on(); \
 634} while (0)
 635#else
 636# define INT_ON int_on()
 637#endif
 638static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
 639force_int_on(void)
 640{
 641        barrier();
 642        suppress_int = 0;
 643        if (pending_int)
 644                raise_interrupt();
 645}
 646#define FORCE_INT_ON force_int_on()
 647
 648#define SAVE_INT(v) ((v) = suppress_int)
 649
 650#define RESTORE_INT(v) do { \
 651        barrier(); \
 652        suppress_int = (v); \
 653        if (suppress_int == 0 && pending_int) \
 654                raise_interrupt(); \
 655} while (0)
 656
 657
 658/* ============ Stdout/stderr output */
 659
 660static void
 661outstr(const char *p, FILE *file)
 662{
 663        INT_OFF;
 664        fputs(p, file);
 665        INT_ON;
 666}
 667
 668static void
 669flush_stdout_stderr(void)
 670{
 671        INT_OFF;
 672        fflush_all();
 673        INT_ON;
 674}
 675
 676/* Was called outcslow(c,FILE*), but c was always '\n' */
 677static void
 678newline_and_flush(FILE *dest)
 679{
 680        INT_OFF;
 681        putc('\n', dest);
 682        fflush(dest);
 683        INT_ON;
 684}
 685
 686static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
 687static int
 688out1fmt(const char *fmt, ...)
 689{
 690        va_list ap;
 691        int r;
 692
 693        INT_OFF;
 694        va_start(ap, fmt);
 695        r = vprintf(fmt, ap);
 696        va_end(ap);
 697        INT_ON;
 698        return r;
 699}
 700
 701static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
 702static int
 703fmtstr(char *outbuf, size_t length, const char *fmt, ...)
 704{
 705        va_list ap;
 706        int ret;
 707
 708        INT_OFF;
 709        va_start(ap, fmt);
 710        ret = vsnprintf(outbuf, length, fmt, ap);
 711        va_end(ap);
 712        INT_ON;
 713        return ret;
 714}
 715
 716static void
 717out1str(const char *p)
 718{
 719        outstr(p, stdout);
 720}
 721
 722static void
 723out2str(const char *p)
 724{
 725        outstr(p, stderr);
 726        flush_stdout_stderr();
 727}
 728
 729
 730/* ============ Parser structures */
 731
 732/* control characters in argument strings */
 733#define CTL_FIRST CTLESC
 734#define CTLESC       ((unsigned char)'\201')    /* escape next character */
 735#define CTLVAR       ((unsigned char)'\202')    /* variable defn */
 736#define CTLENDVAR    ((unsigned char)'\203')
 737#define CTLBACKQ     ((unsigned char)'\204')
 738#define CTLARI       ((unsigned char)'\206')    /* arithmetic expression */
 739#define CTLENDARI    ((unsigned char)'\207')
 740#define CTLQUOTEMARK ((unsigned char)'\210')
 741#define CTL_LAST CTLQUOTEMARK
 742
 743/* variable substitution byte (follows CTLVAR) */
 744#define VSTYPE  0x0f            /* type of variable substitution */
 745#define VSNUL   0x10            /* colon--treat the empty string as unset */
 746
 747/* values of VSTYPE field */
 748#define VSNORMAL        0x1     /* normal variable:  $var or ${var} */
 749#define VSMINUS         0x2     /* ${var-text} */
 750#define VSPLUS          0x3     /* ${var+text} */
 751#define VSQUESTION      0x4     /* ${var?message} */
 752#define VSASSIGN        0x5     /* ${var=text} */
 753#define VSTRIMRIGHT     0x6     /* ${var%pattern} */
 754#define VSTRIMRIGHTMAX  0x7     /* ${var%%pattern} */
 755#define VSTRIMLEFT      0x8     /* ${var#pattern} */
 756#define VSTRIMLEFTMAX   0x9     /* ${var##pattern} */
 757#define VSLENGTH        0xa     /* ${#var} */
 758#if BASH_SUBSTR
 759#define VSSUBSTR        0xc     /* ${var:position:length} */
 760#endif
 761#if BASH_PATTERN_SUBST
 762#define VSREPLACE       0xd     /* ${var/pattern/replacement} */
 763#define VSREPLACEALL    0xe     /* ${var//pattern/replacement} */
 764#endif
 765
 766static const char dolatstr[] ALIGN1 = {
 767        CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=', CTLQUOTEMARK, '\0'
 768};
 769#define DOLATSTRLEN 6
 770
 771#define NCMD      0
 772#define NPIPE     1
 773#define NREDIR    2
 774#define NBACKGND  3
 775#define NSUBSHELL 4
 776#define NAND      5
 777#define NOR       6
 778#define NSEMI     7
 779#define NIF       8
 780#define NWHILE    9
 781#define NUNTIL   10
 782#define NFOR     11
 783#define NCASE    12
 784#define NCLIST   13
 785#define NDEFUN   14
 786#define NARG     15
 787#define NTO      16
 788#if BASH_REDIR_OUTPUT
 789#define NTO2     17
 790#endif
 791#define NCLOBBER 18
 792#define NFROM    19
 793#define NFROMTO  20
 794#define NAPPEND  21
 795#define NTOFD    22
 796#define NFROMFD  23
 797#define NHERE    24
 798#define NXHERE   25
 799#define NNOT     26
 800#define N_NUMBER 27
 801
 802union node;
 803
 804struct ncmd {
 805        smallint type; /* Nxxxx */
 806        int linno;
 807        union node *assign;
 808        union node *args;
 809        union node *redirect;
 810};
 811
 812struct npipe {
 813        smallint type;
 814        smallint pipe_backgnd;
 815        struct nodelist *cmdlist;
 816};
 817
 818struct nredir {
 819        smallint type;
 820        int linno;
 821        union node *n;
 822        union node *redirect;
 823};
 824
 825struct nbinary {
 826        smallint type;
 827        union node *ch1;
 828        union node *ch2;
 829};
 830
 831struct nif {
 832        smallint type;
 833        union node *test;
 834        union node *ifpart;
 835        union node *elsepart;
 836};
 837
 838struct nfor {
 839        smallint type;
 840        int linno;
 841        union node *args;
 842        union node *body;
 843        char *var;
 844};
 845
 846struct ncase {
 847        smallint type;
 848        int linno;
 849        union node *expr;
 850        union node *cases;
 851};
 852
 853struct nclist {
 854        smallint type;
 855        union node *next;
 856        union node *pattern;
 857        union node *body;
 858};
 859
 860struct ndefun {
 861        smallint type;
 862        int linno;
 863        char *text;
 864        union node *body;
 865};
 866
 867struct narg {
 868        smallint type;
 869        union node *next;
 870        char *text;
 871        struct nodelist *backquote;
 872};
 873
 874/* nfile and ndup layout must match!
 875 * NTOFD (>&fdnum) uses ndup structure, but we may discover mid-flight
 876 * that it is actually NTO2 (>&file), and change its type.
 877 */
 878struct nfile {
 879        smallint type;
 880        union node *next;
 881        int fd;
 882        int _unused_dupfd;
 883        union node *fname;
 884        char *expfname;
 885};
 886
 887struct ndup {
 888        smallint type;
 889        union node *next;
 890        int fd;
 891        int dupfd;
 892        union node *vname;
 893        char *_unused_expfname;
 894};
 895
 896struct nhere {
 897        smallint type;
 898        union node *next;
 899        int fd;
 900        union node *doc;
 901};
 902
 903struct nnot {
 904        smallint type;
 905        union node *com;
 906};
 907
 908union node {
 909        smallint type;
 910        struct ncmd ncmd;
 911        struct npipe npipe;
 912        struct nredir nredir;
 913        struct nbinary nbinary;
 914        struct nif nif;
 915        struct nfor nfor;
 916        struct ncase ncase;
 917        struct nclist nclist;
 918        struct ndefun ndefun;
 919        struct narg narg;
 920        struct nfile nfile;
 921        struct ndup ndup;
 922        struct nhere nhere;
 923        struct nnot nnot;
 924};
 925
 926/*
 927 * NODE_EOF is returned by parsecmd when it encounters an end of file.
 928 * It must be distinct from NULL.
 929 */
 930#define NODE_EOF ((union node *) -1L)
 931
 932struct nodelist {
 933        struct nodelist *next;
 934        union node *n;
 935};
 936
 937struct funcnode {
 938        int count;
 939        union node n;
 940};
 941
 942/*
 943 * Free a parse tree.
 944 */
 945static void
 946freefunc(struct funcnode *f)
 947{
 948        if (f && --f->count < 0)
 949                free(f);
 950}
 951
 952
 953/* ============ Debugging output */
 954
 955#if DEBUG
 956
 957static FILE *tracefile;
 958
 959static void
 960trace_printf(const char *fmt, ...)
 961{
 962        va_list va;
 963
 964        if (debug != 1)
 965                return;
 966        if (DEBUG_TIME)
 967                fprintf(tracefile, "%u ", (int) time(NULL));
 968        if (DEBUG_PID)
 969                fprintf(tracefile, "[%u] ", (int) getpid());
 970        if (DEBUG_SIG)
 971                fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
 972        va_start(va, fmt);
 973        vfprintf(tracefile, fmt, va);
 974        va_end(va);
 975}
 976
 977static void
 978trace_vprintf(const char *fmt, va_list va)
 979{
 980        if (debug != 1)
 981                return;
 982        vfprintf(tracefile, fmt, va);
 983        fprintf(tracefile, "\n");
 984}
 985
 986static void
 987trace_puts(const char *s)
 988{
 989        if (debug != 1)
 990                return;
 991        fputs(s, tracefile);
 992}
 993
 994static void
 995trace_puts_quoted(char *s)
 996{
 997        char *p;
 998        char c;
 999
1000        if (debug != 1)
1001                return;
1002        putc('"', tracefile);
1003        for (p = s; *p; p++) {
1004                switch ((unsigned char)*p) {
1005                case '\n': c = 'n'; goto backslash;
1006                case '\t': c = 't'; goto backslash;
1007                case '\r': c = 'r'; goto backslash;
1008                case '\"': c = '\"'; goto backslash;
1009                case '\\': c = '\\'; goto backslash;
1010                case CTLESC: c = 'e'; goto backslash;
1011                case CTLVAR: c = 'v'; goto backslash;
1012                case CTLBACKQ: c = 'q'; goto backslash;
1013 backslash:
1014                        putc('\\', tracefile);
1015                        putc(c, tracefile);
1016                        break;
1017                default:
1018                        if (*p >= ' ' && *p <= '~')
1019                                putc(*p, tracefile);
1020                        else {
1021                                putc('\\', tracefile);
1022                                putc((*p >> 6) & 03, tracefile);
1023                                putc((*p >> 3) & 07, tracefile);
1024                                putc(*p & 07, tracefile);
1025                        }
1026                        break;
1027                }
1028        }
1029        putc('"', tracefile);
1030}
1031
1032static void
1033trace_puts_args(char **ap)
1034{
1035        if (debug != 1)
1036                return;
1037        if (!*ap)
1038                return;
1039        while (1) {
1040                trace_puts_quoted(*ap);
1041                if (!*++ap) {
1042                        putc('\n', tracefile);
1043                        break;
1044                }
1045                putc(' ', tracefile);
1046        }
1047}
1048
1049static void
1050opentrace(void)
1051{
1052        char s[100];
1053#ifdef O_APPEND
1054        int flags;
1055#endif
1056
1057        if (debug != 1) {
1058                if (tracefile)
1059                        fflush(tracefile);
1060                /* leave open because libedit might be using it */
1061                return;
1062        }
1063        strcpy(s, "./trace");
1064        if (tracefile) {
1065                if (!freopen(s, "a", tracefile)) {
1066                        fprintf(stderr, "Can't re-open %s\n", s);
1067                        debug = 0;
1068                        return;
1069                }
1070        } else {
1071                tracefile = fopen(s, "a");
1072                if (tracefile == NULL) {
1073                        fprintf(stderr, "Can't open %s\n", s);
1074                        debug = 0;
1075                        return;
1076                }
1077        }
1078#ifdef O_APPEND
1079        flags = fcntl(fileno(tracefile), F_GETFL);
1080        if (flags >= 0)
1081                fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
1082#endif
1083        setlinebuf(tracefile);
1084        fputs("\nTracing started.\n", tracefile);
1085}
1086
1087static void
1088indent(int amount, char *pfx, FILE *fp)
1089{
1090        int i;
1091
1092        for (i = 0; i < amount; i++) {
1093                if (pfx && i == amount - 1)
1094                        fputs(pfx, fp);
1095                putc('\t', fp);
1096        }
1097}
1098
1099/* little circular references here... */
1100static void shtree(union node *n, int ind, char *pfx, FILE *fp);
1101
1102static void
1103sharg(union node *arg, FILE *fp)
1104{
1105        char *p;
1106        struct nodelist *bqlist;
1107        unsigned char subtype;
1108
1109        if (arg->type != NARG) {
1110                out1fmt("<node type %d>\n", arg->type);
1111                abort();
1112        }
1113        bqlist = arg->narg.backquote;
1114        for (p = arg->narg.text; *p; p++) {
1115                switch ((unsigned char)*p) {
1116                case CTLESC:
1117                        p++;
1118                        putc(*p, fp);
1119                        break;
1120                case CTLVAR:
1121                        putc('$', fp);
1122                        putc('{', fp);
1123                        subtype = *++p;
1124                        if (subtype == VSLENGTH)
1125                                putc('#', fp);
1126
1127                        while (*p != '=') {
1128                                putc(*p, fp);
1129                                p++;
1130                        }
1131
1132                        if (subtype & VSNUL)
1133                                putc(':', fp);
1134
1135                        switch (subtype & VSTYPE) {
1136                        case VSNORMAL:
1137                                putc('}', fp);
1138                                break;
1139                        case VSMINUS:
1140                                putc('-', fp);
1141                                break;
1142                        case VSPLUS:
1143                                putc('+', fp);
1144                                break;
1145                        case VSQUESTION:
1146                                putc('?', fp);
1147                                break;
1148                        case VSASSIGN:
1149                                putc('=', fp);
1150                                break;
1151                        case VSTRIMLEFT:
1152                                putc('#', fp);
1153                                break;
1154                        case VSTRIMLEFTMAX:
1155                                putc('#', fp);
1156                                putc('#', fp);
1157                                break;
1158                        case VSTRIMRIGHT:
1159                                putc('%', fp);
1160                                break;
1161                        case VSTRIMRIGHTMAX:
1162                                putc('%', fp);
1163                                putc('%', fp);
1164                                break;
1165                        case VSLENGTH:
1166                                break;
1167                        default:
1168                                out1fmt("<subtype %d>", subtype);
1169                        }
1170                        break;
1171                case CTLENDVAR:
1172                        putc('}', fp);
1173                        break;
1174                case CTLBACKQ:
1175                        putc('$', fp);
1176                        putc('(', fp);
1177                        shtree(bqlist->n, -1, NULL, fp);
1178                        putc(')', fp);
1179                        break;
1180                default:
1181                        putc(*p, fp);
1182                        break;
1183                }
1184        }
1185}
1186
1187static void
1188shcmd(union node *cmd, FILE *fp)
1189{
1190        union node *np;
1191        int first;
1192        const char *s;
1193        int dftfd;
1194
1195        first = 1;
1196        for (np = cmd->ncmd.args; np; np = np->narg.next) {
1197                if (!first)
1198                        putc(' ', fp);
1199                sharg(np, fp);
1200                first = 0;
1201        }
1202        for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
1203                if (!first)
1204                        putc(' ', fp);
1205                dftfd = 0;
1206                switch (np->nfile.type) {
1207                case NTO:      s = ">>"+1; dftfd = 1; break;
1208                case NCLOBBER: s = ">|"; dftfd = 1; break;
1209                case NAPPEND:  s = ">>"; dftfd = 1; break;
1210#if BASH_REDIR_OUTPUT
1211                case NTO2:
1212#endif
1213                case NTOFD:    s = ">&"; dftfd = 1; break;
1214                case NFROM:    s = "<"; break;
1215                case NFROMFD:  s = "<&"; break;
1216                case NFROMTO:  s = "<>"; break;
1217                default:       s = "*error*"; break;
1218                }
1219                if (np->nfile.fd != dftfd)
1220                        fprintf(fp, "%d", np->nfile.fd);
1221                fputs(s, fp);
1222                if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
1223                        fprintf(fp, "%d", np->ndup.dupfd);
1224                } else {
1225                        sharg(np->nfile.fname, fp);
1226                }
1227                first = 0;
1228        }
1229}
1230
1231static void
1232shtree(union node *n, int ind, char *pfx, FILE *fp)
1233{
1234        struct nodelist *lp;
1235        const char *s;
1236
1237        if (n == NULL)
1238                return;
1239
1240        indent(ind, pfx, fp);
1241
1242        if (n == NODE_EOF) {
1243                fputs("<EOF>", fp);
1244                return;
1245        }
1246
1247        switch (n->type) {
1248        case NSEMI:
1249                s = "; ";
1250                goto binop;
1251        case NAND:
1252                s = " && ";
1253                goto binop;
1254        case NOR:
1255                s = " || ";
1256 binop:
1257                shtree(n->nbinary.ch1, ind, NULL, fp);
1258                /* if (ind < 0) */
1259                        fputs(s, fp);
1260                shtree(n->nbinary.ch2, ind, NULL, fp);
1261                break;
1262        case NCMD:
1263                shcmd(n, fp);
1264                if (ind >= 0)
1265                        putc('\n', fp);
1266                break;
1267        case NPIPE:
1268                for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
1269                        shtree(lp->n, 0, NULL, fp);
1270                        if (lp->next)
1271                                fputs(" | ", fp);
1272                }
1273                if (n->npipe.pipe_backgnd)
1274                        fputs(" &", fp);
1275                if (ind >= 0)
1276                        putc('\n', fp);
1277                break;
1278        default:
1279                fprintf(fp, "<node type %d>", n->type);
1280                if (ind >= 0)
1281                        putc('\n', fp);
1282                break;
1283        }
1284}
1285
1286static void
1287showtree(union node *n)
1288{
1289        trace_puts("showtree called\n");
1290        shtree(n, 1, NULL, stderr);
1291}
1292
1293#endif /* DEBUG */
1294
1295
1296/* ============ Parser data */
1297
1298/*
1299 * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
1300 */
1301struct strlist {
1302        struct strlist *next;
1303        char *text;
1304};
1305
1306struct alias;
1307
1308struct strpush {
1309        struct strpush *prev;   /* preceding string on stack */
1310        char *prev_string;
1311        int prev_left_in_line;
1312#if ENABLE_ASH_ALIAS
1313        struct alias *ap;       /* if push was associated with an alias */
1314#endif
1315        char *string;           /* remember the string since it may change */
1316
1317        /* Remember last two characters for pungetc. */
1318        int lastc[2];
1319
1320        /* Number of outstanding calls to pungetc. */
1321        int unget;
1322};
1323
1324/*
1325 * The parsefile structure pointed to by the global variable parsefile
1326 * contains information about the current file being read.
1327 */
1328struct parsefile {
1329        struct parsefile *prev; /* preceding file on stack */
1330        int linno;              /* current line */
1331        int pf_fd;              /* file descriptor (or -1 if string) */
1332        int left_in_line;       /* number of chars left in this line */
1333        int left_in_buffer;     /* number of chars left in this buffer past the line */
1334        char *next_to_pgetc;    /* next char in buffer */
1335        char *buf;              /* input buffer */
1336        struct strpush *strpush; /* for pushing strings at this level */
1337        struct strpush basestrpush; /* so pushing one is fast */
1338
1339        /* Remember last two characters for pungetc. */
1340        int lastc[2];
1341
1342        /* Number of outstanding calls to pungetc. */
1343        int unget;
1344};
1345
1346static struct parsefile basepf;        /* top level input file */
1347static struct parsefile *g_parsefile = &basepf;  /* current input file */
1348static char *commandname;              /* currently executing command */
1349
1350
1351/* ============ Message printing */
1352
1353static void
1354ash_vmsg(const char *msg, va_list ap)
1355{
1356        fprintf(stderr, "%s: ", arg0);
1357        if (commandname) {
1358                if (strcmp(arg0, commandname))
1359                        fprintf(stderr, "%s: ", commandname);
1360                if (!iflag || g_parsefile->pf_fd > 0)
1361                        fprintf(stderr, "line %d: ", errlinno);
1362        }
1363        vfprintf(stderr, msg, ap);
1364        newline_and_flush(stderr);
1365}
1366
1367/*
1368 * Exverror is called to raise the error exception.  If the second argument
1369 * is not NULL then error prints an error message using printf style
1370 * formatting.  It then raises the error exception.
1371 */
1372static void ash_vmsg_and_raise(int, const char *, va_list) NORETURN;
1373static void
1374ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
1375{
1376#if DEBUG
1377        if (msg) {
1378                TRACE(("ash_vmsg_and_raise(%d):", cond));
1379                TRACEV((msg, ap));
1380        } else
1381                TRACE(("ash_vmsg_and_raise(%d):NULL\n", cond));
1382        if (msg)
1383#endif
1384                ash_vmsg(msg, ap);
1385
1386        flush_stdout_stderr();
1387        raise_exception(cond);
1388        /* NOTREACHED */
1389}
1390
1391static void ash_msg_and_raise_error(const char *, ...) NORETURN;
1392static void
1393ash_msg_and_raise_error(const char *msg, ...)
1394{
1395        va_list ap;
1396
1397        exitstatus = 2;
1398
1399        va_start(ap, msg);
1400        ash_vmsg_and_raise(EXERROR, msg, ap);
1401        /* NOTREACHED */
1402        va_end(ap);
1403}
1404
1405/*
1406 * 'fmt' must be a string literal.
1407 */
1408#define ash_msg_and_raise_perror(fmt, ...) ash_msg_and_raise_error(fmt ": "STRERROR_FMT, ##__VA_ARGS__ STRERROR_ERRNO)
1409
1410static void raise_error_syntax(const char *) NORETURN;
1411static void
1412raise_error_syntax(const char *msg)
1413{
1414        errlinno = g_parsefile->linno;
1415        ash_msg_and_raise_error("syntax error: %s", msg);
1416        /* NOTREACHED */
1417}
1418
1419static void ash_msg_and_raise(int, const char *, ...) NORETURN;
1420static void
1421ash_msg_and_raise(int cond, const char *msg, ...)
1422{
1423        va_list ap;
1424
1425        va_start(ap, msg);
1426        ash_vmsg_and_raise(cond, msg, ap);
1427        /* NOTREACHED */
1428        va_end(ap);
1429}
1430
1431/*
1432 * error/warning routines for external builtins
1433 */
1434static void
1435ash_msg(const char *fmt, ...)
1436{
1437        va_list ap;
1438
1439        va_start(ap, fmt);
1440        ash_vmsg(fmt, ap);
1441        va_end(ap);
1442}
1443
1444/*
1445 * Return a string describing an error.  The returned string may be a
1446 * pointer to a static buffer that will be overwritten on the next call.
1447 * Action describes the operation that got the error.
1448 */
1449static const char *
1450errmsg(int e, const char *em)
1451{
1452        if (e == ENOENT || e == ENOTDIR) {
1453                return em;
1454        }
1455        return strerror(e);
1456}
1457
1458
1459/* ============ Memory allocation */
1460
1461#if 0
1462/* I consider these wrappers nearly useless:
1463 * ok, they return you to nearest exception handler, but
1464 * how much memory do you leak in the process, making
1465 * memory starvation worse?
1466 */
1467static void *
1468ckrealloc(void * p, size_t nbytes)
1469{
1470        p = realloc(p, nbytes);
1471        if (!p)
1472                ash_msg_and_raise_error(bb_msg_memory_exhausted);
1473        return p;
1474}
1475
1476static void *
1477ckmalloc(size_t nbytes)
1478{
1479        return ckrealloc(NULL, nbytes);
1480}
1481
1482static void *
1483ckzalloc(size_t nbytes)
1484{
1485        return memset(ckmalloc(nbytes), 0, nbytes);
1486}
1487
1488static char *
1489ckstrdup(const char *s)
1490{
1491        char *p = strdup(s);
1492        if (!p)
1493                ash_msg_and_raise_error(bb_msg_memory_exhausted);
1494        return p;
1495}
1496#else
1497/* Using bbox equivalents. They exit if out of memory */
1498# define ckrealloc xrealloc
1499# define ckmalloc  xmalloc
1500# define ckzalloc  xzalloc
1501# define ckstrdup  xstrdup
1502#endif
1503
1504/*
1505 * It appears that grabstackstr() will barf with such alignments
1506 * because stalloc() will return a string allocated in a new stackblock.
1507 */
1508#define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
1509enum {
1510        /* Most machines require the value returned from malloc to be aligned
1511         * in some way.  The following macro will get this right
1512         * on many machines.  */
1513        SHELL_SIZE = sizeof(union { int i; char *cp; double d; }) - 1,
1514        /* Minimum size of a block */
1515        MINSIZE = SHELL_ALIGN(504),
1516};
1517
1518struct stack_block {
1519        struct stack_block *prev;
1520        char space[MINSIZE];
1521};
1522
1523struct stackmark {
1524        struct stack_block *stackp;
1525        char *stacknxt;
1526        size_t stacknleft;
1527};
1528
1529
1530struct globals_memstack {
1531        struct stack_block *g_stackp; // = &stackbase;
1532        char *g_stacknxt; // = stackbase.space;
1533        char *sstrend; // = stackbase.space + MINSIZE;
1534        size_t g_stacknleft; // = MINSIZE;
1535        struct stack_block stackbase;
1536};
1537extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack;
1538#define G_memstack (*ash_ptr_to_globals_memstack)
1539#define g_stackp     (G_memstack.g_stackp    )
1540#define g_stacknxt   (G_memstack.g_stacknxt  )
1541#define sstrend      (G_memstack.sstrend     )
1542#define g_stacknleft (G_memstack.g_stacknleft)
1543#define stackbase    (G_memstack.stackbase   )
1544#define INIT_G_memstack() do { \
1545        (*(struct globals_memstack**)&ash_ptr_to_globals_memstack) = xzalloc(sizeof(G_memstack)); \
1546        barrier(); \
1547        g_stackp = &stackbase; \
1548        g_stacknxt = stackbase.space; \
1549        g_stacknleft = MINSIZE; \
1550        sstrend = stackbase.space + MINSIZE; \
1551} while (0)
1552
1553
1554#define stackblock()     ((void *)g_stacknxt)
1555#define stackblocksize() g_stacknleft
1556
1557/*
1558 * Parse trees for commands are allocated in lifo order, so we use a stack
1559 * to make this more efficient, and also to avoid all sorts of exception
1560 * handling code to handle interrupts in the middle of a parse.
1561 *
1562 * The size 504 was chosen because the Ultrix malloc handles that size
1563 * well.
1564 */
1565static void *
1566stalloc(size_t nbytes)
1567{
1568        char *p;
1569        size_t aligned;
1570
1571        aligned = SHELL_ALIGN(nbytes);
1572        if (aligned > g_stacknleft) {
1573                size_t len;
1574                size_t blocksize;
1575                struct stack_block *sp;
1576
1577                blocksize = aligned;
1578                if (blocksize < MINSIZE)
1579                        blocksize = MINSIZE;
1580                len = sizeof(struct stack_block) - MINSIZE + blocksize;
1581                if (len < blocksize)
1582                        ash_msg_and_raise_error(bb_msg_memory_exhausted);
1583                INT_OFF;
1584                sp = ckmalloc(len);
1585                sp->prev = g_stackp;
1586                g_stacknxt = sp->space;
1587                g_stacknleft = blocksize;
1588                sstrend = g_stacknxt + blocksize;
1589                g_stackp = sp;
1590                INT_ON;
1591        }
1592        p = g_stacknxt;
1593        g_stacknxt += aligned;
1594        g_stacknleft -= aligned;
1595        return p;
1596}
1597
1598static void *
1599stzalloc(size_t nbytes)
1600{
1601        return memset(stalloc(nbytes), 0, nbytes);
1602}
1603
1604static void
1605stunalloc(void *p)
1606{
1607#if DEBUG
1608        if (!p || (g_stacknxt < (char *)p) || ((char *)p < g_stackp->space)) {
1609                write(STDERR_FILENO, "stunalloc\n", 10);
1610                abort();
1611        }
1612#endif
1613        g_stacknleft += g_stacknxt - (char *)p;
1614        g_stacknxt = p;
1615}
1616
1617/*
1618 * Like strdup but works with the ash stack.
1619 */
1620static char *
1621sstrdup(const char *p)
1622{
1623        size_t len = strlen(p) + 1;
1624        return memcpy(stalloc(len), p, len);
1625}
1626
1627static ALWAYS_INLINE void
1628grabstackblock(size_t len)
1629{
1630        stalloc(len);
1631}
1632
1633static void
1634pushstackmark(struct stackmark *mark, size_t len)
1635{
1636        mark->stackp = g_stackp;
1637        mark->stacknxt = g_stacknxt;
1638        mark->stacknleft = g_stacknleft;
1639        grabstackblock(len);
1640}
1641
1642static void
1643setstackmark(struct stackmark *mark)
1644{
1645        pushstackmark(mark, g_stacknxt == g_stackp->space && g_stackp != &stackbase);
1646}
1647
1648static void
1649popstackmark(struct stackmark *mark)
1650{
1651        struct stack_block *sp;
1652
1653        if (!mark->stackp)
1654                return;
1655
1656        INT_OFF;
1657        while (g_stackp != mark->stackp) {
1658                sp = g_stackp;
1659                g_stackp = sp->prev;
1660                free(sp);
1661        }
1662        g_stacknxt = mark->stacknxt;
1663        g_stacknleft = mark->stacknleft;
1664        sstrend = mark->stacknxt + mark->stacknleft;
1665        INT_ON;
1666}
1667
1668/*
1669 * When the parser reads in a string, it wants to stick the string on the
1670 * stack and only adjust the stack pointer when it knows how big the
1671 * string is.  Stackblock (defined in stack.h) returns a pointer to a block
1672 * of space on top of the stack and stackblocklen returns the length of
1673 * this block.  Growstackblock will grow this space by at least one byte,
1674 * possibly moving it (like realloc).  Grabstackblock actually allocates the
1675 * part of the block that has been used.
1676 */
1677static void
1678growstackblock(void)
1679{
1680        size_t newlen;
1681
1682        newlen = g_stacknleft * 2;
1683        if (newlen < g_stacknleft)
1684                ash_msg_and_raise_error(bb_msg_memory_exhausted);
1685        if (newlen < 128)
1686                newlen += 128;
1687
1688        if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1689                struct stack_block *sp;
1690                struct stack_block *prevstackp;
1691                size_t grosslen;
1692
1693                INT_OFF;
1694                sp = g_stackp;
1695                prevstackp = sp->prev;
1696                grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
1697                sp = ckrealloc(sp, grosslen);
1698                sp->prev = prevstackp;
1699                g_stackp = sp;
1700                g_stacknxt = sp->space;
1701                g_stacknleft = newlen;
1702                sstrend = sp->space + newlen;
1703                INT_ON;
1704        } else {
1705                char *oldspace = g_stacknxt;
1706                size_t oldlen = g_stacknleft;
1707                char *p = stalloc(newlen);
1708
1709                /* free the space we just allocated */
1710                g_stacknxt = memcpy(p, oldspace, oldlen);
1711                g_stacknleft += newlen;
1712        }
1713}
1714
1715/*
1716 * The following routines are somewhat easier to use than the above.
1717 * The user declares a variable of type STACKSTR, which may be declared
1718 * to be a register.  The macro STARTSTACKSTR initializes things.  Then
1719 * the user uses the macro STPUTC to add characters to the string.  In
1720 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
1721 * grown as necessary.  When the user is done, she can just leave the
1722 * string there and refer to it using stackblock().  Or she can allocate
1723 * the space for it using grabstackstr().  If it is necessary to allow
1724 * someone else to use the stack temporarily and then continue to grow
1725 * the string, the user should use grabstack to allocate the space, and
1726 * then call ungrabstr(p) to return to the previous mode of operation.
1727 *
1728 * USTPUTC is like STPUTC except that it doesn't check for overflow.
1729 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
1730 * is space for at least one character.
1731 */
1732static void *
1733growstackstr(void)
1734{
1735        size_t len = stackblocksize();
1736        growstackblock();
1737        return (char *)stackblock() + len;
1738}
1739
1740/*
1741 * Called from CHECKSTRSPACE.
1742 */
1743static char *
1744makestrspace(size_t newlen, char *p)
1745{
1746        size_t len = p - g_stacknxt;
1747        size_t size;
1748
1749        for (;;) {
1750                size_t nleft;
1751
1752                size = stackblocksize();
1753                nleft = size - len;
1754                if (nleft >= newlen)
1755                        break;
1756                growstackblock();
1757        }
1758        return (char *)stackblock() + len;
1759}
1760
1761static char *
1762stack_nputstr(const char *s, size_t n, char *p)
1763{
1764        p = makestrspace(n, p);
1765        p = (char *)mempcpy(p, s, n);
1766        return p;
1767}
1768
1769static char *
1770stack_putstr(const char *s, char *p)
1771{
1772        return stack_nputstr(s, strlen(s), p);
1773}
1774
1775static char *
1776_STPUTC(int c, char *p)
1777{
1778        if (p == sstrend)
1779                p = growstackstr();
1780        *p++ = c;
1781        return p;
1782}
1783
1784#define STARTSTACKSTR(p)        ((p) = stackblock())
1785#define STPUTC(c, p)            ((p) = _STPUTC((c), (p)))
1786#define CHECKSTRSPACE(n, p) do { \
1787        char *q = (p); \
1788        size_t l = (n); \
1789        size_t m = sstrend - q; \
1790        if (l > m) \
1791                (p) = makestrspace(l, q); \
1792} while (0)
1793#define USTPUTC(c, p)           (*(p)++ = (c))
1794#define STACKSTRNUL(p) do { \
1795        if ((p) == sstrend) \
1796                (p) = growstackstr(); \
1797        *(p) = '\0'; \
1798} while (0)
1799#define STUNPUTC(p)             (--(p))
1800#define STTOPC(p)               ((p)[-1])
1801#define STADJUST(amount, p)     ((p) += (amount))
1802
1803#define grabstackstr(p)         stalloc((char *)(p) - (char *)stackblock())
1804#define ungrabstackstr(s, p)    stunalloc(s)
1805#define stackstrend()           ((void *)sstrend)
1806
1807
1808/* ============ String helpers */
1809
1810/*
1811 * prefix -- see if pfx is a prefix of string.
1812 */
1813static char *
1814prefix(const char *string, const char *pfx)
1815{
1816        while (*pfx) {
1817                if (*pfx++ != *string++)
1818                        return NULL;
1819        }
1820        return (char *) string;
1821}
1822
1823/*
1824 * Check for a valid number.  This should be elsewhere.
1825 */
1826static int
1827is_number(const char *p)
1828{
1829        do {
1830                if (!isdigit(*p))
1831                        return 0;
1832        } while (*++p != '\0');
1833        return 1;
1834}
1835
1836/*
1837 * Convert a string of digits to an integer, printing an error message on
1838 * failure.
1839 */
1840static int
1841number(const char *s)
1842{
1843        if (!is_number(s))
1844                ash_msg_and_raise_error(msg_illnum, s);
1845        return atoi(s);
1846}
1847
1848/*
1849 * Produce a single quoted string suitable as input to the shell.
1850 * The return string is allocated on the stack.
1851 */
1852static char *
1853single_quote(const char *s)
1854{
1855        char *p;
1856
1857        STARTSTACKSTR(p);
1858
1859        do {
1860                char *q;
1861                size_t len;
1862
1863                len = strchrnul(s, '\'') - s;
1864
1865                q = p = makestrspace(len + 3, p);
1866
1867                *q++ = '\'';
1868                q = (char *)mempcpy(q, s, len);
1869                *q++ = '\'';
1870                s += len;
1871
1872                STADJUST(q - p, p);
1873
1874                if (*s != '\'')
1875                        break;
1876                len = 0;
1877                do len++; while (*++s == '\'');
1878
1879                q = p = makestrspace(len + 3, p);
1880
1881                *q++ = '"';
1882                q = (char *)mempcpy(q, s - len, len);
1883                *q++ = '"';
1884
1885                STADJUST(q - p, p);
1886        } while (*s);
1887
1888        USTPUTC('\0', p);
1889
1890        return stackblock();
1891}
1892
1893/*
1894 * Produce a possibly single quoted string suitable as input to the shell.
1895 * If quoting was done, the return string is allocated on the stack,
1896 * otherwise a pointer to the original string is returned.
1897 */
1898static const char *
1899maybe_single_quote(const char *s)
1900{
1901        const char *p = s;
1902
1903        while (*p) {
1904                /* Assuming ACSII */
1905                /* quote ctrl_chars space !"#$%&'()* */
1906                if (*p < '+')
1907                        goto need_quoting;
1908                /* quote ;<=>? */
1909                if (*p >= ';' && *p <= '?')
1910                        goto need_quoting;
1911                /* quote `[\ */
1912                if (*p == '`')
1913                        goto need_quoting;
1914                if (*p == '[')
1915                        goto need_quoting;
1916                if (*p == '\\')
1917                        goto need_quoting;
1918                /* quote {|}~ DEL and high bytes */
1919                if (*p > 'z')
1920                        goto need_quoting;
1921                /* Not quoting these: +,-./ 0-9 :@ A-Z ]^_ a-z */
1922                /* TODO: maybe avoid quoting % */
1923                p++;
1924        }
1925        return s;
1926
1927 need_quoting:
1928        return single_quote(s);
1929}
1930
1931
1932/* ============ nextopt */
1933
1934static char **argptr;                  /* argument list for builtin commands */
1935static char *optionarg;                /* set by nextopt (like getopt) */
1936static char *optptr;                   /* used by nextopt */
1937
1938/*
1939 * XXX - should get rid of. Have all builtins use getopt(3).
1940 * The library getopt must have the BSD extension static variable
1941 * "optreset", otherwise it can't be used within the shell safely.
1942 *
1943 * Standard option processing (a la getopt) for builtin routines.
1944 * The only argument that is passed to nextopt is the option string;
1945 * the other arguments are unnecessary. It returns the character,
1946 * or '\0' on end of input.
1947 */
1948static int
1949nextopt(const char *optstring)
1950{
1951        char *p;
1952        const char *q;
1953        char c;
1954
1955        p = optptr;
1956        if (p == NULL || *p == '\0') {
1957                /* We ate entire "-param", take next one */
1958                p = *argptr;
1959                if (p == NULL)
1960                        return '\0';
1961                if (*p != '-')
1962                        return '\0';
1963                if (*++p == '\0') /* just "-" ? */
1964                        return '\0';
1965                argptr++;
1966                if (LONE_DASH(p)) /* "--" ? */
1967                        return '\0';
1968                /* p => next "-param" */
1969        }
1970        /* p => some option char in the middle of a "-param" */
1971        c = *p++;
1972        for (q = optstring; *q != c;) {
1973                if (*q == '\0')
1974                        ash_msg_and_raise_error("illegal option -%c", c);
1975                if (*++q == ':')
1976                        q++;
1977        }
1978        if (*++q == ':') {
1979                if (*p == '\0') {
1980                        p = *argptr++;
1981                        if (p == NULL)
1982                                ash_msg_and_raise_error("no arg for -%c option", c);
1983                }
1984                optionarg = p;
1985                p = NULL;
1986        }
1987        optptr = p;
1988        return c;
1989}
1990
1991
1992/* ============ Shell variables */
1993
1994struct shparam {
1995        int nparam;             /* # of positional parameters (without $0) */
1996#if ENABLE_ASH_GETOPTS
1997        int optind;             /* next parameter to be processed by getopts */
1998        int optoff;             /* used by getopts */
1999#endif
2000        unsigned char malloced; /* if parameter list dynamically allocated */
2001        char **p;               /* parameter list */
2002};
2003
2004/*
2005 * Free the list of positional parameters.
2006 */
2007static void
2008freeparam(volatile struct shparam *param)
2009{
2010        if (param->malloced) {
2011                char **ap, **ap1;
2012                ap = ap1 = param->p;
2013                while (*ap)
2014                        free(*ap++);
2015                free(ap1);
2016        }
2017}
2018
2019#if ENABLE_ASH_GETOPTS
2020static void FAST_FUNC getoptsreset(const char *value);
2021#endif
2022
2023struct var {
2024        struct var *next;               /* next entry in hash list */
2025        int flags;                      /* flags are defined above */
2026        const char *var_text;           /* name=value */
2027        void (*var_func)(const char *) FAST_FUNC; /* function to be called when  */
2028                                        /* the variable gets set/unset */
2029};
2030
2031struct localvar {
2032        struct localvar *next;          /* next local variable in list */
2033        struct var *vp;                 /* the variable that was made local */
2034        int flags;                      /* saved flags */
2035        const char *text;               /* saved text */
2036};
2037
2038/* flags */
2039#define VEXPORT         0x01    /* variable is exported */
2040#define VREADONLY       0x02    /* variable cannot be modified */
2041#define VSTRFIXED       0x04    /* variable struct is statically allocated */
2042#define VTEXTFIXED      0x08    /* text is statically allocated */
2043#define VSTACK          0x10    /* text is allocated on the stack */
2044#define VUNSET          0x20    /* the variable is not set */
2045#define VNOFUNC         0x40    /* don't call the callback function */
2046#define VNOSET          0x80    /* do not set variable - just readonly test */
2047#define VNOSAVE         0x100   /* when text is on the heap before setvareq */
2048#if ENABLE_ASH_RANDOM_SUPPORT
2049# define VDYNAMIC       0x200   /* dynamic variable */
2050#else
2051# define VDYNAMIC       0
2052#endif
2053
2054
2055/* Need to be before varinit_data[] */
2056#if ENABLE_LOCALE_SUPPORT
2057static void FAST_FUNC
2058change_lc_all(const char *value)
2059{
2060        if (value && *value != '\0')
2061                setlocale(LC_ALL, value);
2062}
2063static void FAST_FUNC
2064change_lc_ctype(const char *value)
2065{
2066        if (value && *value != '\0')
2067                setlocale(LC_CTYPE, value);
2068}
2069#endif
2070#if ENABLE_ASH_MAIL
2071static void chkmail(void);
2072static void changemail(const char *var_value) FAST_FUNC;
2073#else
2074# define chkmail()  ((void)0)
2075#endif
2076static void changepath(const char *) FAST_FUNC;
2077#if ENABLE_ASH_RANDOM_SUPPORT
2078static void change_random(const char *) FAST_FUNC;
2079#endif
2080#if BASH_EPOCH_VARS
2081static void change_seconds(const char *) FAST_FUNC;
2082static void change_realtime(const char *) FAST_FUNC;
2083#endif
2084
2085static const struct {
2086        int flags;
2087        const char *var_text;
2088        void (*var_func)(const char *) FAST_FUNC;
2089} varinit_data[] = {
2090        /*
2091         * Note: VEXPORT would not work correctly here for NOFORK applets:
2092         * some environment strings may be constant.
2093         */
2094        { VSTRFIXED|VTEXTFIXED       , defifsvar   , NULL            },
2095#if ENABLE_ASH_MAIL
2096        { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL"      , changemail      },
2097        { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH"  , changemail      },
2098#endif
2099        { VSTRFIXED|VTEXTFIXED       , bb_PATH_root_path, changepath },
2100        { VSTRFIXED|VTEXTFIXED       , "PS1=$ "    , NULL            },
2101        { VSTRFIXED|VTEXTFIXED       , "PS2=> "    , NULL            },
2102        { VSTRFIXED|VTEXTFIXED       , "PS4=+ "    , NULL            },
2103#if ENABLE_ASH_GETOPTS
2104        { VSTRFIXED|VTEXTFIXED       , defoptindvar, getoptsreset    },
2105#endif
2106        { VSTRFIXED|VTEXTFIXED       , NULL /* inited to linenovar */, NULL },
2107#if ENABLE_ASH_RANDOM_SUPPORT
2108        { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
2109#endif
2110#if BASH_EPOCH_VARS
2111        { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHSECONDS", change_seconds },
2112        { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHREALTIME", change_realtime },
2113#endif
2114#if ENABLE_LOCALE_SUPPORT
2115        { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL"    , change_lc_all   },
2116        { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE"  , change_lc_ctype },
2117#endif
2118#if ENABLE_FEATURE_EDITING_SAVEHISTORY
2119        { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE"  , NULL            },
2120#endif
2121};
2122
2123struct redirtab;
2124
2125struct globals_var {
2126        struct shparam shellparam;      /* $@ current positional parameters */
2127        struct redirtab *redirlist;
2128        int preverrout_fd;   /* stderr fd: usually 2, unless redirect moved it */
2129        struct var *vartab[VTABSIZE];
2130        struct var varinit[ARRAY_SIZE(varinit_data)];
2131        int lineno;
2132        char linenovar[sizeof("LINENO=") + sizeof(int)*3];
2133};
2134extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
2135#define G_var (*ash_ptr_to_globals_var)
2136#define shellparam    (G_var.shellparam   )
2137//#define redirlist     (G_var.redirlist    )
2138#define preverrout_fd (G_var.preverrout_fd)
2139#define vartab        (G_var.vartab       )
2140#define varinit       (G_var.varinit      )
2141#define lineno        (G_var.lineno       )
2142#define linenovar     (G_var.linenovar    )
2143#define vifs      varinit[0]
2144#if ENABLE_ASH_MAIL
2145# define vmail    varinit[1]
2146# define vmpath   varinit[2]
2147#endif
2148#define VAR_OFFSET1 (ENABLE_ASH_MAIL*2)
2149#define vpath     varinit[VAR_OFFSET1 + 1]
2150#define vps1      varinit[VAR_OFFSET1 + 2]
2151#define vps2      varinit[VAR_OFFSET1 + 3]
2152#define vps4      varinit[VAR_OFFSET1 + 4]
2153#if ENABLE_ASH_GETOPTS
2154# define voptind  varinit[VAR_OFFSET1 + 5]
2155#endif
2156#define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS)
2157#define vlineno   varinit[VAR_OFFSET2 + 5]
2158#if ENABLE_ASH_RANDOM_SUPPORT
2159# define vrandom  varinit[VAR_OFFSET2 + 6]
2160#endif
2161#define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT)
2162#if BASH_EPOCH_VARS
2163# define vepochs  varinit[VAR_OFFSET3 + 6]
2164# define vepochr  varinit[VAR_OFFSET3 + 7]
2165#endif
2166#define INIT_G_var() do { \
2167        unsigned i; \
2168        (*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \
2169        barrier(); \
2170        for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
2171                varinit[i].flags    = varinit_data[i].flags; \
2172                varinit[i].var_text = varinit_data[i].var_text; \
2173                varinit[i].var_func = varinit_data[i].var_func; \
2174        } \
2175        strcpy(linenovar, "LINENO="); \
2176        vlineno.var_text = linenovar; \
2177} while (0)
2178
2179/*
2180 * The following macros access the values of the above variables.
2181 * They have to skip over the name.  They return the null string
2182 * for unset variables.
2183 */
2184#define ifsval()        (vifs.var_text + 4)
2185#define ifsset()        ((vifs.flags & VUNSET) == 0)
2186#if ENABLE_ASH_MAIL
2187# define mailval()      (vmail.var_text + 5)
2188# define mpathval()     (vmpath.var_text + 9)
2189# define mpathset()     ((vmpath.flags & VUNSET) == 0)
2190#endif
2191#define pathval()       (vpath.var_text + 5)
2192#define ps1val()        (vps1.var_text + 4)
2193#define ps2val()        (vps2.var_text + 4)
2194#define ps4val()        (vps4.var_text + 4)
2195#if ENABLE_ASH_GETOPTS
2196# define optindval()    (voptind.var_text + 7)
2197#endif
2198
2199#if ENABLE_ASH_GETOPTS
2200static void FAST_FUNC
2201getoptsreset(const char *value)
2202{
2203        shellparam.optind = 1;
2204        if (is_number(value))
2205                shellparam.optind = number(value) ?: 1;
2206        shellparam.optoff = -1;
2207}
2208#endif
2209
2210/*
2211 * Compares two strings up to the first = or '\0'.  The first
2212 * string must be terminated by '='; the second may be terminated by
2213 * either '=' or '\0'.
2214 */
2215static int
2216varcmp(const char *p, const char *q)
2217{
2218        int c, d;
2219
2220        while ((c = *p) == (d = *q)) {
2221                if (c == '\0' || c == '=')
2222                        goto out;
2223                p++;
2224                q++;
2225        }
2226        if (c == '=')
2227                c = '\0';
2228        if (d == '=')
2229                d = '\0';
2230 out:
2231        return c - d;
2232}
2233
2234/*
2235 * Find the appropriate entry in the hash table from the name.
2236 */
2237static struct var **
2238hashvar(const char *p)
2239{
2240        unsigned hashval;
2241
2242        hashval = ((unsigned char) *p) << 4;
2243        while (*p && *p != '=')
2244                hashval += (unsigned char) *p++;
2245        return &vartab[hashval % VTABSIZE];
2246}
2247
2248static int
2249vpcmp(const void *a, const void *b)
2250{
2251        return varcmp(*(const char **)a, *(const char **)b);
2252}
2253
2254/*
2255 * This routine initializes the builtin variables.
2256 */
2257static void
2258initvar(void)
2259{
2260        struct var *vp;
2261        struct var *end;
2262        struct var **vpp;
2263
2264        /*
2265         * PS1 depends on uid
2266         */
2267#if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
2268        vps1.var_text = "PS1=\\w \\$ ";
2269#else
2270        if (!geteuid())
2271                vps1.var_text = "PS1=# ";
2272#endif
2273        vp = varinit;
2274        end = vp + ARRAY_SIZE(varinit);
2275        do {
2276                vpp = hashvar(vp->var_text);
2277                vp->next = *vpp;
2278                *vpp = vp;
2279        } while (++vp < end);
2280}
2281
2282static struct var **
2283findvar(struct var **vpp, const char *name)
2284{
2285        for (; *vpp; vpp = &(*vpp)->next) {
2286                if (varcmp((*vpp)->var_text, name) == 0) {
2287                        break;
2288                }
2289        }
2290        return vpp;
2291}
2292
2293/*
2294 * Find the value of a variable.  Returns NULL if not set.
2295 */
2296static const char* FAST_FUNC
2297lookupvar(const char *name)
2298{
2299        struct var *v;
2300
2301        v = *findvar(hashvar(name), name);
2302        if (v) {
2303#if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS
2304        /*
2305         * Dynamic variables are implemented roughly the same way they are
2306         * in bash. Namely, they're "special" so long as they aren't unset.
2307         * As soon as they're unset, they're no longer dynamic, and dynamic
2308         * lookup will no longer happen at that point. -- PFM.
2309         */
2310                if (v->flags & VDYNAMIC)
2311                        v->var_func(NULL);
2312#endif
2313                if (!(v->flags & VUNSET)) {
2314                        if (v == &vlineno && v->var_text == linenovar) {
2315                                fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno);
2316                        }
2317                        return var_end(v->var_text);
2318                }
2319        }
2320        return NULL;
2321}
2322
2323#if ENABLE_UNICODE_SUPPORT
2324static void
2325reinit_unicode_for_ash(void)
2326{
2327        /* Unicode support should be activated even if LANG is set
2328         * _during_ shell execution, not only if it was set when
2329         * shell was started. Therefore, re-check LANG every time:
2330         */
2331        if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2332         || ENABLE_UNICODE_USING_LOCALE
2333        ) {
2334                const char *s = lookupvar("LC_ALL");
2335                if (!s) s = lookupvar("LC_CTYPE");
2336                if (!s) s = lookupvar("LANG");
2337                reinit_unicode(s);
2338        }
2339}
2340#else
2341# define reinit_unicode_for_ash() ((void)0)
2342#endif
2343
2344/*
2345 * Search the environment of a builtin command.
2346 */
2347static ALWAYS_INLINE const char *
2348bltinlookup(const char *name)
2349{
2350        return lookupvar(name);
2351}
2352
2353/*
2354 * Same as setvar except that the variable and value are passed in
2355 * the first argument as name=value.  Since the first argument will
2356 * be actually stored in the table, it should not be a string that
2357 * will go away.
2358 * Called with interrupts off.
2359 */
2360static struct var *
2361setvareq(char *s, int flags)
2362{
2363        struct var *vp, **vpp;
2364
2365        vpp = hashvar(s);
2366        flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
2367        vpp = findvar(vpp, s);
2368        vp = *vpp;
2369        if (vp) {
2370                if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
2371                        const char *n;
2372
2373                        if (flags & VNOSAVE)
2374                                free(s);
2375                        n = vp->var_text;
2376                        exitstatus = 1;
2377                        ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
2378                }
2379
2380                if (flags & VNOSET)
2381                        goto out;
2382
2383                if (vp->var_func && !(flags & VNOFUNC))
2384                        vp->var_func(var_end(s));
2385
2386                if (!(vp->flags & (VTEXTFIXED|VSTACK)))
2387                        free((char*)vp->var_text);
2388
2389                if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | (vp->flags & VSTRFIXED)) == VUNSET) {
2390                        *vpp = vp->next;
2391                        free(vp);
2392 out_free:
2393                        if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE)
2394                                free(s);
2395                        goto out;
2396                }
2397
2398                flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
2399#if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS
2400                if (flags & VUNSET)
2401                        flags &= ~VDYNAMIC;
2402#endif
2403        } else {
2404                /* variable s is not found */
2405                if (flags & VNOSET)
2406                        goto out;
2407                if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
2408                        goto out_free;
2409                vp = ckzalloc(sizeof(*vp));
2410                vp->next = *vpp;
2411                /*vp->func = NULL; - ckzalloc did it */
2412                *vpp = vp;
2413        }
2414        if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
2415                s = ckstrdup(s);
2416        vp->var_text = s;
2417        vp->flags = flags;
2418
2419 out:
2420        return vp;
2421}
2422
2423/*
2424 * Set the value of a variable.  The flags argument is ored with the
2425 * flags of the variable.  If val is NULL, the variable is unset.
2426 */
2427static struct var *
2428setvar(const char *name, const char *val, int flags)
2429{
2430        const char *q;
2431        char *p;
2432        char *nameeq;
2433        size_t namelen;
2434        size_t vallen;
2435        struct var *vp;
2436
2437        q = endofname(name);
2438        p = strchrnul(q, '=');
2439        namelen = p - name;
2440        if (!namelen || p != q)
2441                ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
2442        vallen = 0;
2443        if (val == NULL) {
2444                flags |= VUNSET;
2445        } else {
2446                vallen = strlen(val);
2447        }
2448
2449        INT_OFF;
2450        nameeq = ckzalloc(namelen + vallen + 2);
2451        p = mempcpy(nameeq, name, namelen);
2452        if (val) {
2453                *p++ = '=';
2454                memcpy(p, val, vallen);
2455        }
2456        vp = setvareq(nameeq, flags | VNOSAVE);
2457        INT_ON;
2458
2459        return vp;
2460}
2461
2462static void FAST_FUNC
2463setvar0(const char *name, const char *val)
2464{
2465        setvar(name, val, 0);
2466}
2467
2468/*
2469 * Unset the specified variable.
2470 */
2471static void
2472unsetvar(const char *s)
2473{
2474        setvar(s, NULL, 0);
2475}
2476
2477/*
2478 * Process a linked list of variable assignments.
2479 */
2480static void
2481listsetvar(struct strlist *list_set_var, int flags)
2482{
2483        struct strlist *lp = list_set_var;
2484
2485        if (!lp)
2486                return;
2487        INT_OFF;
2488        do {
2489                setvareq(lp->text, flags);
2490                lp = lp->next;
2491        } while (lp);
2492        INT_ON;
2493}
2494
2495/*
2496 * Generate a list of variables satisfying the given conditions.
2497 */
2498#if !ENABLE_FEATURE_SH_NOFORK
2499# define listvars(on, off, lp, end) listvars(on, off, end)
2500#endif
2501static char **
2502listvars(int on, int off, struct strlist *lp, char ***end)
2503{
2504        struct var **vpp;
2505        struct var *vp;
2506        char **ep;
2507        int mask;
2508
2509        STARTSTACKSTR(ep);
2510        vpp = vartab;
2511        mask = on | off;
2512        do {
2513                for (vp = *vpp; vp; vp = vp->next) {
2514                        if ((vp->flags & mask) == on) {
2515#if ENABLE_FEATURE_SH_NOFORK
2516                                /* If variable with the same name is both
2517                                 * exported and temporarily set for a command:
2518                                 *  export ZVAR=5
2519                                 *  ZVAR=6 printenv
2520                                 * then "ZVAR=6" will be both in vartab and
2521                                 * lp lists. Do not pass it twice to printenv.
2522                                 */
2523                                struct strlist *lp1 = lp;
2524                                while (lp1) {
2525                                        if (strcmp(lp1->text, vp->var_text) == 0)
2526                                                goto skip;
2527                                        lp1 = lp1->next;
2528                                }
2529#endif
2530                                if (ep == stackstrend())
2531                                        ep = growstackstr();
2532                                *ep++ = (char*)vp->var_text;
2533#if ENABLE_FEATURE_SH_NOFORK
2534 skip: ;
2535#endif
2536                        }
2537                }
2538        } while (++vpp < vartab + VTABSIZE);
2539
2540#if ENABLE_FEATURE_SH_NOFORK
2541        while (lp) {
2542                if (ep == stackstrend())
2543                        ep = growstackstr();
2544                *ep++ = lp->text;
2545                lp = lp->next;
2546        }
2547#endif
2548
2549        if (ep == stackstrend())
2550                ep = growstackstr();
2551        if (end)
2552                *end = ep;
2553        *ep++ = NULL;
2554        return grabstackstr(ep);
2555}
2556
2557
2558/* ============ Path search helper
2559 *
2560 * The variable path (passed by reference) should be set to the start
2561 * of the path before the first call; path_advance will update
2562 * this value as it proceeds.  Successive calls to path_advance will return
2563 * the possible path expansions in sequence.  If an option (indicated by
2564 * a percent sign) appears in the path entry then the global variable
2565 * pathopt will be set to point to it; otherwise pathopt will be set to
2566 * NULL.
2567 */
2568static const char *pathopt;     /* set by path_advance */
2569
2570static char *
2571path_advance(const char **path, const char *name)
2572{
2573        const char *p;
2574        char *q;
2575        const char *start;
2576        size_t len;
2577
2578        if (*path == NULL)
2579                return NULL;
2580        start = *path;
2581        for (p = start; *p && *p != ':' && *p != '%'; p++)
2582                continue;
2583        len = p - start + strlen(name) + 2;     /* "2" is for '/' and '\0' */
2584        while (stackblocksize() < len)
2585                growstackblock();
2586        q = stackblock();
2587        if (p != start) {
2588                q = mempcpy(q, start, p - start);
2589                *q++ = '/';
2590        }
2591        strcpy(q, name);
2592        pathopt = NULL;
2593        if (*p == '%') {
2594                pathopt = ++p;
2595                while (*p && *p != ':')
2596                        p++;
2597        }
2598        if (*p == ':')
2599                *path = p + 1;
2600        else
2601                *path = NULL;
2602        return stalloc(len);
2603}
2604
2605
2606/* ============ Prompt */
2607
2608static smallint doprompt;                   /* if set, prompt the user */
2609static smallint needprompt;                 /* true if interactive and at start of line */
2610
2611#if ENABLE_FEATURE_EDITING
2612static line_input_t *line_input_state;
2613static const char *cmdedit_prompt;
2614static void
2615putprompt(const char *s)
2616{
2617        if (ENABLE_ASH_EXPAND_PRMT) {
2618                free((char*)cmdedit_prompt);
2619                cmdedit_prompt = ckstrdup(s);
2620                return;
2621        }
2622        cmdedit_prompt = s;
2623}
2624#else
2625static void
2626putprompt(const char *s)
2627{
2628        out2str(s);
2629}
2630#endif
2631
2632/* expandstr() needs parsing machinery, so it is far away ahead... */
2633static const char *expandstr(const char *ps, int syntax_type);
2634/* Values for syntax param */
2635#define BASESYNTAX 0    /* not in quotes */
2636#define DQSYNTAX   1    /* in double quotes */
2637#define SQSYNTAX   2    /* in single quotes */
2638#define ARISYNTAX  3    /* in arithmetic */
2639#if ENABLE_ASH_EXPAND_PRMT
2640# define PSSYNTAX  4    /* prompt. never passed to SIT() */
2641#endif
2642/* PSSYNTAX expansion is identical to DQSYNTAX, except keeping '\$' as '\$' */
2643
2644/*
2645 * called by editline -- any expansions to the prompt should be added here.
2646 */
2647static void
2648setprompt_if(smallint do_set, int whichprompt)
2649{
2650        const char *prompt;
2651        IF_ASH_EXPAND_PRMT(struct stackmark smark;)
2652
2653        if (!do_set)
2654                return;
2655
2656        needprompt = 0;
2657
2658        switch (whichprompt) {
2659        case 1:
2660                prompt = ps1val();
2661                break;
2662        case 2:
2663                prompt = ps2val();
2664                break;
2665        default:                        /* 0 */
2666                prompt = nullstr;
2667        }
2668#if ENABLE_ASH_EXPAND_PRMT
2669        pushstackmark(&smark, stackblocksize());
2670        putprompt(expandstr(prompt, PSSYNTAX));
2671        popstackmark(&smark);
2672#else
2673        putprompt(prompt);
2674#endif
2675}
2676
2677
2678/* ============ The cd and pwd commands */
2679
2680#define CD_PHYSICAL 1
2681#define CD_PRINT 2
2682
2683static int
2684cdopt(void)
2685{
2686        int flags = 0;
2687        int i, j;
2688
2689        j = 'L';
2690        while ((i = nextopt("LP")) != '\0') {
2691                if (i != j) {
2692                        flags ^= CD_PHYSICAL;
2693                        j = i;
2694                }
2695        }
2696
2697        return flags;
2698}
2699
2700/*
2701 * Update curdir (the name of the current directory) in response to a
2702 * cd command.
2703 */
2704static const char *
2705updatepwd(const char *dir)
2706{
2707        char *new;
2708        char *p;
2709        char *cdcomppath;
2710        const char *lim;
2711
2712        cdcomppath = sstrdup(dir);
2713        STARTSTACKSTR(new);
2714        if (*dir != '/') {
2715                if (curdir == nullstr)
2716                        return 0;
2717                new = stack_putstr(curdir, new);
2718        }
2719        new = makestrspace(strlen(dir) + 2, new);
2720        lim = (char *)stackblock() + 1;
2721        if (*dir != '/') {
2722                if (new[-1] != '/')
2723                        USTPUTC('/', new);
2724                if (new > lim && *lim == '/')
2725                        lim++;
2726        } else {
2727                USTPUTC('/', new);
2728                cdcomppath++;
2729                if (dir[1] == '/' && dir[2] != '/') {
2730                        USTPUTC('/', new);
2731                        cdcomppath++;
2732                        lim++;
2733                }
2734        }
2735        p = strtok(cdcomppath, "/");
2736        while (p) {
2737                switch (*p) {
2738                case '.':
2739                        if (p[1] == '.' && p[2] == '\0') {
2740                                while (new > lim) {
2741                                        STUNPUTC(new);
2742                                        if (new[-1] == '/')
2743                                                break;
2744                                }
2745                                break;
2746                        }
2747                        if (p[1] == '\0')
2748                                break;
2749                        /* fall through */
2750                default:
2751                        new = stack_putstr(p, new);
2752                        USTPUTC('/', new);
2753                }
2754                p = strtok(NULL, "/");
2755        }
2756        if (new > lim)
2757                STUNPUTC(new);
2758        *new = 0;
2759        return stackblock();
2760}
2761
2762/*
2763 * Find out what the current directory is. If we already know the current
2764 * directory, this routine returns immediately.
2765 */
2766static char *
2767getpwd(void)
2768{
2769        char *dir = getcwd(NULL, 0); /* huh, using glibc extension? */
2770        return dir ? dir : nullstr;
2771}
2772
2773static void
2774setpwd(const char *val, int setold)
2775{
2776        char *oldcur, *dir;
2777
2778        oldcur = dir = curdir;
2779
2780        if (setold) {
2781                setvar("OLDPWD", oldcur, VEXPORT);
2782        }
2783        INT_OFF;
2784        if (physdir != nullstr) {
2785                if (physdir != oldcur)
2786                        free(physdir);
2787                physdir = nullstr;
2788        }
2789        if (oldcur == val || !val) {
2790                char *s = getpwd();
2791                physdir = s;
2792                if (!val)
2793                        dir = s;
2794        } else
2795                dir = ckstrdup(val);
2796        if (oldcur != dir && oldcur != nullstr) {
2797                free(oldcur);
2798        }
2799        curdir = dir;
2800        INT_ON;
2801        setvar("PWD", dir, VEXPORT);
2802}
2803
2804static void hashcd(void);
2805
2806/*
2807 * Actually do the chdir.  We also call hashcd to let other routines
2808 * know that the current directory has changed.
2809 */
2810static int
2811docd(const char *dest, int flags)
2812{
2813        const char *dir = NULL;
2814        int err;
2815
2816        TRACE(("docd(\"%s\", %d) called\n", dest, flags));
2817
2818        INT_OFF;
2819        if (!(flags & CD_PHYSICAL)) {
2820                dir = updatepwd(dest);
2821                if (dir)
2822                        dest = dir;
2823        }
2824        err = chdir(dest);
2825        if (err)
2826                goto out;
2827        setpwd(dir, 1);
2828        hashcd();
2829 out:
2830        INT_ON;
2831        return err;
2832}
2833
2834static int FAST_FUNC
2835cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2836{
2837        const char *dest;
2838        const char *path;
2839        const char *p;
2840        char c;
2841        struct stat statb;
2842        int flags;
2843
2844        flags = cdopt();
2845        dest = *argptr;
2846        if (!dest)
2847                dest = bltinlookup("HOME");
2848        else if (LONE_DASH(dest)) {
2849                dest = bltinlookup("OLDPWD");
2850                flags |= CD_PRINT;
2851        }
2852        if (!dest)
2853                dest = nullstr;
2854        if (*dest == '/')
2855                goto step6;
2856        if (*dest == '.') {
2857                c = dest[1];
2858 dotdot:
2859                switch (c) {
2860                case '\0':
2861                case '/':
2862                        goto step6;
2863                case '.':
2864                        c = dest[2];
2865                        if (c != '.')
2866                                goto dotdot;
2867                }
2868        }
2869        if (!*dest)
2870                dest = ".";
2871        path = bltinlookup("CDPATH");
2872        while (path) {
2873                c = *path;
2874                p = path_advance(&path, dest);
2875                if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2876                        if (c && c != ':')
2877                                flags |= CD_PRINT;
2878 docd:
2879                        if (!docd(p, flags))
2880                                goto out;
2881                        goto err;
2882                }
2883        }
2884
2885 step6:
2886        p = dest;
2887        goto docd;
2888
2889 err:
2890        ash_msg_and_raise_perror("can't cd to %s", dest);
2891        /* NOTREACHED */
2892 out:
2893        if (flags & CD_PRINT)
2894                out1fmt("%s\n", curdir);
2895        return 0;
2896}
2897
2898static int FAST_FUNC
2899pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2900{
2901        int flags;
2902        const char *dir = curdir;
2903
2904        flags = cdopt();
2905        if (flags) {
2906                if (physdir == nullstr)
2907                        setpwd(dir, 0);
2908                dir = physdir;
2909        }
2910        out1fmt("%s\n", dir);
2911        return 0;
2912}
2913
2914
2915/* ============ ... */
2916
2917
2918#define IBUFSIZ (ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 1024)
2919
2920/* Syntax classes */
2921#define CWORD     0             /* character is nothing special */
2922#define CNL       1             /* newline character */
2923#define CBACK     2             /* a backslash character */
2924#define CSQUOTE   3             /* single quote */
2925#define CDQUOTE   4             /* double quote */
2926#define CENDQUOTE 5             /* a terminating quote */
2927#define CBQUOTE   6             /* backwards single quote */
2928#define CVAR      7             /* a dollar sign */
2929#define CENDVAR   8             /* a '}' character */
2930#define CLP       9             /* a left paren in arithmetic */
2931#define CRP      10             /* a right paren in arithmetic */
2932#define CENDFILE 11             /* end of file */
2933#define CCTL     12             /* like CWORD, except it must be escaped */
2934#define CSPCL    13             /* these terminate a word */
2935#define CIGN     14             /* character should be ignored */
2936
2937#define PEOF     256
2938#if ENABLE_ASH_ALIAS
2939# define PEOA    257
2940#endif
2941
2942#define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE
2943
2944#if ENABLE_FEATURE_SH_MATH
2945# define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12))
2946#else
2947# define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8))
2948#endif
2949static const uint16_t S_I_T[] ALIGN2 = {
2950#if ENABLE_ASH_ALIAS
2951        SIT_ITEM(CSPCL   , CIGN     , CIGN , CIGN   ),    /* 0, PEOA */
2952#endif
2953        SIT_ITEM(CSPCL   , CWORD    , CWORD, CWORD  ),    /* 1, ' ' */
2954        SIT_ITEM(CNL     , CNL      , CNL  , CNL    ),    /* 2, \n */
2955        SIT_ITEM(CWORD   , CCTL     , CCTL , CWORD  ),    /* 3, !*-/:=?[]~ */
2956        SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD  ),    /* 4, '"' */
2957        SIT_ITEM(CVAR    , CVAR     , CWORD, CVAR   ),    /* 5, $ */
2958        SIT_ITEM(CSQUOTE , CWORD    , CENDQUOTE, CWORD),  /* 6, "'" */
2959        SIT_ITEM(CSPCL   , CWORD    , CWORD, CLP    ),    /* 7, ( */
2960        SIT_ITEM(CSPCL   , CWORD    , CWORD, CRP    ),    /* 8, ) */
2961        SIT_ITEM(CBACK   , CBACK    , CCTL , CBACK  ),    /* 9, \ */
2962        SIT_ITEM(CBQUOTE , CBQUOTE  , CWORD, CBQUOTE),    /* 10, ` */
2963        SIT_ITEM(CENDVAR , CENDVAR  , CWORD, CENDVAR),    /* 11, } */
2964#if !USE_SIT_FUNCTION
2965        SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 12, PEOF */
2966        SIT_ITEM(CWORD   , CWORD    , CWORD, CWORD  ),    /* 13, 0-9A-Za-z */
2967        SIT_ITEM(CCTL    , CCTL     , CCTL , CCTL   )     /* 14, CTLESC ... */
2968#endif
2969#undef SIT_ITEM
2970};
2971/* Constants below must match table above */
2972enum {
2973#if ENABLE_ASH_ALIAS
2974        CSPCL_CIGN_CIGN_CIGN               , /*  0 */
2975#endif
2976        CSPCL_CWORD_CWORD_CWORD            , /*  1 */
2977        CNL_CNL_CNL_CNL                    , /*  2 */
2978        CWORD_CCTL_CCTL_CWORD              , /*  3 */
2979        CDQUOTE_CENDQUOTE_CWORD_CWORD      , /*  4 */
2980        CVAR_CVAR_CWORD_CVAR               , /*  5 */
2981        CSQUOTE_CWORD_CENDQUOTE_CWORD      , /*  6 */
2982        CSPCL_CWORD_CWORD_CLP              , /*  7 */
2983        CSPCL_CWORD_CWORD_CRP              , /*  8 */
2984        CBACK_CBACK_CCTL_CBACK             , /*  9 */
2985        CBQUOTE_CBQUOTE_CWORD_CBQUOTE      , /* 10 */
2986        CENDVAR_CENDVAR_CWORD_CENDVAR      , /* 11 */
2987        CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 12 */
2988        CWORD_CWORD_CWORD_CWORD            , /* 13 */
2989        CCTL_CCTL_CCTL_CCTL                , /* 14 */
2990};
2991
2992/* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF,
2993 * caller must ensure proper cast on it if c is *char_ptr!
2994 */
2995#if USE_SIT_FUNCTION
2996
2997static int
2998SIT(int c, int syntax)
2999{
3000        /* Used to also have '/' in this string: "\t\n !\"$&'()*-/:;<=>?[\\]`|}~" */
3001        static const char spec_symbls[] ALIGN1 = "\t\n !\"$&'()*-:;<=>?[\\]`|}~";
3002        /*
3003         * This causes '/' to be prepended with CTLESC in dquoted string,
3004         * making "./file"* treated incorrectly because we feed
3005         * ".\/file*" string to glob(), confusing it (see expandmeta func).
3006         * The "homegrown" glob implementation is okay with that,
3007         * but glibc one isn't. With '/' always treated as CWORD,
3008         * both work fine.
3009         */
3010# if ENABLE_ASH_ALIAS
3011        static const uint8_t syntax_index_table[] ALIGN1 = {
3012                1, 2, 1, 3, 4, 5, 1, 6,         /* "\t\n !\"$&'" */
3013                7, 8, 3, 3,/*3,*/3, 1, 1,       /* "()*-/:;<" */
3014                3, 1, 3, 3, 9, 3, 10, 1,        /* "=>?[\\]`|" */
3015                11, 3                           /* "}~" */
3016        };
3017# else
3018        static const uint8_t syntax_index_table[] ALIGN1 = {
3019                0, 1, 0, 2, 3, 4, 0, 5,         /* "\t\n !\"$&'" */
3020                6, 7, 2, 2,/*2,*/2, 0, 0,       /* "()*-/:;<" */
3021                2, 0, 2, 2, 8, 2, 9, 0,         /* "=>?[\\]`|" */
3022                10, 2                           /* "}~" */
3023        };
3024# endif
3025        const char *s;
3026        int indx;
3027
3028        if (c == PEOF)
3029                return CENDFILE;
3030# if ENABLE_ASH_ALIAS
3031        if (c == PEOA)
3032                indx = 0;
3033        else
3034# endif
3035        {
3036                /* Cast is purely for paranoia here,
3037                 * just in case someone passed signed char to us */
3038                if ((unsigned char)c >= CTL_FIRST
3039                 && (unsigned char)c <= CTL_LAST
3040                ) {
3041                        return CCTL;
3042                }
3043                s = strchrnul(spec_symbls, c);
3044                if (*s == '\0')
3045                        return CWORD;
3046                indx = syntax_index_table[s - spec_symbls];
3047        }
3048        return (S_I_T[indx] >> (syntax*4)) & 0xf;
3049}
3050
3051#else   /* !USE_SIT_FUNCTION */
3052
3053static const uint8_t syntax_index_table[] ALIGN1 = {
3054        /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
3055        /*   0      */ CWORD_CWORD_CWORD_CWORD,
3056        /*   1      */ CWORD_CWORD_CWORD_CWORD,
3057        /*   2      */ CWORD_CWORD_CWORD_CWORD,
3058        /*   3      */ CWORD_CWORD_CWORD_CWORD,
3059        /*   4      */ CWORD_CWORD_CWORD_CWORD,
3060        /*   5      */ CWORD_CWORD_CWORD_CWORD,
3061        /*   6      */ CWORD_CWORD_CWORD_CWORD,
3062        /*   7      */ CWORD_CWORD_CWORD_CWORD,
3063        /*   8      */ CWORD_CWORD_CWORD_CWORD,
3064        /*   9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
3065        /*  10 "\n" */ CNL_CNL_CNL_CNL,
3066        /*  11      */ CWORD_CWORD_CWORD_CWORD,
3067        /*  12      */ CWORD_CWORD_CWORD_CWORD,
3068        /*  13      */ CWORD_CWORD_CWORD_CWORD,
3069        /*  14      */ CWORD_CWORD_CWORD_CWORD,
3070        /*  15      */ CWORD_CWORD_CWORD_CWORD,
3071        /*  16      */ CWORD_CWORD_CWORD_CWORD,
3072        /*  17      */ CWORD_CWORD_CWORD_CWORD,
3073        /*  18      */ CWORD_CWORD_CWORD_CWORD,
3074        /*  19      */ CWORD_CWORD_CWORD_CWORD,
3075        /*  20      */ CWORD_CWORD_CWORD_CWORD,
3076        /*  21      */ CWORD_CWORD_CWORD_CWORD,
3077        /*  22      */ CWORD_CWORD_CWORD_CWORD,
3078        /*  23      */ CWORD_CWORD_CWORD_CWORD,
3079        /*  24      */ CWORD_CWORD_CWORD_CWORD,
3080        /*  25      */ CWORD_CWORD_CWORD_CWORD,
3081        /*  26      */ CWORD_CWORD_CWORD_CWORD,
3082        /*  27      */ CWORD_CWORD_CWORD_CWORD,
3083        /*  28      */ CWORD_CWORD_CWORD_CWORD,
3084        /*  29      */ CWORD_CWORD_CWORD_CWORD,
3085        /*  30      */ CWORD_CWORD_CWORD_CWORD,
3086        /*  31      */ CWORD_CWORD_CWORD_CWORD,
3087        /*  32  " " */ CSPCL_CWORD_CWORD_CWORD,
3088        /*  33  "!" */ CWORD_CCTL_CCTL_CWORD,
3089        /*  34  """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
3090        /*  35  "#" */ CWORD_CWORD_CWORD_CWORD,
3091        /*  36  "$" */ CVAR_CVAR_CWORD_CVAR,
3092        /*  37  "%" */ CWORD_CWORD_CWORD_CWORD,
3093        /*  38  "&" */ CSPCL_CWORD_CWORD_CWORD,
3094        /*  39  "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
3095        /*  40  "(" */ CSPCL_CWORD_CWORD_CLP,
3096        /*  41  ")" */ CSPCL_CWORD_CWORD_CRP,
3097        /*  42  "*" */ CWORD_CCTL_CCTL_CWORD,
3098        /*  43  "+" */ CWORD_CWORD_CWORD_CWORD,
3099        /*  44  "," */ CWORD_CWORD_CWORD_CWORD,
3100        /*  45  "-" */ CWORD_CCTL_CCTL_CWORD,
3101        /*  46  "." */ CWORD_CWORD_CWORD_CWORD,
3102/* "/" was CWORD_CCTL_CCTL_CWORD, see comment in SIT() function why this is changed: */
3103        /*  47  "/" */ CWORD_CWORD_CWORD_CWORD,
3104        /*  48  "0" */ CWORD_CWORD_CWORD_CWORD,
3105        /*  49  "1" */ CWORD_CWORD_CWORD_CWORD,
3106        /*  50  "2" */ CWORD_CWORD_CWORD_CWORD,
3107        /*  51  "3" */ CWORD_CWORD_CWORD_CWORD,
3108        /*  52  "4" */ CWORD_CWORD_CWORD_CWORD,
3109        /*  53  "5" */ CWORD_CWORD_CWORD_CWORD,
3110        /*  54  "6" */ CWORD_CWORD_CWORD_CWORD,
3111        /*  55  "7" */ CWORD_CWORD_CWORD_CWORD,
3112        /*  56  "8" */ CWORD_CWORD_CWORD_CWORD,
3113        /*  57  "9" */ CWORD_CWORD_CWORD_CWORD,
3114        /*  58  ":" */ CWORD_CCTL_CCTL_CWORD,
3115        /*  59  ";" */ CSPCL_CWORD_CWORD_CWORD,
3116        /*  60  "<" */ CSPCL_CWORD_CWORD_CWORD,
3117        /*  61  "=" */ CWORD_CCTL_CCTL_CWORD,
3118        /*  62  ">" */ CSPCL_CWORD_CWORD_CWORD,
3119        /*  63  "?" */ CWORD_CCTL_CCTL_CWORD,
3120        /*  64  "@" */ CWORD_CWORD_CWORD_CWORD,
3121        /*  65  "A" */ CWORD_CWORD_CWORD_CWORD,
3122        /*  66  "B" */ CWORD_CWORD_CWORD_CWORD,
3123        /*  67  "C" */ CWORD_CWORD_CWORD_CWORD,
3124        /*  68  "D" */ CWORD_CWORD_CWORD_CWORD,
3125        /*  69  "E" */ CWORD_CWORD_CWORD_CWORD,
3126        /*  70  "F" */ CWORD_CWORD_CWORD_CWORD,
3127        /*  71  "G" */ CWORD_CWORD_CWORD_CWORD,
3128        /*  72  "H" */ CWORD_CWORD_CWORD_CWORD,
3129        /*  73  "I" */ CWORD_CWORD_CWORD_CWORD,
3130        /*  74  "J" */ CWORD_CWORD_CWORD_CWORD,
3131        /*  75  "K" */ CWORD_CWORD_CWORD_CWORD,
3132        /*  76  "L" */ CWORD_CWORD_CWORD_CWORD,
3133        /*  77  "M" */ CWORD_CWORD_CWORD_CWORD,
3134        /*  78  "N" */ CWORD_CWORD_CWORD_CWORD,
3135        /*  79  "O" */ CWORD_CWORD_CWORD_CWORD,
3136        /*  80  "P" */ CWORD_CWORD_CWORD_CWORD,
3137        /*  81  "Q" */ CWORD_CWORD_CWORD_CWORD,
3138        /*  82  "R" */ CWORD_CWORD_CWORD_CWORD,
3139        /*  83  "S" */ CWORD_CWORD_CWORD_CWORD,
3140        /*  84  "T" */ CWORD_CWORD_CWORD_CWORD,
3141        /*  85  "U" */ CWORD_CWORD_CWORD_CWORD,
3142        /*  86  "V" */ CWORD_CWORD_CWORD_CWORD,
3143        /*  87  "W" */ CWORD_CWORD_CWORD_CWORD,
3144        /*  88  "X" */ CWORD_CWORD_CWORD_CWORD,
3145        /*  89  "Y" */ CWORD_CWORD_CWORD_CWORD,
3146        /*  90  "Z" */ CWORD_CWORD_CWORD_CWORD,
3147        /*  91  "[" */ CWORD_CCTL_CCTL_CWORD,
3148        /*  92  "\" */ CBACK_CBACK_CCTL_CBACK,
3149        /*  93  "]" */ CWORD_CCTL_CCTL_CWORD,
3150        /*  94  "^" */ CWORD_CWORD_CWORD_CWORD,
3151        /*  95  "_" */ CWORD_CWORD_CWORD_CWORD,
3152        /*  96  "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
3153        /*  97  "a" */ CWORD_CWORD_CWORD_CWORD,
3154        /*  98  "b" */ CWORD_CWORD_CWORD_CWORD,
3155        /*  99  "c" */ CWORD_CWORD_CWORD_CWORD,
3156        /* 100  "d" */ CWORD_CWORD_CWORD_CWORD,
3157        /* 101  "e" */ CWORD_CWORD_CWORD_CWORD,
3158        /* 102  "f" */ CWORD_CWORD_CWORD_CWORD,
3159        /* 103  "g" */ CWORD_CWORD_CWORD_CWORD,
3160        /* 104  "h" */ CWORD_CWORD_CWORD_CWORD,
3161        /* 105  "i" */ CWORD_CWORD_CWORD_CWORD,
3162        /* 106  "j" */ CWORD_CWORD_CWORD_CWORD,
3163        /* 107  "k" */ CWORD_CWORD_CWORD_CWORD,
3164        /* 108  "l" */ CWORD_CWORD_CWORD_CWORD,
3165        /* 109  "m" */ CWORD_CWORD_CWORD_CWORD,
3166        /* 110  "n" */ CWORD_CWORD_CWORD_CWORD,
3167        /* 111  "o" */ CWORD_CWORD_CWORD_CWORD,
3168        /* 112  "p" */ CWORD_CWORD_CWORD_CWORD,
3169        /* 113  "q" */ CWORD_CWORD_CWORD_CWORD,
3170        /* 114  "r" */ CWORD_CWORD_CWORD_CWORD,
3171        /* 115  "s" */ CWORD_CWORD_CWORD_CWORD,
3172        /* 116  "t" */ CWORD_CWORD_CWORD_CWORD,
3173        /* 117  "u" */ CWORD_CWORD_CWORD_CWORD,
3174        /* 118  "v" */ CWORD_CWORD_CWORD_CWORD,
3175        /* 119  "w" */ CWORD_CWORD_CWORD_CWORD,
3176        /* 120  "x" */ CWORD_CWORD_CWORD_CWORD,
3177        /* 121  "y" */ CWORD_CWORD_CWORD_CWORD,
3178        /* 122  "z" */ CWORD_CWORD_CWORD_CWORD,
3179        /* 123  "{" */ CWORD_CWORD_CWORD_CWORD,
3180        /* 124  "|" */ CSPCL_CWORD_CWORD_CWORD,
3181        /* 125  "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
3182        /* 126  "~" */ CWORD_CCTL_CCTL_CWORD,
3183        /* 127  del */ CWORD_CWORD_CWORD_CWORD,
3184        /* 128 0x80 */ CWORD_CWORD_CWORD_CWORD,
3185        /* 129 CTLESC       */ CCTL_CCTL_CCTL_CCTL,
3186        /* 130 CTLVAR       */ CCTL_CCTL_CCTL_CCTL,
3187        /* 131 CTLENDVAR    */ CCTL_CCTL_CCTL_CCTL,
3188        /* 132 CTLBACKQ     */ CCTL_CCTL_CCTL_CCTL,
3189        /* 133 CTLQUOTE     */ CCTL_CCTL_CCTL_CCTL,
3190        /* 134 CTLARI       */ CCTL_CCTL_CCTL_CCTL,
3191        /* 135 CTLENDARI    */ CCTL_CCTL_CCTL_CCTL,
3192        /* 136 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
3193        /* 137      */ CWORD_CWORD_CWORD_CWORD,
3194        /* 138      */ CWORD_CWORD_CWORD_CWORD,
3195        /* 139      */ CWORD_CWORD_CWORD_CWORD,
3196        /* 140      */ CWORD_CWORD_CWORD_CWORD,
3197        /* 141      */ CWORD_CWORD_CWORD_CWORD,
3198        /* 142      */ CWORD_CWORD_CWORD_CWORD,
3199        /* 143      */ CWORD_CWORD_CWORD_CWORD,
3200        /* 144      */ CWORD_CWORD_CWORD_CWORD,
3201        /* 145      */ CWORD_CWORD_CWORD_CWORD,
3202        /* 146      */ CWORD_CWORD_CWORD_CWORD,
3203        /* 147      */ CWORD_CWORD_CWORD_CWORD,
3204        /* 148      */ CWORD_CWORD_CWORD_CWORD,
3205        /* 149      */ CWORD_CWORD_CWORD_CWORD,
3206        /* 150      */ CWORD_CWORD_CWORD_CWORD,
3207        /* 151      */ CWORD_CWORD_CWORD_CWORD,
3208        /* 152      */ CWORD_CWORD_CWORD_CWORD,
3209        /* 153      */ CWORD_CWORD_CWORD_CWORD,
3210        /* 154      */ CWORD_CWORD_CWORD_CWORD,
3211        /* 155      */ CWORD_CWORD_CWORD_CWORD,
3212        /* 156      */ CWORD_CWORD_CWORD_CWORD,
3213        /* 157      */ CWORD_CWORD_CWORD_CWORD,
3214        /* 158      */ CWORD_CWORD_CWORD_CWORD,
3215        /* 159      */ CWORD_CWORD_CWORD_CWORD,
3216        /* 160      */ CWORD_CWORD_CWORD_CWORD,
3217        /* 161      */ CWORD_CWORD_CWORD_CWORD,
3218        /* 162      */ CWORD_CWORD_CWORD_CWORD,
3219        /* 163      */ CWORD_CWORD_CWORD_CWORD,
3220        /* 164      */ CWORD_CWORD_CWORD_CWORD,
3221        /* 165      */ CWORD_CWORD_CWORD_CWORD,
3222        /* 166      */ CWORD_CWORD_CWORD_CWORD,
3223        /* 167      */ CWORD_CWORD_CWORD_CWORD,
3224        /* 168      */ CWORD_CWORD_CWORD_CWORD,
3225        /* 169      */ CWORD_CWORD_CWORD_CWORD,
3226        /* 170      */ CWORD_CWORD_CWORD_CWORD,
3227        /* 171      */ CWORD_CWORD_CWORD_CWORD,
3228        /* 172      */ CWORD_CWORD_CWORD_CWORD,
3229        /* 173      */ CWORD_CWORD_CWORD_CWORD,
3230        /* 174      */ CWORD_CWORD_CWORD_CWORD,
3231        /* 175      */ CWORD_CWORD_CWORD_CWORD,
3232        /* 176      */ CWORD_CWORD_CWORD_CWORD,
3233        /* 177      */ CWORD_CWORD_CWORD_CWORD,
3234        /* 178      */ CWORD_CWORD_CWORD_CWORD,
3235        /* 179      */ CWORD_CWORD_CWORD_CWORD,
3236        /* 180      */ CWORD_CWORD_CWORD_CWORD,
3237        /* 181      */ CWORD_CWORD_CWORD_CWORD,
3238        /* 182      */ CWORD_CWORD_CWORD_CWORD,
3239        /* 183      */ CWORD_CWORD_CWORD_CWORD,
3240        /* 184      */ CWORD_CWORD_CWORD_CWORD,
3241        /* 185      */ CWORD_CWORD_CWORD_CWORD,
3242        /* 186      */ CWORD_CWORD_CWORD_CWORD,
3243        /* 187      */ CWORD_CWORD_CWORD_CWORD,
3244        /* 188      */ CWORD_CWORD_CWORD_CWORD,
3245        /* 189      */ CWORD_CWORD_CWORD_CWORD,
3246        /* 190      */ CWORD_CWORD_CWORD_CWORD,
3247        /* 191      */ CWORD_CWORD_CWORD_CWORD,
3248        /* 192      */ CWORD_CWORD_CWORD_CWORD,
3249        /* 193      */ CWORD_CWORD_CWORD_CWORD,
3250        /* 194      */ CWORD_CWORD_CWORD_CWORD,
3251        /* 195      */ CWORD_CWORD_CWORD_CWORD,
3252        /* 196      */ CWORD_CWORD_CWORD_CWORD,
3253        /* 197      */ CWORD_CWORD_CWORD_CWORD,
3254        /* 198      */ CWORD_CWORD_CWORD_CWORD,
3255        /* 199      */ CWORD_CWORD_CWORD_CWORD,
3256        /* 200      */ CWORD_CWORD_CWORD_CWORD,
3257        /* 201      */ CWORD_CWORD_CWORD_CWORD,
3258        /* 202      */ CWORD_CWORD_CWORD_CWORD,
3259        /* 203      */ CWORD_CWORD_CWORD_CWORD,
3260        /* 204      */ CWORD_CWORD_CWORD_CWORD,
3261        /* 205      */ CWORD_CWORD_CWORD_CWORD,
3262        /* 206      */ CWORD_CWORD_CWORD_CWORD,
3263        /* 207      */ CWORD_CWORD_CWORD_CWORD,
3264        /* 208      */ CWORD_CWORD_CWORD_CWORD,
3265        /* 209      */ CWORD_CWORD_CWORD_CWORD,
3266        /* 210      */ CWORD_CWORD_CWORD_CWORD,
3267        /* 211      */ CWORD_CWORD_CWORD_CWORD,
3268        /* 212      */ CWORD_CWORD_CWORD_CWORD,
3269        /* 213      */ CWORD_CWORD_CWORD_CWORD,
3270        /* 214      */ CWORD_CWORD_CWORD_CWORD,
3271        /* 215      */ CWORD_CWORD_CWORD_CWORD,
3272        /* 216      */ CWORD_CWORD_CWORD_CWORD,
3273        /* 217      */ CWORD_CWORD_CWORD_CWORD,
3274        /* 218      */ CWORD_CWORD_CWORD_CWORD,
3275        /* 219      */ CWORD_CWORD_CWORD_CWORD,
3276        /* 220      */ CWORD_CWORD_CWORD_CWORD,
3277        /* 221      */ CWORD_CWORD_CWORD_CWORD,
3278        /* 222      */ CWORD_CWORD_CWORD_CWORD,
3279        /* 223      */ CWORD_CWORD_CWORD_CWORD,
3280        /* 224      */ CWORD_CWORD_CWORD_CWORD,
3281        /* 225      */ CWORD_CWORD_CWORD_CWORD,
3282        /* 226      */ CWORD_CWORD_CWORD_CWORD,
3283        /* 227      */ CWORD_CWORD_CWORD_CWORD,
3284        /* 228      */ CWORD_CWORD_CWORD_CWORD,
3285        /* 229      */ CWORD_CWORD_CWORD_CWORD,
3286        /* 230      */ CWORD_CWORD_CWORD_CWORD,
3287        /* 231      */ CWORD_CWORD_CWORD_CWORD,
3288        /* 232      */ CWORD_CWORD_CWORD_CWORD,
3289        /* 233      */ CWORD_CWORD_CWORD_CWORD,
3290        /* 234      */ CWORD_CWORD_CWORD_CWORD,
3291        /* 235      */ CWORD_CWORD_CWORD_CWORD,
3292        /* 236      */ CWORD_CWORD_CWORD_CWORD,
3293        /* 237      */ CWORD_CWORD_CWORD_CWORD,
3294        /* 238      */ CWORD_CWORD_CWORD_CWORD,
3295        /* 239      */ CWORD_CWORD_CWORD_CWORD,
3296        /* 230      */ CWORD_CWORD_CWORD_CWORD,
3297        /* 241      */ CWORD_CWORD_CWORD_CWORD,
3298        /* 242      */ CWORD_CWORD_CWORD_CWORD,
3299        /* 243      */ CWORD_CWORD_CWORD_CWORD,
3300        /* 244      */ CWORD_CWORD_CWORD_CWORD,
3301        /* 245      */ CWORD_CWORD_CWORD_CWORD,
3302        /* 246      */ CWORD_CWORD_CWORD_CWORD,
3303        /* 247      */ CWORD_CWORD_CWORD_CWORD,
3304        /* 248      */ CWORD_CWORD_CWORD_CWORD,
3305        /* 249      */ CWORD_CWORD_CWORD_CWORD,
3306        /* 250      */ CWORD_CWORD_CWORD_CWORD,
3307        /* 251      */ CWORD_CWORD_CWORD_CWORD,
3308        /* 252      */ CWORD_CWORD_CWORD_CWORD,
3309        /* 253      */ CWORD_CWORD_CWORD_CWORD,
3310        /* 254      */ CWORD_CWORD_CWORD_CWORD,
3311        /* 255      */ CWORD_CWORD_CWORD_CWORD,
3312        /* PEOF */     CENDFILE_CENDFILE_CENDFILE_CENDFILE,
3313# if ENABLE_ASH_ALIAS
3314        /* PEOA */     CSPCL_CIGN_CIGN_CIGN,
3315# endif
3316};
3317
3318#if 1
3319# define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf)
3320#else /* debug version, caught one signed char bug */
3321# define SIT(c, syntax) \
3322        ({ \
3323                if ((c) < 0 || (c) > (PEOF + ENABLE_ASH_ALIAS)) \
3324                        bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3325                if ((syntax) < 0 || (syntax) > (2 + ENABLE_FEATURE_SH_MATH)) \
3326                        bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3327                ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf); \
3328        })
3329#endif
3330
3331#endif  /* !USE_SIT_FUNCTION */
3332
3333
3334/* ============ Alias handling */
3335
3336#if ENABLE_ASH_ALIAS
3337
3338#define ALIASINUSE 1
3339#define ALIASDEAD  2
3340
3341struct alias {
3342        struct alias *next;
3343        char *name;
3344        char *val;
3345        int flag;
3346};
3347
3348
3349static struct alias **atab; // [ATABSIZE];
3350#define INIT_G_alias() do { \
3351        atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
3352} while (0)
3353
3354
3355static struct alias **
3356__lookupalias(const char *name)
3357{
3358        unsigned int hashval;
3359        struct alias **app;
3360        const char *p;
3361        unsigned int ch;
3362
3363        p = name;
3364
3365        ch = (unsigned char)*p;
3366        hashval = ch << 4;
3367        while (ch) {
3368                hashval += ch;
3369                ch = (unsigned char)*++p;
3370        }
3371        app = &atab[hashval % ATABSIZE];
3372
3373        for (; *app; app = &(*app)->next) {
3374                if (strcmp(name, (*app)->name) == 0) {
3375                        break;
3376                }
3377        }
3378
3379        return app;
3380}
3381
3382static struct alias *
3383lookupalias(const char *name, int check)
3384{
3385        struct alias *ap = *__lookupalias(name);
3386
3387        if (check && ap && (ap->flag & ALIASINUSE))
3388                return NULL;
3389        return ap;
3390}
3391
3392static struct alias *
3393freealias(struct alias *ap)
3394{
3395        struct alias *next;
3396
3397        if (ap->flag & ALIASINUSE) {
3398                ap->flag |= ALIASDEAD;
3399                return ap;
3400        }
3401
3402        next = ap->next;
3403        free(ap->name);
3404        free(ap->val);
3405        free(ap);
3406        return next;
3407}
3408
3409static void
3410setalias(const char *name, const char *val)
3411{
3412        struct alias *ap, **app;
3413
3414        app = __lookupalias(name);
3415        ap = *app;
3416        INT_OFF;
3417        if (ap) {
3418                if (!(ap->flag & ALIASINUSE)) {
3419                        free(ap->val);
3420                }
3421                ap->val = ckstrdup(val);
3422                ap->flag &= ~ALIASDEAD;
3423        } else {
3424                /* not found */
3425                ap = ckzalloc(sizeof(struct alias));
3426                ap->name = ckstrdup(name);
3427                ap->val = ckstrdup(val);
3428                /*ap->flag = 0; - ckzalloc did it */
3429                /*ap->next = NULL;*/
3430                *app = ap;
3431        }
3432        INT_ON;
3433}
3434
3435static int
3436unalias(const char *name)
3437{
3438        struct alias **app;
3439
3440        app = __lookupalias(name);
3441
3442        if (*app) {
3443                INT_OFF;
3444                *app = freealias(*app);
3445                INT_ON;
3446                return 0;
3447        }
3448
3449        return 1;
3450}
3451
3452static void
3453rmaliases(void)
3454{
3455        struct alias *ap, **app;
3456        int i;
3457
3458        INT_OFF;
3459        for (i = 0; i < ATABSIZE; i++) {
3460                app = &atab[i];
3461                for (ap = *app; ap; ap = *app) {
3462                        *app = freealias(*app);
3463                        if (ap == *app) {
3464                                app = &ap->next;
3465                        }
3466                }
3467        }
3468        INT_ON;
3469}
3470
3471static void
3472printalias(const struct alias *ap)
3473{
3474        out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3475}
3476
3477/*
3478 * TODO - sort output
3479 */
3480static int FAST_FUNC
3481aliascmd(int argc UNUSED_PARAM, char **argv)
3482{
3483        char *n, *v;
3484        int ret = 0;
3485        struct alias *ap;
3486
3487        if (!argv[1]) {
3488                int i;
3489
3490                for (i = 0; i < ATABSIZE; i++) {
3491                        for (ap = atab[i]; ap; ap = ap->next) {
3492                                printalias(ap);
3493                        }
3494                }
3495                return 0;
3496        }
3497        while ((n = *++argv) != NULL) {
3498                v = strchr(n+1, '=');
3499                if (v == NULL) { /* n+1: funny ksh stuff */
3500                        ap = *__lookupalias(n);
3501                        if (ap == NULL) {
3502                                fprintf(stderr, "%s: %s not found\n", "alias", n);
3503                                ret = 1;
3504                        } else
3505                                printalias(ap);
3506                } else {
3507                        *v++ = '\0';
3508                        setalias(n, v);
3509                }
3510        }
3511
3512        return ret;
3513}
3514
3515static int FAST_FUNC
3516unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
3517{
3518        int i;
3519
3520        while (nextopt("a") != '\0') {
3521                rmaliases();
3522                return 0;
3523        }
3524        for (i = 0; *argptr; argptr++) {
3525                if (unalias(*argptr)) {
3526                        fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
3527                        i = 1;
3528                }
3529        }
3530
3531        return i;
3532}
3533
3534#endif /* ASH_ALIAS */
3535
3536
3537/* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
3538#define FORK_FG    0
3539#define FORK_BG    1
3540#define FORK_NOJOB 2
3541
3542/* mode flags for showjob(s) */
3543#define SHOW_ONLY_PGID  0x01    /* show only pgid (jobs -p) */
3544#define SHOW_PIDS       0x02    /* show individual pids, not just one line per job */
3545#define SHOW_CHANGED    0x04    /* only jobs whose state has changed */
3546#define SHOW_STDERR     0x08    /* print to stderr (else stdout) */
3547
3548/*
3549 * A job structure contains information about a job.  A job is either a
3550 * single process or a set of processes contained in a pipeline.  In the
3551 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
3552 * array of pids.
3553 */
3554struct procstat {
3555        pid_t   ps_pid;         /* process id */
3556        int     ps_status;      /* last process status from wait() */
3557        char    *ps_cmd;        /* text of command being run */
3558};
3559
3560struct job {
3561        struct procstat ps0;    /* status of process */
3562        struct procstat *ps;    /* status of processes when more than one */
3563#if JOBS
3564        int stopstatus;         /* status of a stopped job */
3565#endif
3566        unsigned nprocs;        /* number of processes */
3567
3568#define JOBRUNNING      0       /* at least one proc running */
3569#define JOBSTOPPED      1       /* all procs are stopped */
3570#define JOBDONE         2       /* all procs are completed */
3571        unsigned
3572                state: 8,
3573#if JOBS
3574                sigint: 1,      /* job was killed by SIGINT */
3575                jobctl: 1,      /* job running under job control */
3576#endif
3577                waited: 1,      /* true if this entry has been waited for */
3578                used: 1,        /* true if this entry is in used */
3579                changed: 1;     /* true if status has changed */
3580        struct job *prev_job;   /* previous job */
3581};
3582
3583static struct job *makejob(/*union node *,*/ int);
3584static int forkshell(struct job *, union node *, int);
3585static int waitforjob(struct job *);
3586
3587#if !JOBS
3588enum { doing_jobctl = 0 };
3589#define setjobctl(on) do {} while (0)
3590#else
3591static smallint doing_jobctl; //references:8
3592static void setjobctl(int);
3593#endif
3594
3595/*
3596 * Ignore a signal.
3597 */
3598static void
3599ignoresig(int signo)
3600{
3601        /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
3602        if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
3603                /* No, need to do it */
3604                signal(signo, SIG_IGN);
3605        }
3606        sigmode[signo - 1] = S_HARD_IGN;
3607}
3608
3609/*
3610 * Only one usage site - in setsignal()
3611 */
3612static void
3613signal_handler(int signo)
3614{
3615        if (signo == SIGCHLD) {
3616                got_sigchld = 1;
3617                if (!trap[SIGCHLD])
3618                        return;
3619        }
3620
3621        gotsig[signo - 1] = 1;
3622        pending_sig = signo;
3623
3624        if (signo == SIGINT && !trap[SIGINT]) {
3625                if (!suppress_int) {
3626                        pending_sig = 0;
3627                        raise_interrupt(); /* does not return */
3628                }
3629                pending_int = 1;
3630        }
3631}
3632
3633/*
3634 * Set the signal handler for the specified signal.  The routine figures
3635 * out what it should be set to.
3636 */
3637static void
3638setsignal(int signo)
3639{
3640        char *t;
3641        char cur_act, new_act;
3642        struct sigaction act;
3643
3644        t = trap[signo];
3645        new_act = S_DFL;
3646        if (t != NULL) { /* trap for this sig is set */
3647                new_act = S_CATCH;
3648                if (t[0] == '\0') /* trap is "": ignore this sig */
3649                        new_act = S_IGN;
3650        }
3651
3652        if (rootshell && new_act == S_DFL) {
3653                switch (signo) {
3654                case SIGINT:
3655                        if (iflag || minusc || sflag == 0)
3656                                new_act = S_CATCH;
3657                        break;
3658                case SIGQUIT:
3659#if DEBUG
3660                        if (debug)
3661                                break;
3662#endif
3663                        /* man bash:
3664                         * "In all cases, bash ignores SIGQUIT. Non-builtin
3665                         * commands run by bash have signal handlers
3666                         * set to the values inherited by the shell
3667                         * from its parent". */
3668                        new_act = S_IGN;
3669                        break;
3670                case SIGTERM:
3671                        if (iflag)
3672                                new_act = S_IGN;
3673                        break;
3674#if JOBS
3675                case SIGTSTP:
3676                case SIGTTOU:
3677                        if (mflag)
3678                                new_act = S_IGN;
3679                        break;
3680#endif
3681                }
3682        }
3683        /* if !rootshell, we reset SIGQUIT to DFL,
3684         * whereas we have to restore it to what shell got on entry.
3685         * This is handled by the fact that if signal was IGNored on entry,
3686         * then cur_act is S_HARD_IGN and we never change its sigaction
3687         * (see code below).
3688         */
3689
3690        if (signo == SIGCHLD)
3691                new_act = S_CATCH;
3692
3693        t = &sigmode[signo - 1];
3694        cur_act = *t;
3695        if (cur_act == 0) {
3696                /* current setting is not yet known */
3697                if (sigaction(signo, NULL, &act)) {
3698                        /* pretend it worked; maybe we should give a warning,
3699                         * but other shells don't. We don't alter sigmode,
3700                         * so we retry every time.
3701                         * btw, in Linux it never fails. --vda */
3702                        return;
3703                }
3704                if (act.sa_handler == SIG_IGN) {
3705                        cur_act = S_HARD_IGN;
3706                        if (mflag
3707                         && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
3708                        ) {
3709                                cur_act = S_IGN;   /* don't hard ignore these */
3710                        }
3711                }
3712                if (act.sa_handler == SIG_DFL && new_act == S_DFL) {
3713                        /* installing SIG_DFL over SIG_DFL is a no-op */
3714                        /* saves one sigaction call in each "sh -c SCRIPT" invocation */
3715                        *t = S_DFL;
3716                        return;
3717                }
3718        }
3719        if (cur_act == S_HARD_IGN || cur_act == new_act)
3720                return;
3721
3722        *t = new_act;
3723
3724        act.sa_handler = SIG_DFL;
3725        switch (new_act) {
3726        case S_CATCH:
3727                act.sa_handler = signal_handler;
3728                break;
3729        case S_IGN:
3730                act.sa_handler = SIG_IGN;
3731                break;
3732        }
3733        /* flags and mask matter only if !DFL and !IGN, but we do it
3734         * for all cases for more deterministic behavior:
3735         */
3736        act.sa_flags = 0; //TODO: why not SA_RESTART?
3737        sigfillset(&act.sa_mask);
3738
3739        sigaction_set(signo, &act);
3740}
3741
3742/* mode flags for set_curjob */
3743#define CUR_DELETE 2
3744#define CUR_RUNNING 1
3745#define CUR_STOPPED 0
3746
3747#if JOBS
3748/* pgrp of shell on invocation */
3749static int initialpgrp; //references:2
3750static int ttyfd = -1; //5
3751#endif
3752/* array of jobs */
3753static struct job *jobtab; //5
3754/* size of array */
3755static unsigned njobs; //4
3756/* current job */
3757static struct job *curjob; //lots
3758/* number of presumed living untracked jobs */
3759static int jobless; //4
3760
3761#if 0
3762/* Bash has a feature: it restores termios after a successful wait for
3763 * a foreground job which had at least one stopped or sigkilled member.
3764 * The probable rationale is that SIGSTOP and SIGKILL can preclude task from
3765 * properly restoring tty state. Should we do this too?
3766 * A reproducer: ^Z an interactive python:
3767 *
3768 * # python
3769 * Python 2.7.12 (...)
3770 * >>> ^Z
3771 *      { python leaves tty in -icanon -echo state. We do survive that... }
3772 *  [1]+  Stopped                    python
3773 *      { ...however, next program (python #2) does not survive it well: }
3774 * # python
3775 * Python 2.7.12 (...)
3776 * >>> Traceback (most recent call last):
3777 *      { above, I typed "qwerty<CR>", but -echo state is still in effect }
3778 *   File "<stdin>", line 1, in <module>
3779 * NameError: name 'qwerty' is not defined
3780 *
3781 * The implementation below is modeled on bash code and seems to work.
3782 * However, I'm not sure we should do this. For one: what if I'd fg
3783 * the stopped python instead? It'll be confused by "restored" tty state.
3784 */
3785static struct termios shell_tty_info;
3786static void
3787get_tty_state(void)
3788{
3789        if (rootshell && ttyfd >= 0)
3790                tcgetattr(ttyfd, &shell_tty_info);
3791}
3792static void
3793set_tty_state(void)
3794{
3795        /* if (rootshell) - caller ensures this */
3796        if (ttyfd >= 0)
3797                tcsetattr(ttyfd, TCSADRAIN, &shell_tty_info);
3798}
3799static int
3800job_signal_status(struct job *jp)
3801{
3802        int status;
3803        unsigned i;
3804        struct procstat *ps = jp->ps;
3805        for (i = 0; i < jp->nprocs; i++) {
3806                status = ps[i].ps_status;
3807                if (WIFSIGNALED(status) || WIFSTOPPED(status))
3808                        return status;
3809        }
3810        return 0;
3811}
3812static void
3813restore_tty_if_stopped_or_signaled(struct job *jp)
3814{
3815//TODO: check what happens if we come from waitforjob() in expbackq()
3816        if (rootshell) {
3817                int s = job_signal_status(jp);
3818                if (s) /* WIFSIGNALED(s) || WIFSTOPPED(s) */
3819                        set_tty_state();
3820        }
3821}
3822#else
3823# define get_tty_state() ((void)0)
3824# define restore_tty_if_stopped_or_signaled(jp) ((void)0)
3825#endif
3826
3827static void
3828set_curjob(struct job *jp, unsigned mode)
3829{
3830        struct job *jp1;
3831        struct job **jpp, **curp;
3832
3833        /* first remove from list */
3834        jpp = curp = &curjob;
3835        while (1) {
3836                jp1 = *jpp;
3837                if (jp1 == jp)
3838                        break;
3839                jpp = &jp1->prev_job;
3840        }
3841        *jpp = jp1->prev_job;
3842
3843        /* Then re-insert in correct position */
3844        jpp = curp;
3845        switch (mode) {
3846        default:
3847#if DEBUG
3848                abort();
3849#endif
3850        case CUR_DELETE:
3851                /* job being deleted */
3852                break;
3853        case CUR_RUNNING:
3854                /* newly created job or backgrounded job,
3855                 * put after all stopped jobs.
3856                 */
3857                while (1) {
3858                        jp1 = *jpp;
3859#if JOBS
3860                        if (!jp1 || jp1->state != JOBSTOPPED)
3861#endif
3862                                break;
3863                        jpp = &jp1->prev_job;
3864                }
3865                /* FALLTHROUGH */
3866#if JOBS
3867        case CUR_STOPPED:
3868#endif
3869                /* newly stopped job - becomes curjob */
3870                jp->prev_job = *jpp;
3871                *jpp = jp;
3872                break;
3873        }
3874}
3875
3876#if JOBS || DEBUG
3877static int
3878jobno(const struct job *jp)
3879{
3880        return jp - jobtab + 1;
3881}
3882#endif
3883
3884/*
3885 * Convert a job name to a job structure.
3886 */
3887#if !JOBS
3888#define getjob(name, getctl) getjob(name)
3889#endif
3890static struct job *
3891getjob(const char *name, int getctl)
3892{
3893        struct job *jp;
3894        struct job *found;
3895        const char *err_msg = "%s: no such job";
3896        unsigned num;
3897        int c;
3898        const char *p;
3899        char *(*match)(const char *, const char *);
3900
3901        jp = curjob;
3902        p = name;
3903        if (!p)
3904                goto currentjob;
3905
3906        if (*p != '%')
3907                goto err;
3908
3909        c = *++p;
3910        if (!c)
3911                goto currentjob;
3912
3913        if (!p[1]) {
3914                if (c == '+' || c == '%') {
3915 currentjob:
3916                        err_msg = "No current job";
3917                        goto check;
3918                }
3919                if (c == '-') {
3920                        if (jp)
3921                                jp = jp->prev_job;
3922                        err_msg = "No previous job";
3923 check:
3924                        if (!jp)
3925                                goto err;
3926                        goto gotit;
3927                }
3928        }
3929
3930        if (is_number(p)) {
3931                num = atoi(p);
3932                if (num > 0 && num <= njobs) {
3933                        jp = jobtab + num - 1;
3934                        if (jp->used)
3935                                goto gotit;
3936                        goto err;
3937                }
3938        }
3939
3940        match = prefix;
3941        if (*p == '?') {
3942                match = strstr;
3943                p++;
3944        }
3945
3946        found = NULL;
3947        while (jp) {
3948                if (match(jp->ps[0].ps_cmd, p)) {
3949                        if (found)
3950                                goto err;
3951                        found = jp;
3952                        err_msg = "%s: ambiguous";
3953                }
3954                jp = jp->prev_job;
3955        }
3956        if (!found)
3957                goto err;
3958        jp = found;
3959
3960 gotit:
3961#if JOBS
3962        err_msg = "job %s not created under job control";
3963        if (getctl && jp->jobctl == 0)
3964                goto err;
3965#endif
3966        return jp;
3967 err:
3968        ash_msg_and_raise_error(err_msg, name);
3969}
3970
3971/*
3972 * Mark a job structure as unused.
3973 */
3974static void
3975freejob(struct job *jp)
3976{
3977        struct procstat *ps;
3978        int i;
3979
3980        INT_OFF;
3981        for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
3982                if (ps->ps_cmd != nullstr)
3983                        free(ps->ps_cmd);
3984        }
3985        if (jp->ps != &jp->ps0)
3986                free(jp->ps);
3987        jp->used = 0;
3988        set_curjob(jp, CUR_DELETE);
3989        INT_ON;
3990}
3991
3992#if JOBS
3993static void
3994xtcsetpgrp(int fd, pid_t pgrp)
3995{
3996        if (tcsetpgrp(fd, pgrp))
3997                ash_msg_and_raise_perror("can't set tty process group");
3998}
3999
4000/*
4001 * Turn job control on and off.
4002 *
4003 * Note:  This code assumes that the third arg to ioctl is a character
4004 * pointer, which is true on Berkeley systems but not System V.  Since
4005 * System V doesn't have job control yet, this isn't a problem now.
4006 *
4007 * Called with interrupts off.
4008 */
4009static void
4010setjobctl(int on)
4011{
4012        int fd;
4013        int pgrp;
4014
4015        if (on == doing_jobctl || rootshell == 0)
4016                return;
4017        if (on) {
4018                int ofd;
4019                ofd = fd = open(_PATH_TTY, O_RDWR);
4020                if (fd < 0) {
4021        /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
4022         * That sometimes helps to acquire controlling tty.
4023         * Obviously, a workaround for bugs when someone
4024         * failed to provide a controlling tty to bash! :) */
4025                        fd = 2;
4026                        while (!isatty(fd))
4027                                if (--fd < 0)
4028                                        goto out;
4029                }
4030                /* fd is a tty at this point */
4031                fd = fcntl(fd, F_DUPFD_CLOEXEC, 10);
4032                if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */
4033                        close(ofd);
4034                if (fd < 0)
4035                        goto out; /* F_DUPFD failed */
4036                if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
4037                        close_on_exec_on(fd);
4038                while (1) { /* while we are in the background */
4039                        pgrp = tcgetpgrp(fd);
4040                        if (pgrp < 0) {
4041 out:
4042                                ash_msg("can't access tty; job control turned off");
4043                                mflag = on = 0;
4044                                goto close;
4045                        }
4046                        if (pgrp == getpgrp())
4047                                break;
4048                        killpg(0, SIGTTIN);
4049                }
4050                initialpgrp = pgrp;
4051
4052                setsignal(SIGTSTP);
4053                setsignal(SIGTTOU);
4054                setsignal(SIGTTIN);
4055                pgrp = rootpid;
4056                setpgid(0, pgrp);
4057                xtcsetpgrp(fd, pgrp);
4058        } else {
4059                /* turning job control off */
4060                fd = ttyfd;
4061                pgrp = initialpgrp;
4062                /* was xtcsetpgrp, but this can make exiting ash
4063                 * loop forever if pty is already deleted */
4064                tcsetpgrp(fd, pgrp);
4065                setpgid(0, pgrp);
4066                setsignal(SIGTSTP);
4067                setsignal(SIGTTOU);
4068                setsignal(SIGTTIN);
4069 close:
4070                if (fd >= 0)
4071                        close(fd);
4072                fd = -1;
4073        }
4074        ttyfd = fd;
4075        doing_jobctl = on;
4076}
4077
4078static int FAST_FUNC
4079killcmd(int argc, char **argv)
4080{
4081        if (argv[1] && strcmp(argv[1], "-l") != 0) {
4082                int i = 1;
4083                do {
4084                        if (argv[i][0] == '%') {
4085                                /*
4086                                 * "kill %N" - job kill
4087                                 * Converting to pgrp / pid kill
4088                                 */
4089                                struct job *jp;
4090                                char *dst;
4091                                int j, n;
4092
4093                                jp = getjob(argv[i], 0);
4094                                /*
4095                                 * In jobs started under job control, we signal
4096                                 * entire process group by kill -PGRP_ID.
4097                                 * This happens, f.e., in interactive shell.
4098                                 *
4099                                 * Otherwise, we signal each child via
4100                                 * kill PID1 PID2 PID3.
4101                                 * Testcases:
4102                                 * sh -c 'sleep 1|sleep 1 & kill %1'
4103                                 * sh -c 'true|sleep 2 & sleep 1; kill %1'
4104                                 * sh -c 'true|sleep 1 & sleep 2; kill %1'
4105                                 */
4106                                n = jp->nprocs; /* can't be 0 (I hope) */
4107                                if (jp->jobctl)
4108                                        n = 1;
4109                                dst = alloca(n * sizeof(int)*4);
4110                                argv[i] = dst;
4111                                for (j = 0; j < n; j++) {
4112                                        struct procstat *ps = &jp->ps[j];
4113                                        /* Skip non-running and not-stopped members
4114                                         * (i.e. dead members) of the job
4115                                         */
4116                                        if (ps->ps_status != -1 && !WIFSTOPPED(ps->ps_status))
4117                                                continue;
4118                                        /*
4119                                         * kill_main has matching code to expect
4120                                         * leading space. Needed to not confuse
4121                                         * negative pids with "kill -SIGNAL_NO" syntax
4122                                         */
4123                                        dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid);
4124                                }
4125                                *dst = '\0';
4126                        }
4127                } while (argv[++i]);
4128        }
4129        return kill_main(argc, argv);
4130}
4131
4132static void
4133showpipe(struct job *jp /*, FILE *out*/)
4134{
4135        struct procstat *ps;
4136        struct procstat *psend;
4137
4138        psend = jp->ps + jp->nprocs;
4139        for (ps = jp->ps + 1; ps < psend; ps++)
4140                printf(" | %s", ps->ps_cmd);
4141        newline_and_flush(stdout);
4142        flush_stdout_stderr();
4143}
4144
4145
4146static int
4147restartjob(struct job *jp, int mode)
4148{
4149        struct procstat *ps;
4150        int i;
4151        int status;
4152        pid_t pgid;
4153
4154        INT_OFF;
4155        if (jp->state == JOBDONE)
4156                goto out;
4157        jp->state = JOBRUNNING;
4158        pgid = jp->ps[0].ps_pid;
4159        if (mode == FORK_FG) {
4160                get_tty_state();
4161                xtcsetpgrp(ttyfd, pgid);
4162        }
4163        killpg(pgid, SIGCONT);
4164        ps = jp->ps;
4165        i = jp->nprocs;
4166        do {
4167                if (WIFSTOPPED(ps->ps_status)) {
4168                        ps->ps_status = -1;
4169                }
4170                ps++;
4171        } while (--i);
4172 out:
4173        status = (mode == FORK_FG) ? waitforjob(jp) : 0;
4174        INT_ON;
4175        return status;
4176}
4177
4178static int FAST_FUNC
4179fg_bgcmd(int argc UNUSED_PARAM, char **argv)
4180{
4181        struct job *jp;
4182        int mode;
4183        int retval;
4184
4185        mode = (**argv == 'f') ? FORK_FG : FORK_BG;
4186        nextopt(nullstr);
4187        argv = argptr;
4188        do {
4189                jp = getjob(*argv, 1);
4190                if (mode == FORK_BG) {
4191                        set_curjob(jp, CUR_RUNNING);
4192                        printf("[%d] ", jobno(jp));
4193                }
4194                out1str(jp->ps[0].ps_cmd);
4195                showpipe(jp /*, stdout*/);
4196                retval = restartjob(jp, mode);
4197        } while (*argv && *++argv);
4198        return retval;
4199}
4200#endif
4201
4202static int
4203sprint_status48(char *s, int status, int sigonly)
4204{
4205        int col;
4206        int st;
4207
4208        col = 0;
4209        if (!WIFEXITED(status)) {
4210#if JOBS
4211                if (WIFSTOPPED(status))
4212                        st = WSTOPSIG(status);
4213                else
4214#endif
4215                        st = WTERMSIG(status);
4216                if (sigonly) {
4217                        if (st == SIGINT || st == SIGPIPE)
4218                                goto out;
4219#if JOBS
4220                        if (WIFSTOPPED(status))
4221                                goto out;
4222#endif
4223                }
4224                st &= 0x7f;
4225//TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata
4226                col = fmtstr(s, 32, strsignal(st));
4227                if (WCOREDUMP(status)) {
4228                        strcpy(s + col, " (core dumped)");
4229                        col += sizeof(" (core dumped)")-1;
4230                }
4231        } else if (!sigonly) {
4232                st = WEXITSTATUS(status);
4233                col = fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st);
4234        }
4235 out:
4236        return col;
4237}
4238
4239static int
4240wait_block_or_sig(int *status)
4241{
4242        int pid;
4243
4244        do {
4245                sigset_t mask;
4246
4247                /* Poll all children for changes in their state */
4248                got_sigchld = 0;
4249                /* if job control is active, accept stopped processes too */
4250                pid = waitpid(-1, status, doing_jobctl ? (WNOHANG|WUNTRACED) : WNOHANG);
4251                if (pid != 0)
4252                        break; /* Error (e.g. EINTR, ECHILD) or pid */
4253
4254                /* Children exist, but none are ready. Sleep until interesting signal */
4255#if 1
4256                sigfillset(&mask);
4257                sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */
4258                while (!got_sigchld && !pending_sig)
4259                        sigsuspend(&mask);
4260                sigprocmask(SIG_SETMASK, &mask, NULL);
4261#else /* unsafe: a signal can set pending_sig after check, but before pause() */
4262                while (!got_sigchld && !pending_sig)
4263                        pause();
4264#endif
4265
4266                /* If it was SIGCHLD, poll children again */
4267        } while (got_sigchld);
4268
4269        return pid;
4270}
4271
4272#define DOWAIT_NONBLOCK 0
4273#define DOWAIT_BLOCK    1
4274#define DOWAIT_BLOCK_OR_SIG 2
4275#if BASH_WAIT_N
4276# define DOWAIT_JOBSTATUS 0x10   /* OR this to get job's exitstatus instead of pid */
4277#endif
4278
4279static int
4280dowait(int block, struct job *job)
4281{
4282        int pid;
4283        int status;
4284        struct job *jp;
4285        struct job *thisjob;
4286#if BASH_WAIT_N
4287        bool want_jobexitstatus = (block & DOWAIT_JOBSTATUS);
4288        block = (block & ~DOWAIT_JOBSTATUS);
4289#endif
4290
4291        TRACE(("dowait(0x%x) called\n", block));
4292
4293        /* It's wrong to call waitpid() outside of INT_OFF region:
4294         * signal can arrive just after syscall return and handler can
4295         * longjmp away, losing stop/exit notification processing.
4296         * Thus, for "jobs" builtin, and for waiting for a fg job,
4297         * we call waitpid() (blocking or non-blocking) inside INT_OFF.
4298         *
4299         * However, for "wait" builtin it is wrong to simply call waitpid()
4300         * in INT_OFF region: "wait" needs to wait for any running job
4301         * to change state, but should exit on any trap too.
4302         * In INT_OFF region, a signal just before syscall entry can set
4303         * pending_sig variables, but we can't check them, and we would
4304         * either enter a sleeping waitpid() (BUG), or need to busy-loop.
4305         *
4306         * Because of this, we run inside INT_OFF, but use a special routine
4307         * which combines waitpid() and sigsuspend().
4308         * This is the reason why we need to have a handler for SIGCHLD:
4309         * SIG_DFL handler does not wake sigsuspend().
4310         */
4311        INT_OFF;
4312        if (block == DOWAIT_BLOCK_OR_SIG) {
4313                pid = wait_block_or_sig(&status);
4314        } else {
4315                int wait_flags = 0;
4316                if (block == DOWAIT_NONBLOCK)
4317                        wait_flags = WNOHANG;
4318                /* if job control is active, accept stopped processes too */
4319                if (doing_jobctl)
4320                        wait_flags |= WUNTRACED;
4321                /* NB: _not_ safe_waitpid, we need to detect EINTR */
4322                pid = waitpid(-1, &status, wait_flags);
4323        }
4324        TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
4325                                pid, status, errno, strerror(errno)));
4326        thisjob = NULL;
4327        if (pid <= 0)
4328                goto out;
4329
4330        for (jp = curjob; jp; jp = jp->prev_job) {
4331                int jobstate;
4332                struct procstat *ps;
4333                struct procstat *psend;
4334                if (jp->state == JOBDONE)
4335                        continue;
4336                jobstate = JOBDONE;
4337                ps = jp->ps;
4338                psend = ps + jp->nprocs;
4339                do {
4340                        if (ps->ps_pid == pid) {
4341                                TRACE(("Job %d: changing status of proc %d "
4342                                        "from 0x%x to 0x%x\n",
4343                                        jobno(jp), pid, ps->ps_status, status));
4344                                ps->ps_status = status;
4345                                thisjob = jp;
4346                        }
4347                        if (ps->ps_status == -1)
4348                                jobstate = JOBRUNNING;
4349#if JOBS
4350                        if (jobstate == JOBRUNNING)
4351                                continue;
4352                        if (WIFSTOPPED(ps->ps_status)) {
4353                                jp->stopstatus = ps->ps_status;
4354                                jobstate = JOBSTOPPED;
4355                        }
4356#endif
4357                } while (++ps < psend);
4358                if (!thisjob)
4359                        continue;
4360
4361                /* Found the job where one of its processes changed its state.
4362                 * Is there at least one live and running process in this job? */
4363                if (jobstate != JOBRUNNING) {
4364                        /* No. All live processes in the job are stopped
4365                         * (JOBSTOPPED) or there are no live processes (JOBDONE)
4366                         */
4367                        thisjob->changed = 1;
4368                        if (thisjob->state != jobstate) {
4369                                TRACE(("Job %d: changing state from %d to %d\n",
4370                                        jobno(thisjob), thisjob->state, jobstate));
4371                                thisjob->state = jobstate;
4372#if JOBS
4373                                if (jobstate == JOBSTOPPED)
4374                                        set_curjob(thisjob, CUR_STOPPED);
4375#endif
4376                        }
4377                }
4378                goto out;
4379        }
4380        /* The process wasn't found in job list */
4381#if JOBS
4382        if (!WIFSTOPPED(status))
4383                jobless--;
4384#endif
4385 out:
4386        INT_ON;
4387
4388#if BASH_WAIT_N
4389        if (want_jobexitstatus) {
4390                pid = -1;
4391                if (thisjob && thisjob->state == JOBDONE)
4392                        pid = thisjob->ps[thisjob->nprocs - 1].ps_status;
4393        }
4394#endif
4395        if (thisjob && thisjob == job) {
4396                char s[48 + 1];
4397                int len;
4398
4399                len = sprint_status48(s, status, 1);
4400                if (len) {
4401                        s[len] = '\n';
4402                        s[len + 1] = '\0';
4403                        out2str(s);
4404                }
4405        }
4406        return pid;
4407}
4408
4409#if JOBS
4410static void
4411showjob(struct job *jp, int mode)
4412{
4413        struct procstat *ps;
4414        struct procstat *psend;
4415        int col;
4416        int indent_col;
4417        char s[16 + 16 + 48];
4418        FILE *out = (mode & SHOW_STDERR ? stderr : stdout);
4419
4420        ps = jp->ps;
4421
4422        if (mode & SHOW_ONLY_PGID) { /* jobs -p */
4423                /* just output process (group) id of pipeline */
4424                fprintf(out, "%d\n", ps->ps_pid);
4425                return;
4426        }
4427
4428        col = fmtstr(s, 16, "[%d]   ", jobno(jp));
4429        indent_col = col;
4430
4431        if (jp == curjob)
4432                s[col - 3] = '+';
4433        else if (curjob && jp == curjob->prev_job)
4434                s[col - 3] = '-';
4435
4436        if (mode & SHOW_PIDS)
4437                col += fmtstr(s + col, 16, "%d ", ps->ps_pid);
4438
4439        psend = ps + jp->nprocs;
4440
4441        if (jp->state == JOBRUNNING) {
4442                strcpy(s + col, "Running");
4443                col += sizeof("Running") - 1;
4444        } else {
4445                int status = psend[-1].ps_status;
4446                if (jp->state == JOBSTOPPED)
4447                        status = jp->stopstatus;
4448                col += sprint_status48(s + col, status, 0);
4449        }
4450        /* By now, "[JOBID]*  [maybe PID] STATUS" is printed */
4451
4452        /* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
4453         * or prints several "PID             | <cmdN>" lines,
4454         * depending on SHOW_PIDS bit.
4455         * We do not print status of individual processes
4456         * between PID and <cmdN>. bash does it, but not very well:
4457         * first line shows overall job status, not process status,
4458         * making it impossible to know 1st process status.
4459         */
4460        goto start;
4461        do {
4462                /* for each process */
4463                s[0] = '\0';
4464                col = 33;
4465                if (mode & SHOW_PIDS)
4466                        col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1;
4467 start:
4468                fprintf(out, "%s%*c%s%s",
4469                                s,
4470                                33 - col >= 0 ? 33 - col : 0, ' ',
4471                                ps == jp->ps ? "" : "| ",
4472                                ps->ps_cmd
4473                );
4474        } while (++ps != psend);
4475        newline_and_flush(out);
4476
4477        jp->changed = 0;
4478
4479        if (jp->state == JOBDONE) {
4480                TRACE(("showjob: freeing job %d\n", jobno(jp)));
4481                freejob(jp);
4482        }
4483}
4484
4485/*
4486 * Print a list of jobs.  If "change" is nonzero, only print jobs whose
4487 * statuses have changed since the last call to showjobs.
4488 */
4489static void
4490showjobs(int mode)
4491{
4492        struct job *jp;
4493
4494        TRACE(("showjobs(0x%x) called\n", mode));
4495
4496        /* Handle all finished jobs */
4497        while (dowait(DOWAIT_NONBLOCK, NULL) > 0)
4498                continue;
4499
4500        for (jp = curjob; jp; jp = jp->prev_job) {
4501                if (!(mode & SHOW_CHANGED) || jp->changed) {
4502                        showjob(jp, mode);
4503                }
4504        }
4505}
4506
4507static int FAST_FUNC
4508jobscmd(int argc UNUSED_PARAM, char **argv)
4509{
4510        int mode, m;
4511
4512        mode = 0;
4513        while ((m = nextopt("lp")) != '\0') {
4514                if (m == 'l')
4515                        mode |= SHOW_PIDS;
4516                else
4517                        mode |= SHOW_ONLY_PGID;
4518        }
4519
4520        argv = argptr;
4521        if (*argv) {
4522                do
4523                        showjob(getjob(*argv, 0), mode);
4524                while (*++argv);
4525        } else {
4526                showjobs(mode);
4527        }
4528
4529        return 0;
4530}
4531#endif /* JOBS */
4532
4533/* Called only on finished or stopped jobs (no members are running) */
4534static int
4535getstatus(struct job *job)
4536{
4537        int status;
4538        int retval;
4539        struct procstat *ps;
4540
4541        /* Fetch last member's status */
4542        ps = job->ps + job->nprocs - 1;
4543        status = ps->ps_status;
4544        if (pipefail) {
4545                /* "set -o pipefail" mode: use last _nonzero_ status */
4546                while (status == 0 && --ps >= job->ps)
4547                        status = ps->ps_status;
4548        }
4549
4550        retval = WEXITSTATUS(status);
4551        if (!WIFEXITED(status)) {
4552#if JOBS
4553                retval = WSTOPSIG(status);
4554                if (!WIFSTOPPED(status))
4555#endif
4556                {
4557                        /* XXX: limits number of signals */
4558                        retval = WTERMSIG(status);
4559#if JOBS
4560                        if (retval == SIGINT)
4561                                job->sigint = 1;
4562#endif
4563                }
4564                retval += 128;
4565        }
4566        TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n",
4567                jobno(job), job->nprocs, status, retval));
4568        return retval;
4569}
4570
4571static int FAST_FUNC
4572waitcmd(int argc UNUSED_PARAM, char **argv)
4573{
4574        struct job *job;
4575        int retval;
4576        struct job *jp;
4577#if BASH_WAIT_N
4578        int status;
4579        char one = nextopt("n");
4580#else
4581        nextopt(nullstr);
4582#endif
4583        retval = 0;
4584
4585        argv = argptr;
4586        if (!argv[0]) {
4587                /* wait for all jobs / one job if -n */
4588                for (;;) {
4589                        jp = curjob;
4590#if BASH_WAIT_N
4591                        if (one && !jp)
4592                                /* exitcode of "wait -n" with nothing to wait for is 127, not 0 */
4593                                retval = 127;
4594#endif
4595                        while (1) {
4596                                if (!jp) /* no running procs */
4597                                        goto ret;
4598                                if (jp->state == JOBRUNNING)
4599                                        break;
4600                                jp->waited = 1;
4601                                jp = jp->prev_job;
4602                        }
4603        /* man bash:
4604         * "When bash is waiting for an asynchronous command via
4605         * the wait builtin, the reception of a signal for which a trap
4606         * has been set will cause the wait builtin to return immediately
4607         * with an exit status greater than 128, immediately after which
4608         * the trap is executed."
4609         */
4610#if BASH_WAIT_N
4611                        status = dowait(DOWAIT_BLOCK_OR_SIG | DOWAIT_JOBSTATUS, NULL);
4612#else
4613                        dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4614#endif
4615        /* if child sends us a signal *and immediately exits*,
4616         * dowait() returns pid > 0. Check this case,
4617         * not "if (dowait() < 0)"!
4618         */
4619                        if (pending_sig)
4620                                goto sigout;
4621#if BASH_WAIT_N
4622                        if (one) {
4623                                /* wait -n waits for one _job_, not one _process_.
4624                                 *  date; sleep 3 & sleep 2 | sleep 1 & wait -n; date
4625                                 * should wait for 2 seconds. Not 1 or 3.
4626                                 */
4627                                if (status != -1 && !WIFSTOPPED(status)) {
4628                                        retval = WEXITSTATUS(status);
4629                                        if (WIFSIGNALED(status))
4630                                                retval = WTERMSIG(status) + 128;
4631                                        goto ret;
4632                                }
4633                        }
4634#endif
4635                }
4636        }
4637
4638        retval = 127;
4639        do {
4640                if (**argv != '%') {
4641                        pid_t pid = number(*argv);
4642                        job = curjob;
4643                        while (1) {
4644                                if (!job)
4645                                        goto repeat;
4646                                if (job->ps[job->nprocs - 1].ps_pid == pid)
4647                                        break;
4648                                job = job->prev_job;
4649                        }
4650                } else {
4651                        job = getjob(*argv, 0);
4652                }
4653                /* loop until process terminated or stopped */
4654                while (job->state == JOBRUNNING) {
4655                        dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4656                        if (pending_sig)
4657                                goto sigout;
4658                }
4659                job->waited = 1;
4660                retval = getstatus(job);
4661 repeat: ;
4662        } while (*++argv);
4663
4664 ret:
4665        return retval;
4666 sigout:
4667        retval = 128 + pending_sig;
4668        return retval;
4669}
4670
4671static struct job *
4672growjobtab(void)
4673{
4674        size_t len;
4675        ptrdiff_t offset;
4676        struct job *jp, *jq;
4677
4678        len = njobs * sizeof(*jp);
4679        jq = jobtab;
4680        jp = ckrealloc(jq, len + 4 * sizeof(*jp));
4681
4682        offset = (char *)jp - (char *)jq;
4683        if (offset) {
4684                /* Relocate pointers */
4685                size_t l = len;
4686
4687                jq = (struct job *)((char *)jq + l);
4688                while (l) {
4689                        l -= sizeof(*jp);
4690                        jq--;
4691#define joff(p) ((struct job *)((char *)(p) + l))
4692#define jmove(p) (p) = (void *)((char *)(p) + offset)
4693                        if (joff(jp)->ps == &jq->ps0)
4694                                jmove(joff(jp)->ps);
4695                        if (joff(jp)->prev_job)
4696                                jmove(joff(jp)->prev_job);
4697                }
4698                if (curjob)
4699                        jmove(curjob);
4700#undef joff
4701#undef jmove
4702        }
4703
4704        njobs += 4;
4705        jobtab = jp;
4706        jp = (struct job *)((char *)jp + len);
4707        jq = jp + 3;
4708        do {
4709                jq->used = 0;
4710        } while (--jq >= jp);
4711        return jp;
4712}
4713
4714/*
4715 * Return a new job structure.
4716 * Called with interrupts off.
4717 */
4718static struct job *
4719makejob(/*union node *node,*/ int nprocs)
4720{
4721        int i;
4722        struct job *jp;
4723
4724        for (i = njobs, jp = jobtab; ; jp++) {
4725                if (--i < 0) {
4726                        jp = growjobtab();
4727                        break;
4728                }
4729                if (jp->used == 0)
4730                        break;
4731                if (jp->state != JOBDONE || !jp->waited)
4732                        continue;
4733#if JOBS
4734                if (doing_jobctl)
4735                        continue;
4736#endif
4737                freejob(jp);
4738                break;
4739        }
4740        memset(jp, 0, sizeof(*jp));
4741#if JOBS
4742        /* jp->jobctl is a bitfield.
4743         * "jp->jobctl |= doing_jobctl" likely to give awful code */
4744        if (doing_jobctl)
4745                jp->jobctl = 1;
4746#endif
4747        jp->prev_job = curjob;
4748        curjob = jp;
4749        jp->used = 1;
4750        jp->ps = &jp->ps0;
4751        if (nprocs > 1) {
4752                jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
4753        }
4754        TRACE(("makejob(%d) returns %%%d\n", nprocs,
4755                                jobno(jp)));
4756        return jp;
4757}
4758
4759#if JOBS
4760/*
4761 * Return a string identifying a command (to be printed by the
4762 * jobs command).
4763 */
4764static char *cmdnextc;
4765
4766static void
4767cmdputs(const char *s)
4768{
4769        static const char vstype[VSTYPE + 1][3] = {
4770                "", "}", "-", "+", "?", "=",
4771                "%", "%%", "#", "##"
4772                IF_BASH_SUBSTR(, ":")
4773                IF_BASH_PATTERN_SUBST(, "/", "//")
4774        };
4775
4776        const char *p, *str;
4777        char cc[2];
4778        char *nextc;
4779        unsigned char c;
4780        unsigned char subtype = 0;
4781        int quoted = 0;
4782
4783        cc[1] = '\0';
4784        nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
4785        p = s;
4786        while ((c = *p++) != '\0') {
4787                str = NULL;
4788                switch (c) {
4789                case CTLESC:
4790                        c = *p++;
4791                        break;
4792                case CTLVAR:
4793                        subtype = *p++;
4794                        if ((subtype & VSTYPE) == VSLENGTH)
4795                                str = "${#";
4796                        else
4797                                str = "${";
4798                        goto dostr;
4799                case CTLENDVAR:
4800                        str = "\"}" + !(quoted & 1);
4801                        quoted >>= 1;
4802                        subtype = 0;
4803                        goto dostr;
4804                case CTLBACKQ:
4805                        str = "$(...)";
4806                        goto dostr;
4807#if ENABLE_FEATURE_SH_MATH
4808                case CTLARI:
4809                        str = "$((";
4810                        goto dostr;
4811                case CTLENDARI:
4812                        str = "))";
4813                        goto dostr;
4814#endif
4815                case CTLQUOTEMARK:
4816                        quoted ^= 1;
4817                        c = '"';
4818                        break;
4819                case '=':
4820                        if (subtype == 0)
4821                                break;
4822                        if ((subtype & VSTYPE) != VSNORMAL)
4823                                quoted <<= 1;
4824                        str = vstype[subtype & VSTYPE];
4825                        if (subtype & VSNUL)
4826                                c = ':';
4827                        else
4828                                goto checkstr;
4829                        break;
4830                case '\'':
4831                case '\\':
4832                case '"':
4833                case '$':
4834                        /* These can only happen inside quotes */
4835                        cc[0] = c;
4836                        str = cc;
4837//FIXME:
4838// $ true $$ &
4839// $ <cr>
4840// [1]+  Done    true ${\$}   <<=== BUG: ${\$} is not a valid way to write $$ (${$} would be ok)
4841                        c = '\\';
4842                        break;
4843                default:
4844                        break;
4845                }
4846                USTPUTC(c, nextc);
4847 checkstr:
4848                if (!str)
4849                        continue;
4850 dostr:
4851                while ((c = *str++) != '\0') {
4852                        USTPUTC(c, nextc);
4853                }
4854        } /* while *p++ not NUL */
4855
4856        if (quoted & 1) {
4857                USTPUTC('"', nextc);
4858        }
4859        *nextc = 0;
4860        cmdnextc = nextc;
4861}
4862
4863/* cmdtxt() and cmdlist() call each other */
4864static void cmdtxt(union node *n);
4865
4866static void
4867cmdlist(union node *np, int sep)
4868{
4869        for (; np; np = np->narg.next) {
4870                if (!sep)
4871                        cmdputs(" ");
4872                cmdtxt(np);
4873                if (sep && np->narg.next)
4874                        cmdputs(" ");
4875        }
4876}
4877
4878static void
4879cmdtxt(union node *n)
4880{
4881        union node *np;
4882        struct nodelist *lp;
4883        const char *p;
4884
4885        if (!n)
4886                return;
4887        switch (n->type) {
4888        default:
4889#if DEBUG
4890                abort();
4891#endif
4892        case NPIPE:
4893                lp = n->npipe.cmdlist;
4894                for (;;) {
4895                        cmdtxt(lp->n);
4896                        lp = lp->next;
4897                        if (!lp)
4898                                break;
4899                        cmdputs(" | ");
4900                }
4901                break;
4902        case NSEMI:
4903                p = "; ";
4904                goto binop;
4905        case NAND:
4906                p = " && ";
4907                goto binop;
4908        case NOR:
4909                p = " || ";
4910 binop:
4911                cmdtxt(n->nbinary.ch1);
4912                cmdputs(p);
4913                n = n->nbinary.ch2;
4914                goto donode;
4915        case NREDIR:
4916        case NBACKGND:
4917                n = n->nredir.n;
4918                goto donode;
4919        case NNOT:
4920                cmdputs("!");
4921                n = n->nnot.com;
4922 donode:
4923                cmdtxt(n);
4924                break;
4925        case NIF:
4926                cmdputs("if ");
4927                cmdtxt(n->nif.test);
4928                cmdputs("; then ");
4929                if (n->nif.elsepart) {
4930                        cmdtxt(n->nif.ifpart);
4931                        cmdputs("; else ");
4932                        n = n->nif.elsepart;
4933                } else {
4934                        n = n->nif.ifpart;
4935                }
4936                p = "; fi";
4937                goto dotail;
4938        case NSUBSHELL:
4939                cmdputs("(");
4940                n = n->nredir.n;
4941                p = ")";
4942                goto dotail;
4943        case NWHILE:
4944                p = "while ";
4945                goto until;
4946        case NUNTIL:
4947                p = "until ";
4948 until:
4949                cmdputs(p);
4950                cmdtxt(n->nbinary.ch1);
4951                n = n->nbinary.ch2;
4952                p = "; done";
4953 dodo:
4954                cmdputs("; do ");
4955 dotail:
4956                cmdtxt(n);
4957                goto dotail2;
4958        case NFOR:
4959                cmdputs("for ");
4960                cmdputs(n->nfor.var);
4961                cmdputs(" in ");
4962                cmdlist(n->nfor.args, 1);
4963                n = n->nfor.body;
4964                p = "; done";
4965                goto dodo;
4966        case NDEFUN:
4967                cmdputs(n->ndefun.text);
4968                p = "() { ... }";
4969                goto dotail2;
4970        case NCMD:
4971                cmdlist(n->ncmd.args, 1);
4972                cmdlist(n->ncmd.redirect, 0);
4973                break;
4974        case NARG:
4975                p = n->narg.text;
4976 dotail2:
4977                cmdputs(p);
4978                break;
4979        case NHERE:
4980        case NXHERE:
4981                p = "<<...";
4982                goto dotail2;
4983        case NCASE:
4984                cmdputs("case ");
4985                cmdputs(n->ncase.expr->narg.text);
4986                cmdputs(" in ");
4987                for (np = n->ncase.cases; np; np = np->nclist.next) {
4988                        cmdtxt(np->nclist.pattern);
4989                        cmdputs(") ");
4990                        cmdtxt(np->nclist.body);
4991                        cmdputs(";; ");
4992                }
4993                p = "esac";
4994                goto dotail2;
4995        case NTO:
4996                p = ">";
4997                goto redir;
4998        case NCLOBBER:
4999                p = ">|";
5000                goto redir;
5001        case NAPPEND:
5002                p = ">>";
5003                goto redir;
5004#if BASH_REDIR_OUTPUT
5005        case NTO2:
5006#endif
5007        case NTOFD:
5008                p = ">&";
5009                goto redir;
5010        case NFROM:
5011                p = "<";
5012                goto redir;
5013        case NFROMFD:
5014                p = "<&";
5015                goto redir;
5016        case NFROMTO:
5017                p = "<>";
5018 redir:
5019                cmdputs(utoa(n->nfile.fd));
5020                cmdputs(p);
5021                if (n->type == NTOFD || n->type == NFROMFD) {
5022                        if (n->ndup.dupfd >= 0)
5023                                cmdputs(utoa(n->ndup.dupfd));
5024                        else
5025                                cmdputs("-");
5026                        break;
5027                }
5028                n = n->nfile.fname;
5029                goto donode;
5030        }
5031}
5032
5033static char *
5034commandtext(union node *n)
5035{
5036        char *name;
5037
5038        STARTSTACKSTR(cmdnextc);
5039        cmdtxt(n);
5040        name = stackblock();
5041        TRACE(("commandtext: name %p, end %p\n", name, cmdnextc));
5042        return ckstrdup(name);
5043}
5044#endif /* JOBS */
5045
5046/*
5047 * Fork off a subshell.  If we are doing job control, give the subshell its
5048 * own process group.  Jp is a job structure that the job is to be added to.
5049 * N is the command that will be evaluated by the child.  Both jp and n may
5050 * be NULL.  The mode parameter can be one of the following:
5051 *      FORK_FG - Fork off a foreground process.
5052 *      FORK_BG - Fork off a background process.
5053 *      FORK_NOJOB - Like FORK_FG, but don't give the process its own
5054 *                   process group even if job control is on.
5055 *
5056 * When job control is turned off, background processes have their standard
5057 * input redirected to /dev/null (except for the second and later processes
5058 * in a pipeline).
5059 *
5060 * Called with interrupts off.
5061 */
5062/*
5063 * Clear traps on a fork.
5064 */
5065static void
5066clear_traps(void)
5067{
5068        char **tp;
5069
5070        INT_OFF;
5071        for (tp = trap; tp < &trap[NSIG]; tp++) {
5072                if (*tp && **tp) {      /* trap not NULL or "" (SIG_IGN) */
5073                        if (trap_ptr == trap)
5074                                free(*tp);
5075                        /* else: it "belongs" to trap_ptr vector, don't free */
5076                        *tp = NULL;
5077                        if ((tp - trap) != 0)
5078                                setsignal(tp - trap);
5079                }
5080        }
5081        may_have_traps = 0;
5082        INT_ON;
5083}
5084
5085/* Lives far away from here, needed for forkchild */
5086static void closescript(void);
5087
5088/* Called after fork(), in child */
5089/* jp and n are NULL when called by openhere() for heredoc support */
5090static NOINLINE void
5091forkchild(struct job *jp, union node *n, int mode)
5092{
5093        int oldlvl;
5094
5095        TRACE(("Child shell %d\n", getpid()));
5096        oldlvl = shlvl;
5097        shlvl++;
5098
5099        /* man bash: "Non-builtin commands run by bash have signal handlers
5100         * set to the values inherited by the shell from its parent".
5101         * Do we do it correctly? */
5102
5103        closescript();
5104
5105        if (mode == FORK_NOJOB          /* is it `xxx` ? */
5106         && n && n->type == NCMD        /* is it single cmd? */
5107        /* && n->ncmd.args->type == NARG - always true? */
5108         && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0
5109         && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
5110        /* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
5111        ) {
5112                TRACE(("Trap hack\n"));
5113                /* Awful hack for `trap` or $(trap).
5114                 *
5115                 * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
5116                 * contains an example where "trap" is executed in a subshell:
5117                 *
5118                 * save_traps=$(trap)
5119                 * ...
5120                 * eval "$save_traps"
5121                 *
5122                 * Standard does not say that "trap" in subshell shall print
5123                 * parent shell's traps. It only says that its output
5124                 * must have suitable form, but then, in the above example
5125                 * (which is not supposed to be normative), it implies that.
5126                 *
5127                 * bash (and probably other shell) does implement it
5128                 * (traps are reset to defaults, but "trap" still shows them),
5129                 * but as a result, "trap" logic is hopelessly messed up:
5130                 *
5131                 * # trap
5132                 * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
5133                 * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
5134                 * # true | trap   <--- trap is in subshell - no output (ditto)
5135                 * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
5136                 * trap -- 'echo Ho' SIGWINCH
5137                 * # echo `(trap)`         <--- in subshell in subshell - output
5138                 * trap -- 'echo Ho' SIGWINCH
5139                 * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
5140                 * trap -- 'echo Ho' SIGWINCH
5141                 *
5142                 * The rules when to forget and when to not forget traps
5143                 * get really complex and nonsensical.
5144                 *
5145                 * Our solution: ONLY bare $(trap) or `trap` is special.
5146                 */
5147                /* Save trap handler strings for trap builtin to print */
5148                trap_ptr = xmemdup(trap, sizeof(trap));
5149                /* Fall through into clearing traps */
5150        }
5151        clear_traps();
5152#if JOBS
5153        /* do job control only in root shell */
5154        doing_jobctl = 0;
5155        if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) {
5156                pid_t pgrp;
5157
5158                if (jp->nprocs == 0)
5159                        pgrp = getpid();
5160                else
5161                        pgrp = jp->ps[0].ps_pid;
5162                /* this can fail because we are doing it in the parent also */
5163                setpgid(0, pgrp);
5164                if (mode == FORK_FG)
5165                        xtcsetpgrp(ttyfd, pgrp);
5166                setsignal(SIGTSTP);
5167                setsignal(SIGTTOU);
5168        } else
5169#endif
5170        if (mode == FORK_BG) {
5171                /* man bash: "When job control is not in effect,
5172                 * asynchronous commands ignore SIGINT and SIGQUIT" */
5173                ignoresig(SIGINT);
5174                ignoresig(SIGQUIT);
5175                if (jp->nprocs == 0) {
5176                        close(0);
5177                        if (open(bb_dev_null, O_RDONLY) != 0)
5178                                ash_msg_and_raise_perror("can't open '%s'", bb_dev_null);
5179                }
5180        }
5181        if (oldlvl == 0) {
5182                if (iflag) { /* why if iflag only? */
5183                        setsignal(SIGINT);
5184                        setsignal(SIGTERM);
5185                }
5186                /* man bash:
5187                 * "In all cases, bash ignores SIGQUIT. Non-builtin
5188                 * commands run by bash have signal handlers
5189                 * set to the values inherited by the shell
5190                 * from its parent".
5191                 * Take care of the second rule: */
5192                setsignal(SIGQUIT);
5193        }
5194#if JOBS
5195        if (n && n->type == NCMD
5196         && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "jobs") == 0
5197        ) {
5198                TRACE(("Job hack\n"));
5199                /* "jobs": we do not want to clear job list for it,
5200                 * instead we remove only _its_ own_ job from job list.
5201                 * This makes "jobs .... | cat" more useful.
5202                 */
5203                freejob(curjob);
5204                return;
5205        }
5206#endif
5207        for (jp = curjob; jp; jp = jp->prev_job)
5208                freejob(jp);
5209        jobless = 0;
5210}
5211
5212/* Called after fork(), in parent */
5213#if !JOBS
5214#define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid)
5215#endif
5216static void
5217forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5218{
5219        TRACE(("In parent shell: child = %d\n", pid));
5220        if (!jp) {
5221                /* jp is NULL when called by openhere() for heredoc support */
5222                while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0)
5223                        continue;
5224                jobless++;
5225                return;
5226        }
5227#if JOBS
5228        if (mode != FORK_NOJOB && jp->jobctl) {
5229                int pgrp;
5230
5231                if (jp->nprocs == 0)
5232                        pgrp = pid;
5233                else
5234                        pgrp = jp->ps[0].ps_pid;
5235                /* This can fail because we are doing it in the child also */
5236                setpgid(pid, pgrp);
5237        }
5238#endif
5239        if (mode == FORK_BG) {
5240                backgndpid = pid;               /* set $! */
5241                set_curjob(jp, CUR_RUNNING);
5242        }
5243        if (jp) {
5244                struct procstat *ps = &jp->ps[jp->nprocs++];
5245                ps->ps_pid = pid;
5246                ps->ps_status = -1;
5247                ps->ps_cmd = nullstr;
5248#if JOBS
5249                if (doing_jobctl && n)
5250                        ps->ps_cmd = commandtext(n);
5251#endif
5252        }
5253}
5254
5255/* jp and n are NULL when called by openhere() for heredoc support */
5256static int
5257forkshell(struct job *jp, union node *n, int mode)
5258{
5259        int pid;
5260
5261        TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
5262        pid = fork();
5263        if (pid < 0) {
5264                TRACE(("Fork failed, errno=%d", errno));
5265                if (jp)
5266                        freejob(jp);
5267                ash_msg_and_raise_perror("can't fork");
5268        }
5269        if (pid == 0) {
5270                CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */
5271                forkchild(jp, n, mode);
5272        } else {
5273                forkparent(jp, n, mode, pid);
5274        }
5275        return pid;
5276}
5277
5278/*
5279 * Wait for job to finish.
5280 *
5281 * Under job control we have the problem that while a child process
5282 * is running interrupts generated by the user are sent to the child
5283 * but not to the shell.  This means that an infinite loop started by
5284 * an interactive user may be hard to kill.  With job control turned off,
5285 * an interactive user may place an interactive program inside a loop.
5286 * If the interactive program catches interrupts, the user doesn't want
5287 * these interrupts to also abort the loop.  The approach we take here
5288 * is to have the shell ignore interrupt signals while waiting for a
5289 * foreground process to terminate, and then send itself an interrupt
5290 * signal if the child process was terminated by an interrupt signal.
5291 * Unfortunately, some programs want to do a bit of cleanup and then
5292 * exit on interrupt; unless these processes terminate themselves by
5293 * sending a signal to themselves (instead of calling exit) they will
5294 * confuse this approach.
5295 *
5296 * Called with interrupts off.
5297 */
5298static int
5299waitforjob(struct job *jp)
5300{
5301        int st;
5302
5303        TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
5304
5305        INT_OFF;
5306        while (jp->state == JOBRUNNING) {
5307                /* In non-interactive shells, we _can_ get
5308                 * a keyboard signal here and be EINTRed,
5309                 * but we just loop back, waiting for command to complete.
5310                 *
5311                 * man bash:
5312                 * "If bash is waiting for a command to complete and receives
5313                 * a signal for which a trap has been set, the trap
5314                 * will not be executed until the command completes."
5315                 *
5316                 * Reality is that even if trap is not set, bash
5317                 * will not act on the signal until command completes.
5318                 * Try this. sleep5intoff.c:
5319                 * #include <signal.h>
5320                 * #include <unistd.h>
5321                 * int main() {
5322                 *         sigset_t set;
5323                 *         sigemptyset(&set);
5324                 *         sigaddset(&set, SIGINT);
5325                 *         sigaddset(&set, SIGQUIT);
5326                 *         sigprocmask(SIG_BLOCK, &set, NULL);
5327                 *         sleep(5);
5328                 *         return 0;
5329                 * }
5330                 * $ bash -c './sleep5intoff; echo hi'
5331                 * ^C^C^C^C <--- pressing ^C once a second
5332                 * $ _
5333                 * $ bash -c './sleep5intoff; echo hi'
5334                 * ^\^\^\^\hi <--- pressing ^\ (SIGQUIT)
5335                 * $ _
5336                 */
5337                dowait(DOWAIT_BLOCK, jp);
5338        }
5339        INT_ON;
5340
5341        st = getstatus(jp);
5342#if JOBS
5343        if (jp->jobctl) {
5344                xtcsetpgrp(ttyfd, rootpid);
5345                restore_tty_if_stopped_or_signaled(jp);
5346
5347                /*
5348                 * This is truly gross.
5349                 * If we're doing job control, then we did a TIOCSPGRP which
5350                 * caused us (the shell) to no longer be in the controlling
5351                 * session -- so we wouldn't have seen any ^C/SIGINT.  So, we
5352                 * intuit from the subprocess exit status whether a SIGINT
5353                 * occurred, and if so interrupt ourselves.  Yuck.  - mycroft
5354                 */
5355                if (jp->sigint) /* TODO: do the same with all signals */
5356                        raise(SIGINT); /* ... by raise(jp->sig) instead? */
5357        }
5358        if (jp->state == JOBDONE)
5359#endif
5360                freejob(jp);
5361        return st;
5362}
5363
5364/*
5365 * return 1 if there are stopped jobs, otherwise 0
5366 */
5367static int
5368stoppedjobs(void)
5369{
5370        struct job *jp;
5371        int retval;
5372
5373        retval = 0;
5374        if (job_warning)
5375                goto out;
5376        jp = curjob;
5377        if (jp && jp->state == JOBSTOPPED) {
5378                out2str("You have stopped jobs.\n");
5379                job_warning = 2;
5380                retval++;
5381        }
5382 out:
5383        return retval;
5384}
5385
5386
5387/*
5388 * Code for dealing with input/output redirection.
5389 */
5390
5391#undef EMPTY
5392#undef CLOSED
5393#define EMPTY -2                /* marks an unused slot in redirtab */
5394#define CLOSED -1               /* marks a slot of previously-closed fd */
5395
5396/*
5397 * Handle here documents.  Normally we fork off a process to write the
5398 * data to a pipe.  If the document is short, we can stuff the data in
5399 * the pipe without forking.
5400 */
5401/* openhere needs this forward reference */
5402static void expandhere(union node *arg, int fd);
5403static int
5404openhere(union node *redir)
5405{
5406        int pip[2];
5407        size_t len = 0;
5408
5409        if (pipe(pip) < 0)
5410                ash_msg_and_raise_perror("can't create pipe");
5411        if (redir->type == NHERE) {
5412                len = strlen(redir->nhere.doc->narg.text);
5413                if (len <= PIPE_BUF) {
5414                        full_write(pip[1], redir->nhere.doc->narg.text, len);
5415                        goto out;
5416                }
5417        }
5418        if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
5419                /* child */
5420                close(pip[0]);
5421                ignoresig(SIGINT);  //signal(SIGINT, SIG_IGN);
5422                ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
5423                ignoresig(SIGHUP);  //signal(SIGHUP, SIG_IGN);
5424                ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5425                signal(SIGPIPE, SIG_DFL);
5426                if (redir->type == NHERE)
5427                        full_write(pip[1], redir->nhere.doc->narg.text, len);
5428                else /* NXHERE */
5429                        expandhere(redir->nhere.doc, pip[1]);
5430                _exit(EXIT_SUCCESS);
5431        }
5432 out:
5433        close(pip[1]);
5434        return pip[0];
5435}
5436
5437static int
5438openredirect(union node *redir)
5439{
5440        struct stat sb;
5441        char *fname;
5442        int f;
5443
5444        switch (redir->nfile.type) {
5445/* Can't happen, our single caller does this itself */
5446//      case NTOFD:
5447//      case NFROMFD:
5448//              return -1;
5449        case NHERE:
5450        case NXHERE:
5451                return openhere(redir);
5452        }
5453
5454        /* For N[X]HERE, reading redir->nfile.expfname would touch beyond
5455         * allocated space. Do it only when we know it is safe.
5456         */
5457        fname = redir->nfile.expfname;
5458
5459        switch (redir->nfile.type) {
5460        default:
5461#if DEBUG
5462                abort();
5463#endif
5464        case NFROM:
5465                f = open(fname, O_RDONLY);
5466                if (f < 0)
5467                        goto eopen;
5468                break;
5469        case NFROMTO:
5470                f = open(fname, O_RDWR|O_CREAT, 0666);
5471                if (f < 0)
5472                        goto ecreate;
5473                break;
5474        case NTO:
5475#if BASH_REDIR_OUTPUT
5476        case NTO2:
5477#endif
5478                /* Take care of noclobber mode. */
5479                if (Cflag) {
5480                        if (stat(fname, &sb) < 0) {
5481                                f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
5482                                if (f < 0)
5483                                        goto ecreate;
5484                        } else if (!S_ISREG(sb.st_mode)) {
5485                                f = open(fname, O_WRONLY, 0666);
5486                                if (f < 0)
5487                                        goto ecreate;
5488                                if (!fstat(f, &sb) && S_ISREG(sb.st_mode)) {
5489                                        close(f);
5490                                        errno = EEXIST;
5491                                        goto ecreate;
5492                                }
5493                        } else {
5494                                errno = EEXIST;
5495                                goto ecreate;
5496                        }
5497                        break;
5498                }
5499                /* FALLTHROUGH */
5500        case NCLOBBER:
5501                f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
5502                if (f < 0)
5503                        goto ecreate;
5504                break;
5505        case NAPPEND:
5506                f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
5507                if (f < 0)
5508                        goto ecreate;
5509                break;
5510        }
5511
5512        return f;
5513 ecreate:
5514        ash_msg_and_raise_error("can't create %s: %s", fname, errmsg(errno, "nonexistent directory"));
5515 eopen:
5516        ash_msg_and_raise_error("can't open %s: %s", fname, errmsg(errno, "no such file"));
5517}
5518
5519/*
5520 * Copy a file descriptor to be >= 10. Throws exception on error.
5521 */
5522static int
5523savefd(int from)
5524{
5525        int newfd;
5526        int err;
5527
5528        newfd = fcntl(from, F_DUPFD_CLOEXEC, 10);
5529        err = newfd < 0 ? errno : 0;
5530        if (err != EBADF) {
5531                if (err)
5532                        ash_msg_and_raise_perror("%d", from);
5533                close(from);
5534                if (F_DUPFD_CLOEXEC == F_DUPFD)
5535                        close_on_exec_on(newfd);
5536        }
5537
5538        return newfd;
5539}
5540static int
5541dup2_or_raise(int from, int to)
5542{
5543        int newfd;
5544
5545        newfd = (from != to) ? dup2(from, to) : to;
5546        if (newfd < 0) {
5547                /* Happens when source fd is not open: try "echo >&99" */
5548                ash_msg_and_raise_perror("%d", from);
5549        }
5550        return newfd;
5551}
5552static int
5553dup_CLOEXEC(int fd, int avoid_fd)
5554{
5555        int newfd;
5556 repeat:
5557        newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5558        if (newfd >= 0) {
5559                if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
5560                        close_on_exec_on(newfd);
5561        } else { /* newfd < 0 */
5562                if (errno == EBUSY)
5563                        goto repeat;
5564                if (errno == EINTR)
5565                        goto repeat;
5566        }
5567        return newfd;
5568}
5569static int
5570xdup_CLOEXEC_and_close(int fd, int avoid_fd)
5571{
5572        int newfd;
5573 repeat:
5574        newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5575        if (newfd < 0) {
5576                if (errno == EBUSY)
5577                        goto repeat;
5578                if (errno == EINTR)
5579                        goto repeat;
5580                /* fd was not open? */
5581                if (errno == EBADF)
5582                        return fd;
5583                ash_msg_and_raise_perror("%d", newfd);
5584        }
5585        if (F_DUPFD_CLOEXEC == F_DUPFD)
5586                close_on_exec_on(newfd);
5587        close(fd);
5588        return newfd;
5589}
5590
5591/* Struct def and variable are moved down to the first usage site */
5592struct squirrel {
5593        int orig_fd;
5594        int moved_to;
5595};
5596struct redirtab {
5597        struct redirtab *next;
5598        int pair_count;
5599        struct squirrel two_fd[];
5600};
5601#define redirlist (G_var.redirlist)
5602
5603static void
5604add_squirrel_closed(struct redirtab *sq, int fd)
5605{
5606        int i;
5607
5608        if (!sq)
5609                return;
5610
5611        for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5612                /* If we collide with an already moved fd... */
5613                if (fd == sq->two_fd[i].orig_fd) {
5614                        /* Examples:
5615                         * "echo 3>FILE 3>&- 3>FILE"
5616                         * "echo 3>&- 3>FILE"
5617                         * No need for last redirect to insert
5618                         * another "need to close 3" indicator.
5619                         */
5620                        TRACE(("redirect_fd %d: already moved or closed\n", fd));
5621                        return;
5622                }
5623        }
5624        TRACE(("redirect_fd %d: previous fd was closed\n", fd));
5625        sq->two_fd[i].orig_fd = fd;
5626        sq->two_fd[i].moved_to = CLOSED;
5627}
5628
5629static int
5630save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5631{
5632        int i, new_fd;
5633
5634        if (avoid_fd < 9) /* the important case here is that it can be -1 */
5635                avoid_fd = 9;
5636
5637#if JOBS
5638        if (fd == ttyfd) {
5639                /* Testcase: "ls -l /proc/$$/fd 10>&-" should work */
5640                ttyfd = xdup_CLOEXEC_and_close(ttyfd, avoid_fd);
5641                TRACE(("redirect_fd %d: matches ttyfd, moving it to %d\n", fd, ttyfd));
5642                return 1; /* "we closed fd" */
5643        }
5644#endif
5645        /* Are we called from redirect(0)? E.g. redirect
5646         * in a forked child. No need to save fds,
5647         * we aren't going to use them anymore, ok to trash.
5648         */
5649        if (!sq)
5650                return 0;
5651
5652        /* If this one of script's fds? */
5653        if (fd != 0) {
5654                struct parsefile *pf = g_parsefile;
5655                while (pf) {
5656                        /* We skip fd == 0 case because of the following:
5657                         * $ ash  # running ash interactively
5658                         * $ . ./script.sh
5659                         * and in script.sh: "exec 9>&0".
5660                         * Even though top-level pf_fd _is_ 0,
5661                         * it's still ok to use it: "read" builtin uses it,
5662                         * why should we cripple "exec" builtin?
5663                         */
5664                        if (fd == pf->pf_fd) {
5665                                pf->pf_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
5666                                return 1; /* "we closed fd" */
5667                        }
5668                        pf = pf->prev;
5669                }
5670        }
5671
5672        /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
5673
5674        /* First: do we collide with some already moved fds? */
5675        for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5676                /* If we collide with an already moved fd... */
5677                if (fd == sq->two_fd[i].moved_to) {
5678                        new_fd = dup_CLOEXEC(fd, avoid_fd);
5679                        sq->two_fd[i].moved_to = new_fd;
5680                        TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd));
5681                        if (new_fd < 0) /* what? */
5682                                xfunc_die();
5683                        return 0; /* "we did not close fd" */
5684                }
5685                if (fd == sq->two_fd[i].orig_fd) {
5686                        /* Example: echo Hello >/dev/null 1>&2 */
5687                        TRACE(("redirect_fd %d: already moved\n", fd));
5688                        return 0; /* "we did not close fd" */
5689                }
5690        }
5691
5692        /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */
5693        new_fd = dup_CLOEXEC(fd, avoid_fd);
5694        TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd));
5695        if (new_fd < 0) {
5696                if (errno != EBADF)
5697                        xfunc_die();
5698                /* new_fd = CLOSED; - already is -1 */
5699        }
5700        sq->two_fd[i].moved_to = new_fd;
5701        sq->two_fd[i].orig_fd = fd;
5702
5703        /* if we move stderr, let "set -x" code know */
5704        if (fd == preverrout_fd)
5705                preverrout_fd = new_fd;
5706
5707        return 0; /* "we did not close fd" */
5708}
5709
5710static int
5711internally_opened_fd(int fd, struct redirtab *sq)
5712{
5713        int i;
5714#if JOBS
5715        if (fd == ttyfd)
5716                return 1;
5717#endif
5718        /* If this one of script's fds? */
5719        if (fd != 0) {
5720                struct parsefile *pf = g_parsefile;
5721                while (pf) {
5722                        if (fd == pf->pf_fd)
5723                                return 1;
5724                        pf = pf->prev;
5725                }
5726        }
5727
5728        if (sq) for (i = 0; i < sq->pair_count && sq->two_fd[i].orig_fd != EMPTY; i++) {
5729                if (fd == sq->two_fd[i].moved_to)
5730                        return 1;
5731        }
5732        return 0;
5733}
5734
5735/*
5736 * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
5737 * old file descriptors are stashed away so that the redirection can be
5738 * undone by calling popredir.
5739 */
5740/* flags passed to redirect */
5741#define REDIR_PUSH    01        /* save previous values of file descriptors */
5742static void
5743redirect(union node *redir, int flags)
5744{
5745        struct redirtab *sv;
5746
5747        if (!redir)
5748                return;
5749
5750        sv = NULL;
5751        INT_OFF;
5752        if (flags & REDIR_PUSH)
5753                sv = redirlist;
5754        do {
5755                int fd;
5756                int newfd;
5757                int close_fd;
5758                int closed;
5759
5760                fd = redir->nfile.fd;
5761                if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
5762                        //bb_error_msg("doing %d > %d", fd, newfd);
5763                        newfd = redir->ndup.dupfd;
5764                        close_fd = -1;
5765                } else {
5766                        newfd = openredirect(redir); /* always >= 0 */
5767                        if (fd == newfd) {
5768                                /* open() gave us precisely the fd we wanted.
5769                                 * This means that this fd was not busy
5770                                 * (not opened to anywhere).
5771                                 * Remember to close it on restore:
5772                                 */
5773                                add_squirrel_closed(sv, fd);
5774                                continue;
5775                        }
5776                        close_fd = newfd;
5777                }
5778
5779                if (fd == newfd)
5780                        continue;
5781
5782                /* if "N>FILE": move newfd to fd */
5783                /* if "N>&M": dup newfd to fd */
5784                /* if "N>&-": close fd (newfd is -1) */
5785
5786 IF_BASH_REDIR_OUTPUT(redirect_more:)
5787
5788                closed = save_fd_on_redirect(fd, /*avoid:*/ newfd, sv);
5789                if (newfd == -1) {
5790                        /* "N>&-" means "close me" */
5791                        if (!closed) {
5792                                /* ^^^ optimization: saving may already
5793                                 * have closed it. If not... */
5794                                close(fd);
5795                        }
5796                } else {
5797                        /* if newfd is a script fd or saved fd, simulate EBADF */
5798                        if (internally_opened_fd(newfd, sv)) {
5799                                errno = EBADF;
5800                                ash_msg_and_raise_perror("%d", newfd);
5801                        }
5802                        dup2_or_raise(newfd, fd);
5803                        if (close_fd >= 0) /* "N>FILE" or ">&FILE" or heredoc? */
5804                                close(close_fd);
5805#if BASH_REDIR_OUTPUT
5806                        if (redir->nfile.type == NTO2 && fd == 1) {
5807                                /* ">&FILE". we already redirected to 1, now copy 1 to 2 */
5808                                fd = 2;
5809                                newfd = 1;
5810                                close_fd = -1;
5811                                goto redirect_more;
5812                        }
5813#endif
5814                }
5815        } while ((redir = redir->nfile.next) != NULL);
5816        INT_ON;
5817
5818//dash:#define REDIR_SAVEFD2 03        /* set preverrout */
5819#define REDIR_SAVEFD2 0
5820        // dash has a bug: since REDIR_SAVEFD2=3 and REDIR_PUSH=1, this test
5821        // triggers for pure REDIR_PUSH too. Thus, this is done almost always,
5822        // not only for calls with flags containing REDIR_SAVEFD2.
5823        // We do this unconditionally (see save_fd_on_redirect()).
5824        //if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
5825        //      preverrout_fd = copied_fd2;
5826}
5827
5828static int
5829redirectsafe(union node *redir, int flags)
5830{
5831        int err;
5832        volatile int saveint;
5833        struct jmploc *volatile savehandler = exception_handler;
5834        struct jmploc jmploc;
5835
5836        SAVE_INT(saveint);
5837        /* "echo 9>/dev/null; echo >&9; echo result: $?" - result should be 1, not 2! */
5838        err = setjmp(jmploc.loc); /* was = setjmp(jmploc.loc) * 2; */
5839        if (!err) {
5840                exception_handler = &jmploc;
5841                redirect(redir, flags);
5842        }
5843        exception_handler = savehandler;
5844        if (err && exception_type != EXERROR)
5845                longjmp(exception_handler->loc, 1);
5846        RESTORE_INT(saveint);
5847        return err;
5848}
5849
5850static struct redirtab*
5851pushredir(union node *redir)
5852{
5853        struct redirtab *sv;
5854        int i;
5855
5856        if (!redir)
5857                return redirlist;
5858
5859        i = 0;
5860        do {
5861                i++;
5862#if BASH_REDIR_OUTPUT
5863                if (redir->nfile.type == NTO2)
5864                        i++;
5865#endif
5866                redir = redir->nfile.next;
5867        } while (redir);
5868
5869        sv = ckzalloc(sizeof(*sv) + i * sizeof(sv->two_fd[0]));
5870        sv->pair_count = i;
5871        while (--i >= 0)
5872                sv->two_fd[i].orig_fd = sv->two_fd[i].moved_to = EMPTY;
5873        sv->next = redirlist;
5874        redirlist = sv;
5875        return sv->next;
5876}
5877
5878/*
5879 * Undo the effects of the last redirection.
5880 */
5881static void
5882popredir(int drop)
5883{
5884        struct redirtab *rp;
5885        int i;
5886
5887        if (redirlist == NULL)
5888                return;
5889        INT_OFF;
5890        rp = redirlist;
5891        for (i = 0; i < rp->pair_count; i++) {
5892                int fd = rp->two_fd[i].orig_fd;
5893                int copy = rp->two_fd[i].moved_to;
5894                if (copy == CLOSED) {
5895                        if (!drop)
5896                                close(fd);
5897                        continue;
5898                }
5899                if (copy != EMPTY) {
5900                        if (!drop) {
5901                                /*close(fd);*/
5902                                dup2_or_raise(copy, fd);
5903                        }
5904                        close(copy);
5905                }
5906        }
5907        redirlist = rp->next;
5908        free(rp);
5909        INT_ON;
5910}
5911
5912static void
5913unwindredir(struct redirtab *stop)
5914{
5915        while (redirlist != stop)
5916                popredir(/*drop:*/ 0);
5917}
5918
5919
5920/* ============ Routines to expand arguments to commands
5921 *
5922 * We have to deal with backquotes, shell variables, and file metacharacters.
5923 */
5924
5925#if ENABLE_FEATURE_SH_MATH
5926static arith_t
5927ash_arith(const char *s)
5928{
5929        arith_state_t math_state;
5930        arith_t result;
5931
5932        math_state.lookupvar = lookupvar;
5933        math_state.setvar    = setvar0;
5934        //math_state.endofname = endofname;
5935
5936        INT_OFF;
5937        result = arith(&math_state, s);
5938        if (math_state.errmsg)
5939                ash_msg_and_raise_error(math_state.errmsg);
5940        INT_ON;
5941
5942        return result;
5943}
5944#endif
5945#if BASH_SUBSTR
5946# if ENABLE_FEATURE_SH_MATH
5947static int substr_atoi(const char *s)
5948{
5949        arith_t t = ash_arith(s);
5950        if (sizeof(t) > sizeof(int)) {
5951                /* clamp very large or very large negative nums for ${v:N:M}:
5952                 * else "${v:0:0x100000001}" would work as "${v:0:1}"
5953                 */
5954                if (t > INT_MAX)
5955                        t = INT_MAX;
5956                if (t < INT_MIN)
5957                        t = INT_MIN;
5958        }
5959        return t;
5960}
5961# else
5962#  define substr_atoi(s) number(s)
5963# endif
5964#endif
5965
5966/*
5967 * expandarg flags
5968 */
5969#define EXP_FULL        0x1     /* perform word splitting & file globbing */
5970#define EXP_TILDE       0x2     /* do normal tilde expansion */
5971#define EXP_VARTILDE    0x4     /* expand tildes in an assignment */
5972#define EXP_REDIR       0x8     /* file glob for a redirection (1 match only) */
5973/* ^^^^^^^^^^^^^^ this is meant to support constructs such as "cmd >file*.txt"
5974 * POSIX says for this case:
5975 *  Pathname expansion shall not be performed on the word by a
5976 *  non-interactive shell; an interactive shell may perform it, but shall
5977 *  do so only when the expansion would result in one word.
5978 * Currently, our code complies to the above rule by never globbing
5979 * redirection filenames.
5980 * Bash performs globbing, unless it is non-interactive and in POSIX mode.
5981 * (this means that on a typical Linux distro, bash almost always
5982 * performs globbing, and thus diverges from what we do).
5983 */
5984#define EXP_CASE        0x10    /* keeps quotes around for CASE pattern */
5985#define EXP_VARTILDE2   0x20    /* expand tildes after colons only */
5986#define EXP_WORD        0x40    /* expand word in parameter expansion */
5987#define EXP_QUOTED      0x100   /* expand word in double quotes */
5988/*
5989 * rmescape() flags
5990 */
5991#define RMESCAPE_ALLOC  0x1     /* Allocate a new string */
5992#define RMESCAPE_GLOB   0x2     /* Add backslashes for glob */
5993#define RMESCAPE_GROW   0x8     /* Grow strings instead of stalloc */
5994#define RMESCAPE_HEAP   0x10    /* Malloc strings instead of stalloc */
5995
5996/* Add CTLESC when necessary. */
5997#define QUOTES_ESC     (EXP_FULL | EXP_CASE)
5998/* Do not skip NUL characters. */
5999#define QUOTES_KEEPNUL EXP_TILDE
6000
6001/*
6002 * Structure specifying which parts of the string should be searched
6003 * for IFS characters.
6004 */
6005struct ifsregion {
6006        struct ifsregion *next; /* next region in list */
6007        int begoff;             /* offset of start of region */
6008        int endoff;             /* offset of end of region */
6009        int nulonly;            /* search for nul bytes only */
6010};
6011
6012struct arglist {
6013        struct strlist *list;
6014        struct strlist **lastp;
6015};
6016
6017/* output of current string */
6018static char *expdest;
6019/* list of back quote expressions */
6020static struct nodelist *argbackq;
6021/* first struct in list of ifs regions */
6022static struct ifsregion ifsfirst;
6023/* last struct in list */
6024static struct ifsregion *ifslastp;
6025/* holds expanded arg list */
6026static struct arglist exparg;
6027
6028/*
6029 * Our own itoa().
6030 * cvtnum() is used even if math support is off (to prepare $? values and such).
6031 */
6032static int
6033cvtnum(arith_t num)
6034{
6035        int len;
6036
6037        /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6038        len = sizeof(arith_t) * 3;
6039        /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6040        if (sizeof(arith_t) < 4) len += 2;
6041
6042        expdest = makestrspace(len, expdest);
6043        len = fmtstr(expdest, len, ARITH_FMT, num);
6044        STADJUST(len, expdest);
6045        return len;
6046}
6047
6048/*
6049 * Break the argument string into pieces based upon IFS and add the
6050 * strings to the argument list.  The regions of the string to be
6051 * searched for IFS characters have been stored by recordregion.
6052 */
6053static void
6054ifsbreakup(char *string, struct arglist *arglist)
6055{
6056        struct ifsregion *ifsp;
6057        struct strlist *sp;
6058        char *start;
6059        char *p;
6060        char *q;
6061        const char *ifs, *realifs;
6062        int ifsspc;
6063        int nulonly;
6064
6065        start = string;
6066        if (ifslastp != NULL) {
6067                ifsspc = 0;
6068                nulonly = 0;
6069                realifs = ifsset() ? ifsval() : defifs;
6070                ifsp = &ifsfirst;
6071                do {
6072                        int afternul;
6073
6074                        p = string + ifsp->begoff;
6075                        afternul = nulonly;
6076                        nulonly = ifsp->nulonly;
6077                        ifs = nulonly ? nullstr : realifs;
6078                        ifsspc = 0;
6079                        while (p < string + ifsp->endoff) {
6080                                q = p;
6081                                if ((unsigned char)*p == CTLESC)
6082                                        p++;
6083                                if (!strchr(ifs, *p)) {
6084                                        p++;
6085                                        continue;
6086                                }
6087                                if (!(afternul || nulonly))
6088                                        ifsspc = (strchr(defifs, *p) != NULL);
6089                                /* Ignore IFS whitespace at start */
6090                                if (q == start && ifsspc) {
6091                                        p++;
6092                                        start = p;
6093                                        continue;
6094                                }
6095                                *q = '\0';
6096                                sp = stzalloc(sizeof(*sp));
6097                                sp->text = start;
6098                                *arglist->lastp = sp;
6099                                arglist->lastp = &sp->next;
6100                                p++;
6101                                if (!nulonly) {
6102                                        for (;;) {
6103                                                if (p >= string + ifsp->endoff) {
6104                                                        break;
6105                                                }
6106                                                q = p;
6107                                                if ((unsigned char)*p == CTLESC)
6108                                                        p++;
6109                                                if (strchr(ifs, *p) == NULL) {
6110                                                        p = q;
6111                                                        break;
6112                                                }
6113                                                if (strchr(defifs, *p) == NULL) {
6114                                                        if (ifsspc) {
6115                                                                p++;
6116                                                                ifsspc = 0;
6117                                                        } else {
6118                                                                p = q;
6119                                                                break;
6120                                                        }
6121                                                } else
6122                                                        p++;
6123                                        }
6124                                }
6125                                start = p;
6126                        } /* while */
6127                        ifsp = ifsp->next;
6128                } while (ifsp != NULL);
6129                if (nulonly)
6130                        goto add;
6131        }
6132
6133        if (!*start)
6134                return;
6135
6136 add:
6137        sp = stzalloc(sizeof(*sp));
6138        sp->text = start;
6139        *arglist->lastp = sp;
6140        arglist->lastp = &sp->next;
6141}
6142
6143static void
6144ifsfree(void)
6145{
6146        struct ifsregion *p = ifsfirst.next;
6147
6148        if (!p)
6149                goto out;
6150
6151        INT_OFF;
6152        do {
6153                struct ifsregion *ifsp;
6154                ifsp = p->next;
6155                free(p);
6156                p = ifsp;
6157        } while (p);
6158        ifsfirst.next = NULL;
6159        INT_ON;
6160 out:
6161        ifslastp = NULL;
6162}
6163
6164static size_t
6165esclen(const char *start, const char *p)
6166{
6167        size_t esc = 0;
6168
6169        while (p > start && (unsigned char)*--p == CTLESC) {
6170                esc++;
6171        }
6172        return esc;
6173}
6174
6175/*
6176 * Remove any CTLESC characters from a string.
6177 */
6178#if !BASH_PATTERN_SUBST
6179#define rmescapes(str, flag, slash_position) \
6180        rmescapes(str, flag)
6181#endif
6182static char *
6183rmescapes(char *str, int flag, int *slash_position)
6184{
6185        static const char qchars[] ALIGN1 = {
6186                IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' };
6187
6188        char *p, *q, *r;
6189        unsigned protect_against_glob;
6190        unsigned globbing;
6191
6192        p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash_position));
6193        if (!p)
6194                return str;
6195
6196        q = p;
6197        r = str;
6198        if (flag & RMESCAPE_ALLOC) {
6199                size_t len = p - str;
6200                size_t fulllen = len + strlen(p) + 1;
6201
6202                if (flag & RMESCAPE_GROW) {
6203                        int strloc = str - (char *)stackblock();
6204                        r = makestrspace(fulllen, expdest);
6205                        /* p and str may be invalidated by makestrspace */
6206                        str = (char *)stackblock() + strloc;
6207                        p = str + len;
6208                } else if (flag & RMESCAPE_HEAP) {
6209                        r = ckmalloc(fulllen);
6210                } else {
6211                        r = stalloc(fulllen);
6212                }
6213                q = r;
6214                if (len > 0) {
6215                        q = (char *)mempcpy(q, str, len);
6216                }
6217        }
6218
6219        globbing = flag & RMESCAPE_GLOB;
6220        protect_against_glob = globbing;
6221        while (*p) {
6222                if ((unsigned char)*p == CTLQUOTEMARK) {
6223// Note: protect_against_glob only affect whether
6224// CTLESC,<ch> gets converted to <ch> or to \<ch>
6225                        p++;
6226                        protect_against_glob = globbing;
6227                        continue;
6228                }
6229                if (*p == '\\') {
6230                        /* naked back slash */
6231                        protect_against_glob = 0;
6232                        goto copy;
6233                }
6234                if ((unsigned char)*p == CTLESC) {
6235                        p++;
6236#if DEBUG
6237                        if (*p == '\0')
6238                                ash_msg_and_raise_error("CTLESC at EOL (shouldn't happen)");
6239#endif
6240                        if (protect_against_glob) {
6241                                /*
6242                                 * We used to trust glob() and fnmatch() to eat
6243                                 * superfluous escapes (\z where z has no
6244                                 * special meaning anyway). But this causes
6245                                 * bugs such as string of one greek letter rho
6246                                 * (unicode-encoded as two bytes "cf,81")
6247                                 * getting encoded as "cf,CTLESC,81"
6248                                 * and here, converted to "cf,\,81" -
6249                                 * which does not go well with some flavors
6250                                 * of fnmatch() in unicode locales
6251                                 * (for example, glibc <= 2.22).
6252                                 *
6253                                 * Lets add "\" only on the chars which need it.
6254                                 * Testcases for less obvious chars are shown.
6255                                 */
6256                                if (*p == '*'
6257                                 || *p == '?'
6258                                 || *p == '['
6259                                 || *p == '\\' /* case '\' in \\    ) echo ok;; *) echo WRONG;; esac */
6260                                 || *p == ']'  /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
6261                                 || *p == '-'  /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
6262                                 || *p == '!'  /* case '!' in [\!]  ) echo ok;; *) echo WRONG;; esac */
6263                                /* Some libc support [^negate], that's why "^" also needs love */
6264                                 || *p == '^'  /* case '^' in [\^]  ) echo ok;; *) echo WRONG;; esac */
6265                                ) {
6266                                        *q++ = '\\';
6267                                }
6268                        }
6269                }
6270#if BASH_PATTERN_SUBST
6271                else if (slash_position && p == str + *slash_position) {
6272                        /* stop handling globbing */
6273                        globbing = 0;
6274                        *slash_position = q - r;
6275                        slash_position = NULL;
6276                }
6277#endif
6278                protect_against_glob = globbing;
6279 copy:
6280                *q++ = *p++;
6281        }
6282        *q = '\0';
6283        if (flag & RMESCAPE_GROW) {
6284                expdest = r;
6285                STADJUST(q - r + 1, expdest);
6286        }
6287        return r;
6288}
6289#define pmatch(a, b) !fnmatch((a), (b), 0)
6290
6291/*
6292 * Prepare a pattern for a expmeta (internal glob(3)) call.
6293 *
6294 * Returns an stalloced string.
6295 */
6296static char *
6297preglob(const char *pattern, int flag)
6298{
6299        return rmescapes((char *)pattern, flag | RMESCAPE_GLOB, NULL);
6300}
6301
6302/*
6303 * Put a string on the stack.
6304 */
6305static void
6306memtodest(const char *p, size_t len, int syntax, int quotes)
6307{
6308        char *q;
6309
6310        if (!len)
6311                return;
6312
6313        q = makestrspace((quotes & QUOTES_ESC) ? len * 2 : len, expdest);
6314
6315        do {
6316                unsigned char c = *p++;
6317                if (c) {
6318                        if (quotes & QUOTES_ESC) {
6319                                int n = SIT(c, syntax);
6320                                if (n == CCTL
6321                                 || (syntax != BASESYNTAX && n == CBACK)
6322                                ) {
6323                                        USTPUTC(CTLESC, q);
6324                                }
6325                        }
6326                } else if (!(quotes & QUOTES_KEEPNUL))
6327                        continue;
6328                USTPUTC(c, q);
6329        } while (--len);
6330
6331        expdest = q;
6332}
6333
6334static size_t
6335strtodest(const char *p, int syntax, int quotes)
6336{
6337        size_t len = strlen(p);
6338        memtodest(p, len, syntax, quotes);
6339        return len;
6340}
6341
6342/*
6343 * Record the fact that we have to scan this region of the
6344 * string for IFS characters.
6345 */
6346static void
6347recordregion(int start, int end, int nulonly)
6348{
6349        struct ifsregion *ifsp;
6350
6351        if (ifslastp == NULL) {
6352                ifsp = &ifsfirst;
6353        } else {
6354                INT_OFF;
6355                ifsp = ckzalloc(sizeof(*ifsp));
6356                /*ifsp->next = NULL; - ckzalloc did it */
6357                ifslastp->next = ifsp;
6358                INT_ON;
6359        }
6360        ifslastp = ifsp;
6361        ifslastp->begoff = start;
6362        ifslastp->endoff = end;
6363        ifslastp->nulonly = nulonly;
6364}
6365
6366static void
6367removerecordregions(int endoff)
6368{
6369        if (ifslastp == NULL)
6370                return;
6371
6372        if (ifsfirst.endoff > endoff) {
6373                while (ifsfirst.next) {
6374                        struct ifsregion *ifsp;
6375                        INT_OFF;
6376                        ifsp = ifsfirst.next->next;
6377                        free(ifsfirst.next);
6378                        ifsfirst.next = ifsp;
6379                        INT_ON;
6380                }
6381                if (ifsfirst.begoff > endoff) {
6382                        ifslastp = NULL;
6383                } else {
6384                        ifslastp = &ifsfirst;
6385                        ifsfirst.endoff = endoff;
6386                }
6387                return;
6388        }
6389
6390        ifslastp = &ifsfirst;
6391        while (ifslastp->next && ifslastp->next->begoff < endoff)
6392                ifslastp = ifslastp->next;
6393        while (ifslastp->next) {
6394                struct ifsregion *ifsp;
6395                INT_OFF;
6396                ifsp = ifslastp->next->next;
6397                free(ifslastp->next);
6398                ifslastp->next = ifsp;
6399                INT_ON;
6400        }
6401        if (ifslastp->endoff > endoff)
6402                ifslastp->endoff = endoff;
6403}
6404
6405static char *
6406exptilde(char *startp, char *p, int flags)
6407{
6408        unsigned char c;
6409        char *name;
6410        struct passwd *pw;
6411        const char *home;
6412        int quotes = flags & QUOTES_ESC;
6413
6414        name = p + 1;
6415
6416        while ((c = *++p) != '\0') {
6417                switch (c) {
6418                case CTLESC:
6419                        return startp;
6420                case CTLQUOTEMARK:
6421                        return startp;
6422                case ':':
6423                        if (flags & EXP_VARTILDE)
6424                                goto done;
6425                        break;
6426                case '/':
6427                case CTLENDVAR:
6428                        goto done;
6429                }
6430        }
6431 done:
6432        *p = '\0';
6433        if (*name == '\0') {
6434                home = lookupvar("HOME");
6435        } else {
6436                pw = getpwnam(name);
6437                if (pw == NULL)
6438                        goto lose;
6439                home = pw->pw_dir;
6440        }
6441        if (!home || !*home)
6442                goto lose;
6443        *p = c;
6444        strtodest(home, SQSYNTAX, quotes);
6445        return p;
6446 lose:
6447        *p = c;