toybox/toys/pending/sh.c
<<
>>
Prefs
   1/* sh.c - toybox shell
   2 *
   3 * Copyright 2006 Rob Landley <rob@landley.net>
   4 *
   5 * This shell aims for bash compatibility. The bash man page is at:
   6 * http://man7.org/linux/man-pages/man1/bash.1.html
   7 *
   8 * The POSIX-2008/SUSv4 shell spec is at:
   9 * http://opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
  10 * and http://opengroup.org/onlinepubs/9699919799/utilities/sh.html
  11 *
  12 * deviations from posix: don't care about $LANG or $LC_ALL
  13
  14 * builtins: alias bg command fc fg getopts jobs newgrp read umask unalias wait
  15 *          disown suspend source pushd popd dirs logout times trap cd hash exit
  16 *           unset local export readonly set : . let history declare ulimit type
  17 * "special" builtins: break continue eval exec return shift
  18 * external with extra shell behavior: kill pwd time test
  19
  20 * * ? [ # ~ = % [[ ]] function select exit label:
  21
  22 * TODO: case, wildcard +(*|?), job control (find_plus_minus), ${x//}, $(())
  23
  24 * TODO: support case in $() because $(case a in a) ;; ; esac) stops at first )
  25 * TODO: test exit from "trap EXIT" doesn't recurse
  26 * TODO: ! history expansion
  27 * TODO: getuid() vs geteuid()
  28 * TODO: test that $PS1 color changes work without stupid \[ \] hack
  29 * TODO: Handle embedded NUL bytes in the command line? (When/how?)
  30 * TODO: set -e -u -o pipefail, shopt -s nullglob
  31 *
  32 * bash man page:
  33 * control operators || & && ; ;; ;& ;;& ( ) | |& <newline>
  34 * reserved words
  35 *   ! case  coproc  do done elif else esac fi for  function  if  in  select
  36 *   then until while { } time [[ ]]
  37 *
  38 * Flow control statements:
  39 *
  40 * if/then/elif/else/fi, for select while until/do/done, case/esac,
  41 * {/}, [[/]], (/), function assignment
  42
  43USE_SH(NEWTOY(cd, ">1LP[-LP]", TOYFLAG_NOFORK))
  44USE_SH(NEWTOY(eval, 0, TOYFLAG_NOFORK))
  45USE_SH(NEWTOY(exec, "^cla:", TOYFLAG_NOFORK))
  46USE_SH(NEWTOY(exit, 0, TOYFLAG_NOFORK))
  47USE_SH(NEWTOY(export, "np", TOYFLAG_NOFORK))
  48USE_SH(NEWTOY(shift, ">1", TOYFLAG_NOFORK))
  49USE_SH(NEWTOY(source, "<1", TOYFLAG_NOFORK))
  50USE_SH(OLDTOY(., source, TOYFLAG_NOFORK))
  51USE_SH(NEWTOY(unset, "fvn", TOYFLAG_NOFORK))
  52
  53USE_SH(NEWTOY(sh, "(noediting)(noprofile)(norc)sc:i", TOYFLAG_BIN))
  54USE_SH(OLDTOY(toysh, sh, TOYFLAG_BIN))
  55USE_SH(OLDTOY(bash, sh, TOYFLAG_BIN))
  56// Login lies in argv[0], so add some aliases to catch that
  57USE_SH(OLDTOY(-sh, sh, 0))
  58USE_SH(OLDTOY(-toysh, sh, 0))
  59USE_SH(OLDTOY(-bash, sh, 0))
  60
  61config SH
  62  bool "sh (toysh)"
  63  default n
  64  help
  65    usage: sh [-c command] [script]
  66
  67    Command shell.  Runs a shell script, or reads input interactively
  68    and responds to it.
  69
  70    -c  command line to execute
  71    -i  interactive mode (default when STDIN is a tty)
  72
  73# These are here for the help text, they're not selectable and control nothing
  74config CD
  75  bool
  76  default n
  77  depends on SH
  78  help
  79    usage: cd [-PL] [path]
  80
  81    Change current directory.  With no arguments, go $HOME.
  82
  83    -P  Physical path: resolve symlinks in path
  84    -L  Local path: .. trims directories off $PWD (default)
  85
  86config EXIT
  87  bool
  88  default n
  89  depends on SH
  90  help
  91    usage: exit [status]
  92
  93    Exit shell.  If no return value supplied on command line, use value
  94    of most recent command, or 0 if none.
  95
  96config UNSET
  97  bool
  98  default n
  99  depends on SH
 100  help
 101    usage: unset [-fvn] NAME...
 102
 103    -f  NAME is a function
 104    -v  NAME is a variable
 105    -n  dereference NAME and unset that
 106
 107config EVAL
 108  bool
 109  default n
 110  depends on SH
 111  help
 112    usage: eval COMMAND...
 113
 114    Execute (combined) arguments as a shell command.
 115
 116config EXEC
 117  bool
 118  default n
 119  depends on SH
 120  help
 121    usage: exec [-cl] [-a NAME] COMMAND...
 122
 123    -a  set argv[0] to NAME
 124    -c  clear environment
 125    -l  prepend - to argv[0]
 126
 127config EXPORT
 128  bool
 129  default n
 130  depends on SH
 131  help
 132    usage: export [-n] [NAME[=VALUE]...]
 133
 134    Make variables available to child processes. NAME exports existing local
 135    variable(s), NAME=VALUE sets and exports.
 136
 137    -n  Unexport. Turn listed variable(s) into local variables.
 138
 139    With no arguments list exported variables/attributes as "declare" statements.
 140
 141config JOBS
 142  bool
 143  default n
 144  depends on SH
 145  help
 146    usage: jobs [-lnprs] [%JOB | -x COMMAND...]
 147
 148    List running/stopped background jobs.
 149
 150    -l Include process ID in list
 151    -n Show only new/changed processes
 152    -p Show process IDs only
 153    -r Show running processes
 154    -s Show stopped processes
 155
 156config SHIFT
 157  bool
 158  default n
 159  depends on SH
 160  help
 161    usage: shift [N]
 162
 163    Skip N (default 1) positional parameters, moving $1 and friends along the list.
 164    Does not affect $0.
 165
 166config SOURCE
 167  bool
 168  default n
 169  depends on SH
 170  help
 171    usage: source FILE [ARGS...]
 172
 173    Read FILE and execute commands. Any ARGS become positional parameters.
 174*/
 175
 176#define FOR_sh
 177#include "toys.h"
 178
 179GLOBALS(
 180  union {
 181    struct {
 182      char *c;
 183    } sh;
 184    struct {
 185      char *a;
 186    } exec;
 187  };
 188
 189  // keep lineno here: used to work around compiler limitation in run_command()
 190  long lineno;
 191  char *ifs, *isexec, *wcpat;
 192  unsigned options, jobcnt;
 193  int hfd, pid, bangpid, varslen, shift, cdcount;
 194  long long SECONDS;
 195
 196  // global and local variables
 197  struct sh_vars {
 198    long flags;
 199    char *str;
 200  } *vars;
 201
 202  // Parsed functions
 203  struct sh_function {
 204    char *name;
 205    struct sh_pipeline {  // pipeline segments
 206      struct sh_pipeline *next, *prev, *end;
 207      int count, here, type; // TODO abuse type to replace count during parsing
 208      struct sh_arg {
 209        char **v;
 210        int c;
 211      } arg[1];
 212    } *pipeline;
 213    struct double_list *expect; // should be zero at end of parsing
 214  } *functions;
 215
 216// TODO ctrl-Z suspend should stop script
 217  struct sh_process {
 218    struct sh_process *next, *prev; // | && ||
 219    struct arg_list *delete;   // expanded strings
 220    // undo redirects, a=b at start, child PID, exit status, has !, job #
 221    int *urd, envlen, pid, exit, not, job;
 222    long long when; // when job backgrounded/suspended
 223    struct sh_arg *raw, arg;
 224  } *pp; // currently running process
 225
 226  // job list, command line for $*, scratch space for do_wildcard_files()
 227  struct sh_arg jobs, *arg, *wcdeck;
 228)
 229
 230// Can't yet avoid this prototype. Fundamental problem is $($($(blah))) nests,
 231// leading to function loop with run->parse->run
 232static int sh_run(char *new);
 233
 234// ordered for greedy matching, so >&; becomes >& ; not > &;
 235// making these const means I need to typecast the const away later to
 236// avoid endless warnings.
 237static const char *redirectors[] = {"<<<", "<<-", "<<", "<&", "<>", "<", ">>",
 238  ">&", ">|", ">", "&>>", "&>", 0};
 239
 240#define OPT_I           1
 241#define OPT_BRACE       2   // set -B
 242#define OPT_NOCLOBBER   4   // set -C
 243#define OPT_S           8
 244#define OPT_C          16
 245
 246static void syntax_err(char *s)
 247{
 248  error_msg("syntax error: %s", s);
 249  toys.exitval = 2;
 250  if (!(TT.options&OPT_I)) xexit();
 251}
 252
 253// append to array with null terminator and realloc as necessary
 254static void arg_add(struct sh_arg *arg, char *data)
 255{
 256  // expand with stride 32. Micro-optimization: don't realloc empty stack
 257  if (!(arg->c&31) && (arg->c || !arg->v))
 258    arg->v = xrealloc(arg->v, sizeof(char *)*(arg->c+33));
 259  arg->v[arg->c++] = data;
 260  arg->v[arg->c] = 0;
 261}
 262
 263// add argument to an arg_list
 264static char *push_arg(struct arg_list **list, char *arg)
 265{
 266  struct arg_list *al;
 267
 268  if (list) {
 269    al = xmalloc(sizeof(struct arg_list));
 270    al->next = *list;
 271    al->arg = arg;
 272    *list = al;
 273  }
 274
 275  return arg;
 276}
 277
 278static void arg_add_del(struct sh_arg *arg, char *data,struct arg_list **delete)
 279{
 280  arg_add(arg, push_arg(delete, data));
 281}
 282
 283// return length of valid variable name
 284static char *varend(char *s)
 285{
 286  if (isdigit(*s)) return s;
 287  while (*s>' ' && (*s=='_' || !ispunct(*s))) s++;
 288
 289  return s;
 290}
 291
 292// Return index of variable within this list
 293static struct sh_vars *findvar(char *name)
 294{
 295  int len = varend(name)-name;
 296  struct sh_vars *var = TT.vars+TT.varslen;
 297
 298  if (len) while (var-- != TT.vars) 
 299    if (!strncmp(var->str, name, len) && var->str[len] == '=') return var;
 300
 301  return 0;
 302}
 303
 304// Append variable to TT.vars, returning *struct. Does not check duplicates.
 305static struct sh_vars *addvar(char *s)
 306{
 307  if (!(TT.varslen&31))
 308    TT.vars = xrealloc(TT.vars, (TT.varslen+32)*sizeof(*TT.vars));
 309  TT.vars[TT.varslen].flags = 0;
 310  TT.vars[TT.varslen].str = s;
 311
 312  return TT.vars+TT.varslen++;
 313}
 314
 315// TODO function to resolve a string into a number for $((1+2)) etc
 316long long do_math(char **s)
 317{
 318  long long ll;
 319
 320  while (isspace(**s)) ++*s;
 321  ll = strtoll(*s, s, 0);
 322  while (isspace(**s)) ++*s;
 323
 324  return ll;
 325}
 326
 327// Assign one variable from malloced key=val string, returns var struct
 328// TODO implement remaining types
 329#define VAR_DICT      256
 330#define VAR_ARRAY     128
 331#define VAR_INT       64
 332#define VAR_TOLOWER   32
 333#define VAR_TOUPPER   16
 334#define VAR_NAMEREF   8
 335#define VAR_GLOBAL    4
 336#define VAR_READONLY  2
 337#define VAR_MAGIC     1
 338
 339// declare -aAilnrux
 340// ft
 341static struct sh_vars *setvar(char *s)
 342{
 343  int len = varend(s)-s;
 344  long flags;
 345  struct sh_vars *var;
 346
 347  if (s[len] != '=') {
 348    error_msg("bad setvar %s\n", s);
 349    free(s);
 350
 351    return 0;
 352  }
 353  if (!strncmp(s, "IFS=", 4)) TT.ifs = s+4;
 354  if (!(var = findvar(s))) return addvar(s);
 355  flags = var->flags;
 356
 357  if (flags&VAR_READONLY) {
 358    error_msg("%.*s: read only", len, s);
 359    free(s);
 360
 361    return 0;
 362  }
 363
 364// TODO if (flags&(VAR_TOUPPER|VAR_TOLOWER)) 
 365// unicode _is stupid enough for upper/lower case to be different utf8 byte
 366// lengths. example: lowercase of U+0130 (C4 B0) is U+0069 (69)
 367// TODO VAR_INT
 368// TODO VAR_ARRAY VAR_DICT
 369
 370  if (flags&VAR_MAGIC) {
 371    char *ss = s+len-1;
 372
 373// TODO: trailing garbage after do_math()?
 374    if (*s == 'S') TT.SECONDS = millitime() - 1000*do_math(&ss);
 375    else if (*s == 'R') srandom(do_math(&ss));
 376  } else if (flags&VAR_GLOBAL) xsetenv(var->str = s, 0);
 377  else {
 378    free(var->str);
 379    var->str = s;
 380  }
 381
 382  return var;
 383}
 384
 385static void unsetvar(char *name)
 386{
 387  struct sh_vars *var = findvar(name);
 388  int ii = var-TT.vars;
 389
 390  if (!var) return;
 391  if (var->flags&VAR_GLOBAL) xunsetenv(name);
 392  else free(var->str);
 393
 394  memmove(TT.vars+ii, TT.vars+ii+1, TT.varslen-ii);
 395  TT.varslen--;
 396}
 397
 398static struct sh_vars *setvarval(char *name, char *val)
 399{
 400  return setvar(xmprintf("%s=%s", name, val));
 401}
 402
 403// get value of variable starting at s.
 404static char *getvar(char *s)
 405{
 406  struct sh_vars *var = findvar(s);
 407
 408  if (!var) return 0;
 409
 410  if (var->flags & VAR_MAGIC) {
 411    char c = *var->str;
 412
 413    if (c == 'S') sprintf(toybuf, "%lld", (millitime()-TT.SECONDS)/1000);
 414    else if (c == 'R') sprintf(toybuf, "%ld", random()&((1<<16)-1));
 415    else if (c == 'L') sprintf(toybuf, "%ld", TT.lineno);
 416    else if (c == 'G') sprintf(toybuf, "TODO: GROUPS");
 417
 418    return toybuf;
 419  }
 420
 421  return varend(var->str)+1;
 422}
 423
 424// malloc declare -x "escaped string"
 425static char *declarep(struct sh_vars *var)
 426{
 427  char *types = "-rgnuliaA", *in = types, flags[16], *out = flags, *ss;
 428  int len;
 429
 430  while (*++in) if (var->flags&(1<<(in-types))) *out++ = *in;
 431  if (in == types) *out++ = *types;
 432  *out = 0;
 433  len = out-flags;
 434
 435  for (in = types = varend(var->str); *in; in++) len += !!strchr("$\"\\`", *in);
 436  len += in-types;
 437  ss = xmalloc(len+15);
 438
 439  out = ss + sprintf(ss, "declare -%s \"", out);
 440  while (*types) {
 441    if (strchr("$\"\\`", *types)) *out++ = '\\';
 442    *out++ = *types++;
 443  }
 444  *out++ = '"';
 445  *out = 0;
 446 
 447  return ss; 
 448}
 449
 450// return length of match found at this point (try is null terminated array)
 451static int anystart(char *s, char **try)
 452{
 453  char *ss = s;
 454
 455  while (*try) if (strstart(&s, *try++)) return s-ss;
 456
 457  return 0;
 458}
 459
 460// does this entire string match one of the strings in try[]
 461static int anystr(char *s, char **try)
 462{
 463  while (*try) if (!strcmp(s, *try++)) return 1;
 464
 465  return 0;
 466}
 467
 468// return length of valid prefix that could go before redirect
 469static int redir_prefix(char *word)
 470{
 471  char *s = word;
 472
 473  if (*s == '{') {
 474    if (*(s = varend(s+1)) == '}' && s != word+1) s++;
 475    else s = word;
 476  } else while (isdigit(*s)) s++;
 477
 478  return s-word;
 479}
 480
 481// parse next word from command line. Returns end, or 0 if need continuation
 482// caller eats leading spaces. early = skip one quote block (or return start)
 483// quote is depth of existing quote stack in toybuf (usually 0)
 484static char *parse_word(char *start, int early, int quote)
 485{
 486  int i, q, qc = 0;
 487  char *end = start, *s;
 488
 489  // Things we should only return at the _start_ of a word
 490
 491  if (strstart(&end, "<(") || strstart(&end, ">(")) toybuf[quote++]=')';
 492
 493  // Redirections. 123<<file- parses as 2 args: "123<<" "file-".
 494  s = end + redir_prefix(end);
 495  if ((i = anystart(s, (void *)redirectors))) return s+i;
 496
 497  // (( is a special quote at the start of a word
 498  if (strstart(&end, "((")) toybuf[quote++] = 254;
 499
 500  // find end of this word
 501  while (*end) {
 502    i = 0;
 503
 504    // barf if we're near overloading quote stack (nesting ridiculously deep)
 505    if (quote>4000) {
 506      syntax_err("tilt");
 507      return (void *)1;
 508    }
 509
 510    // Handle quote contexts
 511    if ((q = quote ? toybuf[quote-1] : 0)) {
 512
 513      // when waiting for parentheses, they nest
 514      if ((q == ')' || q >= 254) && (*end == '(' || *end == ')')) {
 515        if (*end == '(') qc++;
 516        else if (qc) qc--;
 517        else if (q >= 254) {
 518          // (( can end with )) or retroactively become two (( if we hit one )
 519          if (strstart(&end, "))")) quote--;
 520          else if (q == 254) return start+1;
 521          else if (q == 255) toybuf[quote-1] = ')';
 522        } else if (*end == ')') quote--;
 523        end++;
 524
 525      // end quote?
 526      } else if (*end == q) quote--, end++;
 527
 528      // single quote claims everything
 529      else if (q == '\'') end++;
 530      else i++;
 531
 532      // loop if we already handled a symbol and aren't stopping early
 533      if (early && !quote) return end;
 534      if (!i) continue;
 535    } else {
 536      // Things that only matter when unquoted
 537
 538      if (isspace(*end)) break;
 539      if (*end == ')') return end+(start==end);
 540
 541      // Flow control characters that end pipeline segments
 542      s = end + anystart(end, (char *[]){";;&", ";;", ";&", ";", "||",
 543        "|&", "|", "&&", "&", "(", ")", 0});
 544      if (s != end) return (end == start) ? s : end;
 545    }
 546
 547    // Things the same unquoted or in most non-single-quote contexts
 548
 549    // start new quote context?
 550    if (strchr("\"'`", *end)) toybuf[quote++] = *end;
 551
 552    // backslash escapes
 553    else if (*end == '\\') {
 554      if (!end[1] || (end[1]=='\n' && !end[2])) return early ? end+1 : 0;
 555      end += 2;
 556    } else if (*end == '$' && -1 != (i = stridx("({[", end[1]))) {
 557      end++;
 558      if (strstart(&end, "((")) toybuf[quote++] = 255;
 559      else {
 560        toybuf[quote++] = ")}]"[i];
 561        end++;
 562      }
 563    } else if (end[1]=='(' && strchr("?*+@!", *end)) {
 564      toybuf[quote++] = ')';
 565      end += 2;
 566    }
 567
 568    if (early && !quote) return end;
 569    end++;
 570  }
 571
 572  return (quote && !early) ? 0 : end;
 573}
 574
 575// Return next available high (>=10) file descriptor
 576static int next_hfd()
 577{
 578  int hfd;
 579
 580  for (; TT.hfd<=99999; TT.hfd++) if (-1 == fcntl(TT.hfd, F_GETFL)) break;
 581  hfd = TT.hfd;
 582  if (TT.hfd>99999) {
 583    hfd = -1;
 584    if (!errno) errno = EMFILE;
 585  }
 586
 587  return hfd;
 588}
 589
 590// Perform a redirect, saving displaced filehandle to a high (>10) fd
 591// rd is an int array: [0] = count, followed by from/to pairs to restore later.
 592// If from >= 0 dup from->to after saving to. If from == -1 just save to.
 593// if from == -2 schedule "to" to be closed by unredirect.
 594static int save_redirect(int **rd, int from, int to)
 595{
 596  int cnt, hfd, *rr;
 597
 598  if (from == to) return 0;
 599  // save displaced to, copying to high (>=10) file descriptor to undo later
 600  // except if we're saving to environment variable instead (don't undo that)
 601  if (from>-2) {
 602    if ((hfd = next_hfd())==-1) return 1;
 603    if (hfd != dup2(to, hfd)) hfd = -1;
 604    else fcntl(hfd, F_SETFD, FD_CLOEXEC);
 605
 606    // dup "to"
 607    if (from >= 0 && to != dup2(from, to)) {
 608      if (hfd >= 0) close(hfd);
 609
 610      return 1;
 611    }
 612  } else {
 613    hfd = to;
 614    to = -1;
 615  }
 616
 617  // Append undo information to redirect list so we can restore saved hfd later.
 618  if (!((cnt = *rd ? **rd : 0)&31)) *rd = xrealloc(*rd, (cnt+33)*2*sizeof(int));
 619  *(rr = *rd) = ++cnt;
 620  rr[2*cnt-1] = hfd;
 621  rr[2*cnt] = to;
 622
 623  return 0;
 624}
 625
 626// TODO: waitpid(WNOHANG) to clean up zombies and catch background& ending
 627static void subshell_callback(char **argv)
 628{
 629  char *s;
 630
 631  xsetenv(s = xmprintf("@%d,%d=", getpid(), getppid()), 0);
 632  s[strlen(s)-1] = 0;
 633  xsetenv(xmprintf("$=%d", TT.pid), 0);
 634// TODO: test $$ in (nommu)
 635}
 636
 637// TODO check every caller of run_subshell for error, or syntax_error() here
 638// from pipe() failure
 639
 640// Pass environment and command string to child shell, return PID of child
 641static int run_subshell(char *str, int len)
 642{
 643  pid_t pid;
 644
 645  // The with-mmu path is significantly faster.
 646  if (CFG_TOYBOX_FORK) {
 647    char *s;
 648
 649    if ((pid = fork())<0) perror_msg("fork");
 650    else if (!pid) {
 651      s = xstrndup(str, len);
 652      sh_run(s);
 653      free(s);
 654      _exit(toys.exitval);
 655    }
 656
 657  // On nommu vfork, exec /proc/self/exe, and pipe state data to ourselves.
 658  } else {
 659    int pipes[2], i, c;
 660
 661    // open pipe to child
 662    if (pipe(pipes) || 254 != dup2(pipes[0], 254)) return 1;
 663    close(pipes[0]);
 664    fcntl(pipes[1], F_SETFD, FD_CLOEXEC);
 665
 666    // vfork child
 667    pid = xpopen_setup(0, 0, subshell_callback);
 668
 669    // free entries added to end of environment by callback (shared heap)
 670    for (i = 0; environ[i]; i++) {
 671      c = environ[i][0];
 672      if (c == '_' || !ispunct(c)) continue;
 673      free(environ[i]);
 674      environ[i] = 0;
 675    }
 676
 677    // marshall data to child
 678    close(254);
 679    for (i = 0; i<TT.varslen; i++) {
 680      char *s;
 681
 682      if (TT.vars[i].flags&VAR_GLOBAL) continue;
 683      dprintf(pipes[1], "%s\n", s = declarep(TT.vars+i));
 684      free(s);
 685    }
 686    dprintf(pipes[1], "%.*s\n", len, str);
 687    close(pipes[1]);
 688  }
 689
 690  return pid;
 691}
 692
 693// restore displaced filehandles, closing high filehandles they were copied to
 694static void unredirect(int *urd)
 695{
 696  int *rr = urd+1, i;
 697
 698  if (!urd) return;
 699
 700  for (i = 0; i<*urd; i++, rr += 2) if (rr[0] != -1) {
 701    // No idea what to do about fd exhaustion here, so Steinbach's Guideline.
 702    dup2(rr[0], rr[1]);
 703    close(rr[0]);
 704  }
 705  free(urd);
 706}
 707
 708// Call subshell with either stdin/stdout redirected, return other end of pipe
 709static int pipe_subshell(char *s, int len, int out)
 710{
 711  int pipes[2], *uu = 0, in = !out;
 712
 713  // Grab subshell data
 714  if (pipe(pipes)) {
 715    perror_msg("%.*s", len, s);
 716
 717    return -1;
 718  }
 719
 720  // Perform input or output redirect and launch process (ignoring errors)
 721  save_redirect(&uu, pipes[in], in);
 722  close(pipes[in]);
 723  run_subshell(s, len);
 724  unredirect(uu);
 725
 726  return pipes[out];
 727}
 728
 729// utf8 strchr: return wide char matched at wc from chrs, or 0 if not matched
 730// if len, save length of next wc (whether or not it's in list)
 731static int utf8chr(char *wc, char *chrs, int *len)
 732{
 733  wchar_t wc1, wc2;
 734  int ll;
 735
 736  if (len) *len = 1;
 737  if (!*wc) return 0;
 738  if (0<(ll = utf8towc(&wc1, wc, 99))) {
 739    if (len) *len = ll;
 740    while (*chrs) {
 741      if(1>(ll = utf8towc(&wc2, chrs, 99))) chrs++;
 742      else {
 743        if (wc1 == wc2) return wc1;
 744        chrs += ll;
 745      }
 746    }
 747  }
 748
 749  return 0;
 750}
 751
 752// grab variable or special param (ala $$) up to len bytes. Return value.
 753// set *used to length consumed. Does not handle $* and $@
 754char *getvar_special(char *str, int len, int *used, struct arg_list **delete)
 755{
 756  char *s = 0, *ss, cc = *str;
 757  unsigned uu;
 758
 759  *used = 1;
 760  if (cc == '-') {
 761    s = ss = xmalloc(8);
 762    if (TT.options&OPT_I) *ss++ = 'i';
 763    if (TT.options&OPT_BRACE) *ss++ = 'B';
 764    if (TT.options&OPT_S) *ss++ = 's';
 765    if (TT.options&OPT_C) *ss++ = 'c';
 766    *ss = 0;
 767  } else if (cc == '?') s = xmprintf("%d", toys.exitval);
 768  else if (cc == '$') s = xmprintf("%d", TT.pid);
 769  else if (cc == '#') s = xmprintf("%d", TT.arg->c?TT.arg->c-1:0);
 770  else if (cc == '!') s = xmprintf("%d"+2*!TT.bangpid, TT.bangpid);
 771  else {
 772    delete = 0;
 773    for (*used = uu = 0; *used<len && isdigit(str[*used]); ++*used)
 774      uu = (10*uu)+str[*used]-'0';
 775    if (*used) {
 776      if (uu) uu += TT.shift;
 777      if (uu<TT.arg->c) s = TT.arg->v[uu];
 778    } else if ((*used = varend(str)-str)) return getvar(str);
 779  }
 780  if (s) push_arg(delete, s);
 781
 782  return s;
 783}
 784
 785// Return length of utf8 char @s fitting in len, writing value into *cc
 786int getutf8(char *s, int len, int *cc)
 787{
 788  wchar_t wc;
 789
 790  if (len<0) wc = len = 0;
 791  else if (1>(len = utf8towc(&wc, s, len))) wc = *s, len = 1;
 792  if (cc) *cc = wc;
 793
 794  return len;
 795}
 796
 797#define WILD_SHORT 1 // else longest match
 798#define WILD_CASE  2 // case insensitive
 799#define WILD_ANY   4 // advance through pattern instead of str
 800// Returns length of str matched by pattern, or -1 if not all pattern consumed
 801static int wildcard_matchlen(char *str, int len, char *pattern, int plen,
 802  struct sh_arg *deck, int flags)
 803{
 804  struct sh_arg ant = {0};    // stack: of str offsets
 805  long ss, pp, dd, best = -1;
 806  int i, j, c, not;
 807
 808  // Loop through wildcards in pattern.
 809  for (ss = pp = dd = 0; ;) {
 810    if ((flags&WILD_ANY) && best!=-1) break;
 811
 812    // did we consume pattern?
 813    if (pp==plen) {
 814      if (ss>best) best = ss;
 815      if (ss==len || (flags&WILD_SHORT)) break;
 816    // attempt literal match?
 817    } else if (dd>=deck->c || pp!=(long)deck->v[dd]) {
 818      if (ss<len) {
 819        if (flags&WILD_CASE) {
 820          c = towupper(getutf8(str+ss, len-ss, &i));
 821          ss += i;
 822          i = towupper(getutf8(pattern+pp, pp-plen, &j));
 823          pp += j;
 824        } else c = str[ss++], i = pattern[pp++];
 825        if (c==i) continue;
 826      }
 827
 828    // Wildcard chars: |+@!*?()[]
 829    } else {
 830      c = pattern[pp++];
 831      dd++;
 832      if (c=='?' || ((flags&WILD_ANY) && c=='*')) {
 833        ss += (i = getutf8(str+ss, len-ss, 0));
 834        if (i) continue;
 835      } else if (c=='*') {
 836
 837        // start with zero length match, don't record consecutive **
 838        if (dd==1 || pp-2!=(long)deck->v[dd-1] || pattern[pp-2]!='*') {
 839          arg_add(&ant, (void *)ss);
 840          arg_add(&ant, 0);
 841        }
 842
 843        continue;
 844      } else if (c == '[') {
 845        pp += (not = !!strchr("!^", pattern[pp]));
 846        ss += getutf8(str+ss, len-ss, &c);
 847        for (i = 0; pp<(long)deck->v[dd]; i = 0) {
 848          pp += getutf8(pattern+pp, plen-pp, &i);
 849          if (pattern[pp]=='-') {
 850            ++pp;
 851            pp += getutf8(pattern+pp, plen-pp, &j);
 852            if (not^(i<=c && j>=c)) break;
 853          } else if (not^(i==c)) break;
 854        }
 855        if (i) {
 856          pp = 1+(long)deck->v[dd++];
 857
 858          continue;
 859        }
 860
 861      // ( preceded by +@!*?
 862
 863      } else { // TODO ( ) |
 864        dd++;
 865        continue;
 866      }
 867    }
 868
 869    // match failure
 870    if (flags&WILD_ANY) {
 871      ss = 0;
 872      if (plen==pp) break;
 873      continue;
 874    }
 875
 876    // pop retry stack or return failure (TODO: seek to next | in paren)
 877    while (ant.c) {
 878      if ((c = pattern[(long)deck->v[--dd]])=='*') {
 879        if (len<(ss = (long)ant.v[ant.c-2]+(long)++ant.v[ant.c-1])) ant.c -= 2;
 880        else {
 881          pp = (long)deck->v[dd++]+1;
 882          break;
 883        }
 884      } else if (c == '(') dprintf(2, "TODO: (");
 885    }
 886
 887    if (!ant.c) break;
 888  }
 889  free (ant.v);
 890
 891  return best;
 892}
 893
 894static int wildcard_match(char *s, char *p, struct sh_arg *deck, int flags)
 895{
 896  return wildcard_matchlen(s, strlen(s), p, strlen(p), deck, flags);
 897}
 898
 899
 900// TODO: test that * matches ""
 901
 902// skip to next slash in wildcard path, passing count active ranges.
 903// start at pattern[off] and deck[*idx], return pattern pos and update *idx
 904char *wildcard_path(char *pattern, int off, struct sh_arg *deck, int *idx,
 905  int count)
 906{
 907  char *p, *old;
 908  int i = 0, j = 0;
 909
 910  // Skip [] and nested () ranges within deck until / or NUL
 911  for (p = old = pattern+off;; p++) {
 912    if (!*p) return p;
 913    while (*p=='/') {
 914      old = p++;
 915      if (j && !count) return old;
 916      j = 0;
 917    }
 918
 919    // Got wildcard? Return if start of name if out of count, else skip [] ()
 920    if (*idx<deck->c && p-pattern == (long)deck->v[*idx]) {
 921      if (!j++ && !count--) return old;
 922      ++*idx;
 923      if (*p=='[') p = pattern+(long)deck->v[(*idx)++];
 924      else if (*p=='(') while (*++p) if (p-pattern == (long)deck->v[*idx]) {
 925        ++*idx;
 926        if (*p == ')') {
 927          if (!i) break;
 928          i--;
 929        } else if (*p == '(') i++;
 930      }
 931    }
 932  }
 933}
 934
 935// TODO ** means this directory as well as ones below it, shopt -s globstar
 936
 937// Filesystem traversal callback
 938// pass on: filename, portion of deck, portion of pattern,
 939// input: pattern+offset, deck+offset. Need to update offsets.
 940int do_wildcard_files(struct dirtree *node)
 941{
 942  struct dirtree *nn;
 943  char *pattern, *patend;
 944  int lvl, ll = 0, ii = 0, rc;
 945  struct sh_arg ant;
 946
 947  // Top level entry has no pattern in it
 948  if (!node->parent) return DIRTREE_RECURSE;
 949
 950  // Find active pattern range
 951  for (nn = node->parent; nn; nn = nn->parent) if (nn->parent) ii++;
 952  pattern = wildcard_path(TT.wcpat, 0, TT.wcdeck, &ll, ii);
 953  while (*pattern=='/') pattern++;
 954  lvl = ll;
 955  patend = wildcard_path(TT.wcpat, pattern-TT.wcpat, TT.wcdeck, &ll, 1);
 956
 957  // Don't include . entries unless explicitly asked for them 
 958  if (*node->name=='.' && *pattern!='.') return 0;
 959
 960  // Don't descend into non-directory (was called with DIRTREE_SYMFOLLOW)
 961  if (*patend && !S_ISDIR(node->st.st_mode) && *node->name) return 0;
 962
 963  // match this filename from pattern to p in deck from lvl to ll
 964  ant.c = ll-lvl;
 965  ant.v = TT.wcdeck->v+lvl;
 966  for (ii = 0; ii<ant.c; ii++) TT.wcdeck->v[lvl+ii] -= pattern-TT.wcpat;
 967  rc = wildcard_matchlen(node->name, strlen(node->name), pattern,
 968    patend-pattern, &ant, 0);
 969  for (ii = 0; ii<ant.c; ii++) TT.wcdeck->v[lvl+ii] += pattern-TT.wcpat;
 970
 971  // Return failure or save exact match.
 972  if (rc<0 || node->name[rc]) return 0;
 973  if (!*patend) return DIRTREE_SAVE;
 974
 975  // Are there more wildcards to test children against?
 976  if (TT.wcdeck->c!=ll) return DIRTREE_RECURSE;
 977
 978  // No more wildcards: check for child and return failure if it isn't there.
 979  pattern = xmprintf("%s%s", node->name, patend);
 980  rc = faccessat(dirtree_parentfd(node), pattern, F_OK, AT_SYMLINK_NOFOLLOW);
 981  free(pattern);
 982  if (rc) return 0;
 983
 984  // Save child and self. (Child could be trailing / but only one saved.)
 985  while (*patend=='/' && patend[1]) patend++;
 986  node->child = xzalloc(sizeof(struct dirtree)+1+strlen(patend));
 987  node->child->parent = node;
 988  strcpy(node->child->name, patend);
 989
 990  return DIRTREE_SAVE;
 991}
 992
 993// Record active wildcard chars in output string
 994// *new start of string, oo offset into string, deck is found wildcards,
 995static void collect_wildcards(char *new, long oo, struct sh_arg *deck)
 996{
 997  long bracket, *vv;
 998  char cc = new[oo];
 999
1000  // Record unescaped/unquoted wildcard metadata for later processing
1001
1002  if (!deck->c) arg_add(deck, 0);
1003  vv = (long *)deck->v;
1004
1005  // vv[0] used for paren level (bottom 16 bits) + bracket start offset<<16
1006
1007  // at end loop backwards through live wildcards to remove pending unmatched (
1008  if (!cc) {
1009    long ii = 0, jj = 65535&*vv, kk;
1010
1011    for (kk = deck->c; jj;) {
1012      if (')' == (cc = new[vv[--kk]])) ii++;
1013      else if ('(' == cc) {
1014        if (ii) ii--;
1015        else {
1016          memmove(vv+kk, vv+kk+1, sizeof(long)*(deck->c-- -kk));
1017          jj--;
1018        }
1019      }
1020    }
1021    if (deck->c) memmove(vv, vv+1, sizeof(long)*deck->c--);
1022
1023    return;
1024  }
1025
1026  // Start +( range, or remove first char that isn't wildcard without (
1027  if (deck->c>1 && vv[deck->c-1] == oo-1 && strchr("+@!*?", new[oo-1])) {
1028    if (cc == '(') {
1029      vv[deck->c-1] = oo;
1030      return;
1031    } else if (!strchr("*?", new[oo-1])) deck->c--;
1032  }
1033
1034  // fall through to add wildcard, popping parentheses stack as necessary
1035  if (strchr("|+@!*?", cc));
1036  else if (cc == ')' && (65535&*vv)) --*vv;
1037
1038  // complete [range], discard wildcards within, add [, fall through to add ]
1039  else if (cc == ']' && (bracket = *vv>>16)) {
1040
1041    // don't end range yet for [] or [^]
1042    if (bracket+1 == oo || (bracket+2 == oo && strchr("!^", new[oo-1]))) return;
1043    while (deck->c>1 && vv[deck->c-1]>=bracket) deck->c--;
1044    *vv &= 65535;
1045    arg_add(deck, (void *)bracket);
1046
1047  // Not a wildcard
1048  } else {
1049    // [ is speculative, don't add to deck yet, just record we saw it
1050    if (cc == '[' && !(*vv>>16)) *vv = (oo<<16)+(65535&*vv);
1051    return;
1052  }
1053
1054  // add active wildcard location
1055  arg_add(deck, (void *)oo);
1056}
1057
1058// wildcard expand data against filesystem, and add results to arg list
1059// Note: this wildcard deck has extra argument at start (leftover from parsing)
1060static void wildcard_add_files(struct sh_arg *arg, char *pattern,
1061  struct sh_arg *deck, struct arg_list **delete)
1062{
1063  struct dirtree *dt;
1064  char *pp;
1065  int ll = 0;
1066
1067  // fast path: when no wildcards, add pattern verbatim
1068  collect_wildcards("", 0, deck);
1069  if (!deck->c) return arg_add(arg, pattern);
1070
1071  // Traverse starting with leading patternless path.
1072  pp = wildcard_path(TT.wcpat = pattern, 0, TT.wcdeck = deck, &ll, 0);
1073  pp = (pp==pattern) ? 0 : xstrndup(pattern, pp-pattern);
1074  dt = dirtree_flagread(pp, DIRTREE_STATLESS|DIRTREE_SYMFOLLOW,
1075    do_wildcard_files);
1076  free(pp);
1077  deck->c = 0;
1078
1079  // If no match save pattern, else free tree saving each path found.
1080  if (!dt) return arg_add(arg, pattern);
1081  while (dt) {
1082    while (dt->child) dt = dt->child;
1083    arg_add(arg, dirtree_path(dt, 0));
1084    do {
1085      pp = (void *)dt;
1086      if ((dt = dt->parent)) dt->child = dt->child->next;
1087      free(pp);
1088    } while (dt && !dt->child);
1089  }
1090// TODO: test .*/../
1091}
1092
1093// Copy string until } including escaped }
1094// if deck collect wildcards, and store terminator at deck->v[deck->c]
1095char *slashcopy(char *s, char *c, struct sh_arg *deck)
1096{
1097  char *ss;
1098  long ii, jj;
1099
1100  for (ii = 0; !strchr(c, s[ii]); ii++) if (s[ii] == '\\') ii++;
1101  ss = xmalloc(ii+1);
1102  for (ii = jj = 0; !strchr(c, s[jj]); ii++)
1103    if ('\\'==(ss[ii] = s[jj++])) ss[ii] = s[jj++];
1104    else if (deck) collect_wildcards(ss, ii, deck);
1105  ss[ii] = 0;
1106  if (deck) {
1107    arg_add(deck, 0);
1108    deck->v[--deck->c] = (void *)jj;
1109    collect_wildcards("", 0, deck);
1110  }
1111
1112  return ss;
1113}
1114
1115#define NO_QUOTE (1<<0)    // quote removal
1116#define NO_PATH  (1<<1)    // path expansion (wildcards)
1117#define NO_SPLIT (1<<2)    // word splitting
1118#define NO_BRACE (1<<3)    // {brace,expansion}
1119#define NO_TILDE (1<<4)    // ~username/path
1120#define NO_NULL  (1<<5)    // Expand to "" instead of NULL
1121#define SEMI_IFS (1<<6)    // Use ' ' instead of IFS to combine $*
1122// expand str appending to arg using above flag defines, add mallocs to delete
1123// if ant not null, save wildcard deck there instead of expanding vs filesystem
1124// returns 0 for success, 1 for error
1125static int expand_arg_nobrace(struct sh_arg *arg, char *str, unsigned flags,
1126  struct arg_list **delete, struct sh_arg *ant)
1127{
1128  char cc, qq = flags&NO_QUOTE, sep[6], *new = str, *s, *ss, *ifs, *slice;
1129  int ii = 0, oo = 0, xx, yy, dd, jj, kk, ll, mm;
1130  struct sh_arg deck = {0};
1131
1132  // Tilde expansion
1133  if (!(flags&NO_TILDE) && *str == '~') {
1134    struct passwd *pw = 0;
1135
1136    ss = 0;
1137    while (str[ii] && str[ii]!=':' && str[ii]!='/') ii++;
1138    if (ii==1) {
1139      if (!(ss = getvar("HOME")) || !*ss) pw = bufgetpwuid(getuid());
1140    } else {
1141      // TODO bufgetpwnam
1142      pw = getpwnam(s = xstrndup(str+1, ii-1));
1143      free(s);
1144    }
1145    if (pw) {
1146      ss = pw->pw_dir;
1147      if (!ss || !*ss) ss = "/";
1148    }
1149    if (ss) {
1150      oo = strlen(ss);
1151      s = xmprintf("%s%s", ss, str+ii);
1152      if (str != new) free(new);
1153      new = s;
1154    }
1155  }
1156
1157  // parameter/variable expansion and dequoting
1158  if (!ant) ant = &deck;
1159  for (; (cc = str[ii++]); str!=new && (new[oo] = 0)) {
1160    struct sh_arg aa = {0};
1161    int nosplit = 0;
1162
1163    // skip literal chars
1164    if (!strchr("'\"\\$`"+2*(flags&NO_QUOTE), cc)) {
1165      if (str != new) new[oo] = cc;
1166      if (!(flags&NO_PATH) && !(qq&1)) collect_wildcards(new, oo, ant);
1167      oo++;
1168      continue;
1169    }
1170
1171    // allocate snapshot if we just started modifying
1172    if (str == new) {
1173      new = xstrdup(new);
1174      new[oo] = 0;
1175    }
1176    ifs = slice = 0;
1177
1178    // handle escapes and quoting
1179    if (cc == '\\') {
1180      if (!(qq&1) || (str[ii] && strchr("\"\\$`", str[ii])))
1181        new[oo++] = str[ii] ? str[ii++] : cc;
1182    } else if (cc == '"') qq++;
1183    else if (cc == '\'') {
1184      if (qq&1) new[oo++] = cc;
1185      else {
1186        qq += 2;
1187        while ((cc = str[ii++]) != '\'') new[oo++] = cc;
1188      }
1189
1190    // both types of subshell work the same, so do $( here not in '$' below
1191// TODO $((echo hello) | cat) ala $(( becomes $( ( retroactively
1192    } else if (cc == '`' || (cc == '$' && strchr("([", str[ii]))) {
1193      off_t pp = 0;
1194
1195      s = str+ii-1;
1196      kk = parse_word(s, 1, 0)-s;
1197      if (str[ii] == '[' || *toybuf == 255) {
1198        s += 2+(str[ii]!='[');
1199        kk -= 3+2*(str[ii]!='[');
1200dprintf(2, "TODO: do math for %.*s\n", kk, s);
1201      } else {
1202        // Run subshell and trim trailing newlines
1203        s += (jj = 1+(cc == '$'));
1204        ii += --kk;
1205        kk -= jj;
1206
1207        // Special case echo $(<input)
1208        for (ss = s; isspace(*ss); ss++);
1209        if (*ss != '<') ss = 0;
1210        else {
1211          while (isspace(*++ss));
1212          if (!(ll = parse_word(ss, 0, 0)-ss)) ss = 0;
1213          else {
1214            jj = ll+(ss-s);
1215            while (isspace(s[jj])) jj++;
1216            if (jj != kk) ss = 0;
1217            else {
1218              jj = xcreate_stdio(ss = xstrndup(ss, ll), O_RDONLY|WARN_ONLY, 0);
1219              free(ss);
1220            }
1221          }
1222        }
1223
1224// TODO what does \ in `` mean? What is echo `printf %s \$x` supposed to do?
1225        if (!ss) jj = pipe_subshell(s, kk, 0);
1226        if ((ifs = readfd(jj, 0, &pp)))
1227          for (kk = strlen(ifs); kk && ifs[kk-1]=='\n'; ifs[--kk] = 0);
1228        close(jj);
1229      }
1230
1231    // $VARIABLE expansions
1232
1233    } else if (cc == '$') {
1234      cc = *(ss = str+ii++);
1235      if (cc=='\'') {
1236        for (s = str+ii; *s != '\''; oo += wcrtomb(new+oo, unescape2(&s, 0),0));
1237        ii = s-str+1;
1238
1239        continue;
1240      } else if (cc=='"' && !(qq&1)) {
1241        qq++;
1242
1243        continue;
1244      } else if (cc == '{') {
1245
1246        // Skip escapes to find }, parse_word() guarantees ${} terminates
1247        for (cc = *++ss; str[ii] != '}'; ii++) if (str[ii]=='\\') ii++;
1248        ii++;
1249
1250        if (cc == '}') ifs = (void *)1;
1251        else if (strchr("#!", cc)) ss++;
1252        jj = varend(ss)-ss;
1253        if (!jj) while (isdigit(ss[jj])) jj++;
1254        if (!jj && strchr("#$!_*", *ss)) jj++;
1255        // parameter or operator? Maybe not a prefix: ${#-} vs ${#-x}
1256        if (!jj && strchr("-?@", *ss)) if (ss[++jj]!='}' && ss[-1]!='{') ss--;
1257        slice = ss+jj;        // start of :operation
1258
1259        if (!jj) {
1260          ifs = (void *)1;
1261          // literal ${#} or ${!} wasn't a prefix
1262          if (strchr("#!", cc)) ifs = getvar_special(--ss, 1, &kk, delete);
1263        } else if (ss[-1]=='{'); // not prefix, fall through
1264        else if (cc == '#') {  // TODO ${#x[@]}
1265          dd = !!strchr("@*", *ss);  // For ${#@} or ${#*} do normal ${#}
1266          ifs = getvar_special(ss-dd, jj, &kk, delete) ? : "";
1267          if (!dd) push_arg(delete, ifs = xmprintf("%zu", strlen(ifs)));
1268        // ${!@} ${!@Q} ${!x} ${!x@} ${!x@Q} ${!x#} ${!x[} ${!x[*]}
1269        } else if (cc == '!') {  // TODO: ${var[@]} array
1270
1271          // special case: normal varname followed by @} or *} = prefix list
1272          if (ss[jj] == '*' || (ss[jj] == '@' && !isalpha(ss[jj+1]))) {
1273            for (slice++, kk = 0; kk<TT.varslen; kk++)
1274              if (!strncmp(s = TT.vars[kk].str, ss, jj))
1275                arg_add(&aa, push_arg(delete, s = xstrndup(s, stridx(s, '='))));
1276            if (aa.c) push_arg(delete, (void *)aa.v);
1277
1278          // else dereference to get new varname, discarding if none, check err
1279          } else {
1280            // First expansion
1281            if (strchr("@*", *ss)) { // special case ${!*}/${!@}
1282              expand_arg_nobrace(&aa, "\"$*\"", NO_PATH|NO_SPLIT, delete, 0);
1283              ifs = *aa.v;
1284              free(aa.v);
1285              memset(&aa, 0, sizeof(aa));
1286              jj = 1;
1287            } else ifs = getvar_special(ss, jj, &jj, delete);
1288            slice = ss+jj;
1289
1290            // Second expansion
1291            if (!jj) ifs = (void *)1;
1292            else if (ifs && *(ss = ifs)) {
1293              if (strchr("@*", cc)) {
1294                aa.c = TT.arg->c-1;
1295                aa.v = TT.arg->v+1;
1296                jj = 1;
1297              } else ifs = getvar_special(ifs, strlen(ifs), &jj, delete);
1298              if (ss && ss[jj]) {
1299                ifs = (void *)1;
1300                slice = ss+strlen(ss);
1301              }
1302            }
1303          }
1304        }
1305
1306        // Substitution error?
1307        if (ifs == (void *)1) {
1308barf:
1309          if (!(((unsigned long)ifs)>>1)) ifs = "bad substitution";
1310          error_msg("%.*s: %s", (int)(slice-ss), ss, ifs);
1311          goto fail;
1312        }
1313      } else jj = 1;
1314
1315      // Resolve unprefixed variables
1316      if (strchr("{$", ss[-1])) {
1317        if (strchr("@*", cc)) {
1318          aa.c = TT.arg->c-1;
1319          aa.v = TT.arg->v+1;
1320        } else {
1321          ifs = getvar_special(ss, jj, &jj, delete);
1322          if (!jj) {
1323            if (ss[-1] == '{') goto barf;
1324            new[oo++] = '$';
1325            ii--;
1326            continue;
1327          } else if (ss[-1] != '{') ii += jj-1;
1328        }
1329      }
1330    }
1331
1332    // combine before/ifs/after sections & split words on $IFS in ifs
1333    // keep oo bytes of str before (already parsed)
1334    // insert ifs (active for wildcards+splitting)
1335    // keep str+ii after (still to parse)
1336
1337    // Fetch separator to glue string back together with
1338    *sep = 0;
1339    if (((qq&1) && cc=='*') || (flags&NO_SPLIT)) {
1340      wchar_t wc;
1341
1342      nosplit++;
1343      if (flags&SEMI_IFS) strcpy(sep, " ");
1344// TODO what if separator is bigger? Need to grab 1 column of combining chars
1345      else if (0<(dd = utf8towc(&wc, TT.ifs, 4)))
1346        sprintf(sep, "%.*s", dd, TT.ifs);
1347    }
1348
1349    // when aa proceed through entries until NULL, else process ifs once
1350    mm = yy = 0;
1351    do {
1352
1353      // get next argument
1354      if (aa.c) ifs = aa.v[mm++] ? : "";
1355
1356      // Are we performing surgery on this argument?
1357      if (slice && *slice != '}') {
1358        dd = slice[xx = (*slice == ':')];
1359        if (!ifs || (xx && !*ifs)) {
1360          if (strchr("-?=", dd)) { // - use default = assign default ? error
1361            push_arg(delete, ifs = slashcopy(slice+xx+1, "}", 0));
1362            if (dd == '?' || (dd == '=' &&
1363              !(setvar(s = xmprintf("%.*s=%s", (int)(slice-ss), ss, ifs)))))
1364                goto barf;
1365          }
1366        } else if (dd == '-'); // NOP when ifs not empty
1367        // use alternate value
1368        else if (dd == '+')
1369          push_arg(delete, ifs = slashcopy(slice+xx+1, "}", 0));
1370        else if (xx) { // ${x::}
1371          long long la, lb, lc;
1372
1373// TODO don't redo math in loop
1374          ss = slice+1;
1375          la = do_math(&s);
1376          if (s && *s == ':') {
1377            s++;
1378            lb = do_math(&s);
1379          } else lb = LLONG_MAX;
1380          if (s && *s != '}') {
1381            error_msg("%.*s: bad '%c'", (int)(slice-ss), ss, *s);
1382            s = 0;
1383          }
1384          if (!s) goto fail;
1385
1386          // This isn't quite what bash does, but close enough.
1387          if (!(lc = aa.c)) lc = strlen(ifs);
1388          else if (!la && !yy && strchr("@*", slice[1])) {
1389            aa.v--; // ${*:0} shows $0 even though default is 1-indexed
1390            aa.c++;
1391            yy++;
1392          }
1393          if (la<0 && (la += lc)<0) continue;
1394          if (lb<0) lb = lc+lb-la;
1395          if (aa.c) {
1396            if (mm<la || mm>=la+lb) continue;
1397          } else if (la>=lc || lb<0) ifs = "";
1398          else if (la+lb>=lc) ifs += la;
1399          else if (!*delete || ifs != (*delete)->arg)
1400            push_arg(delete, ifs = xmprintf("%.*s", (int)lb, ifs+la));
1401          else {
1402            for (dd = 0; dd<lb ; dd++) if (!(ifs[dd] = ifs[dd+la])) break;
1403            ifs[dd] = 0;
1404          }
1405        } else if (strchr("#%^,", *slice)) {
1406          struct sh_arg wild = {0};
1407          char buf[8];
1408
1409          s = slashcopy(slice+(xx = slice[1]==*slice)+1, "}", &wild);
1410
1411          // ${x^pat} ${x^^pat} uppercase ${x,} ${x,,} lowercase (no pat = ?)
1412          if (strchr("^,", *slice)) {
1413            for (ss = ifs; *ss; ss += dd) {
1414              dd = getutf8(ss, 4, &jj);
1415              if (!*s || 0<wildcard_match(ss, s, &wild, WILD_ANY)) {
1416                ll = ((*slice=='^') ? towupper : towlower)(jj);
1417
1418                // Of COURSE unicode case switch can change utf8 encoding length
1419                // Lower case U+0069 becomes u+0130 in turkish.
1420                // Greek U+0390 becomes 3 characters TODO test this
1421                if (ll != jj) {
1422                  yy = ss-ifs;
1423                  if (!*delete || (*delete)->arg!=ifs)
1424                    push_arg(delete, ifs = xstrdup(ifs));
1425                  if (dd != (ll = wctoutf8(buf, ll))) {
1426                    if (dd<ll)
1427                      ifs = (*delete)->arg = xrealloc(ifs, strlen(ifs)+1+dd-ll);
1428                    memmove(ifs+yy+dd-ll, ifs+yy+ll, strlen(ifs+yy+ll)+1);
1429                  }
1430                  memcpy(ss = ifs+yy, buf, dd = ll);
1431                }
1432              }
1433              if (!xx) break;
1434            }
1435          // ${x#y} remove shortest prefix ${x##y} remove longest prefix
1436          } else if (*slice=='#') {
1437            if (0<(dd = wildcard_match(ifs, s, &wild, WILD_SHORT*!xx)))
1438              ifs += dd;
1439          // ${x%y} ${x%%y} suffix
1440          } else if (*slice=='%') {
1441            for (ss = ifs+strlen(ifs), yy = -1; ss>=ifs; ss--) {
1442              if (0<(dd = wildcard_match(ss, s, &wild, WILD_SHORT*xx))&&!ss[dd])
1443              {
1444                yy = ss-ifs;
1445                if (!xx) break;
1446              }
1447            }
1448
1449            if (yy != -1) {
1450              if (*delete && (*delete)->arg==ifs) ifs[yy] = 0;
1451              else push_arg(delete, ifs = xstrndup(ifs, yy));
1452            }
1453          }
1454          free(s);
1455          free(wild.v);
1456
1457        // ${x/pat/sub} substitute ${x//pat/sub} global ${x/#pat/sub} begin
1458        // ${x/%pat/sub} end ${x/pat} delete pat (x can be @ or *)
1459        } else if (*slice=='/') {
1460          struct sh_arg wild = {0};
1461
1462          s = slashcopy(ss = slice+(xx = !!strchr("/#%", slice[1]))+1, "/}",
1463            &wild);
1464          ss += (long)wild.v[wild.c];
1465          ss = (*ss == '/') ? slashcopy(ss+1, "}", 0) : 0;
1466          jj = ss ? strlen(ss) : 0;
1467          ll = 0;
1468          for (ll = 0; ifs[ll];) {
1469            // TODO nocasematch option
1470            if (0<(dd = wildcard_match(ifs+ll, s, &wild, 0))) {
1471              char *bird = 0;
1472
1473              if (slice[1]=='%' && ifs[ll+dd]) {
1474                ll++;
1475                continue;
1476              }
1477              if (*delete && (*delete)->arg==ifs) {
1478                if (jj==dd) memcpy(ifs+ll, ss, jj);
1479                else if (jj<dd) sprintf(ifs+ll, "%s%s", ss, ifs+ll+dd);
1480                else bird = ifs;
1481              } else bird = (void *)1;
1482              if (bird) {
1483                ifs = xmprintf("%.*s%s%s", ll, ifs, ss ? : "", ifs+ll+dd);
1484                if (bird != (void *)1) {
1485                  free(bird);
1486                  (*delete)->arg = ifs;
1487                } else push_arg(delete, ifs);
1488              }
1489              if (slice[1]!='/') break;
1490            } else ll++;
1491            if (slice[1]=='#') break;
1492          }
1493
1494// ${x@QEPAa} Q=$'blah' E=blah without the $'' wrap, P=expand as $PS1
1495//   A=declare that recreates var a=attribute flags
1496//   x can be @*
1497//      } else if (*slice=='@') {
1498
1499// TODO test x can be @ or *
1500        } else {
1501// TODO test ${-abc} as error
1502          ifs = slice;
1503          goto barf;
1504        }
1505
1506// TODO: $((a=42)) can change var, affect lifetime
1507// must replace ifs AND any previous output arg[] within pointer strlen()
1508// also x=;echo $x${x:=4}$x
1509      }
1510
1511      // Nothing left to do?
1512      if (!ifs) break;
1513      if (!*ifs && !qq) continue;
1514
1515      // loop within current ifs checking region to split words
1516      do {
1517
1518        // find end of (split) word
1519        if ((qq&1) || nosplit) ss = ifs+strlen(ifs);
1520        else for (ss = ifs; *ss; ss += kk) if (utf8chr(ss, TT.ifs, &kk)) break;
1521
1522        // when no prefix, not splitting, no suffix: use existing memory
1523        if (!oo && !*ss && !((mm==aa.c) ? str[ii] : nosplit)) {
1524          if (qq || ss!=ifs) {
1525            if (!(flags&NO_PATH))
1526              for (jj = 0; ifs[jj]; jj++) collect_wildcards(ifs, jj, ant);
1527            wildcard_add_files(arg, ifs, &deck, delete);
1528          }
1529          continue;
1530        }
1531
1532        // resize allocation and copy next chunk of IFS-free data
1533        jj = (mm == aa.c) && !*ss;
1534        new = xrealloc(new, oo + (ss-ifs) + ((nosplit&!jj) ? strlen(sep) : 0) +
1535                       (jj ? strlen(str+ii) : 0) + 1);
1536        dd = sprintf(new + oo, "%.*s%s", (int)(ss-ifs), ifs,
1537          (nosplit&!jj) ? sep : "");
1538        if (flags&NO_PATH) oo += dd;
1539        else while (dd--) collect_wildcards(new, oo++, ant);
1540        if (jj) break;
1541
1542        // If splitting, keep quoted, non-blank, or non-whitespace separator
1543        if (!nosplit) {
1544          if (qq || *new || *ss) {
1545            push_arg(delete, new = xrealloc(new, strlen(new)+1));
1546            wildcard_add_files(arg, new, &deck, delete);
1547            new = xstrdup(str+ii);
1548          }
1549          qq &= 1;
1550          oo = 0;
1551        }
1552
1553        // Skip trailing seperator (combining whitespace)
1554        while ((jj = utf8chr(ss, TT.ifs, &ll))) {
1555          ss += ll;
1556          if (!iswspace(jj)) break;
1557        }
1558      } while (*(ifs = ss));
1559    } while (!(mm == aa.c));
1560  }
1561
1562// TODO globbing * ? [] +() happens after variable resolution
1563
1564// TODO test word splitting completely eliminating argument when no non-$IFS data left
1565// wordexp keeps pattern when no matches
1566
1567// TODO test NO_SPLIT cares about IFS, see also trailing \n
1568
1569  // Record result.
1570  if (*new || qq) {
1571    if (str != new) push_arg(delete, new);
1572    wildcard_add_files(arg, new, &deck, delete);
1573    new = 0;
1574  }
1575
1576  // return success after freeing
1577  arg = 0;
1578
1579fail:
1580  if (str != new) free(new);
1581  free(deck.v);
1582  if (ant!=&deck && ant->v) collect_wildcards("", 0, ant);
1583
1584  return !!arg;
1585}
1586
1587struct sh_brace {
1588  struct sh_brace *next, *prev, *stack;
1589  int active, cnt, idx, commas[];
1590};
1591
1592static int brace_end(struct sh_brace *bb)
1593{
1594  return bb->commas[(bb->cnt<0 ? 0 : bb->cnt)+1];
1595}
1596
1597// expand braces (ala {a,b,c}) and call expand_arg_nobrace() each permutation
1598static int expand_arg(struct sh_arg *arg, char *old, unsigned flags,
1599  struct arg_list **delete)
1600{
1601  struct sh_brace *bb = 0, *blist = 0, *bstk, *bnext;
1602  int i, j, k, x;
1603  char *s, *ss;
1604
1605  // collect brace spans
1606  if ((TT.options&OPT_BRACE) && !(flags&NO_BRACE)) for (i = 0; ; i++) {
1607    // skip quoted/escaped text
1608    while ((s = parse_word(old+i, 1, 0)) != old+i) i += s-(old+i);
1609    // stop at end of string if we haven't got any more open braces
1610    if (!bb && !old[i]) break;
1611    // end a brace?
1612    if (bb && (!old[i] || old[i] == '}')) {
1613      bb->active = bb->commas[bb->cnt+1] = i;
1614      // pop brace from bb into bnext
1615      for (bnext = bb; bb && bb->active; bb = (bb==blist) ? 0 : bb->prev);
1616      // Is this a .. span?
1617      j = 1+*bnext->commas;
1618      if (old[i] && !bnext->cnt && i-j>=4) {
1619        // a..z span? Single digit numbers handled here too. TODO: utf8
1620        if (old[j+1]=='.' && old[j+2]=='.') {
1621          bnext->commas[2] = old[j];
1622          bnext->commas[3] = old[j+3];
1623          k = 0;
1624          if (old[j+4]=='}' ||
1625            (sscanf(old+j+4, "..%u}%n", bnext->commas+4, &k) && k))
1626              bnext->cnt = -1;
1627        }
1628        // 3..11 numeric span?
1629        if (!bnext->cnt) {
1630          for (k=0, j = 1+*bnext->commas; k<3; k++, j += x)
1631            if (!sscanf(old+j, "..%u%n"+2*!k, bnext->commas+2+k, &x)) break;
1632          if (old[j] == '}') bnext->cnt = -2;
1633        }
1634        // Increment goes in the right direction by at least 1
1635        if (bnext->cnt) {
1636          if (!bnext->commas[4]) bnext->commas[4] = 1;
1637          if ((bnext->commas[3]-bnext->commas[2]>0) != (bnext->commas[4]>0))
1638            bnext->commas[4] *= -1;
1639        }
1640      }
1641      // discard unterminated span, or commaless span that wasn't x..y
1642      if (!old[i] || !bnext->cnt)
1643        free(dlist_pop((blist == bnext) ? &blist : &bnext));
1644    // starting brace
1645    } else if (old[i] == '{') {
1646      dlist_add_nomalloc((void *)&blist,
1647        (void *)(bb = xzalloc(sizeof(struct sh_brace)+34*4)));
1648      bb->commas[0] = i;
1649    // no active span?
1650    } else if (!bb) continue;
1651    // add a comma to current span
1652    else if (bb && old[i] == ',') {
1653      if (bb->cnt && !(bb->cnt&31)) {
1654        dlist_lpop(&blist);
1655        dlist_add_nomalloc((void *)&blist,
1656          (void *)(bb = xrealloc(bb, sizeof(struct sh_brace)+(bb->cnt+34)*4)));
1657      }
1658      bb->commas[++bb->cnt] = i;
1659    }
1660  }
1661
1662// TODO NOSPLIT with braces? (Collate with spaces?)
1663  // If none, pass on verbatim
1664  if (!blist) return expand_arg_nobrace(arg, old, flags, delete, 0);
1665
1666  // enclose entire range in top level brace.
1667  (bstk = xzalloc(sizeof(struct sh_brace)+8))->commas[1] = strlen(old)+1;
1668  bstk->commas[0] = -1;
1669
1670  // loop through each combination
1671  for (;;) {
1672
1673    // Brace expansion can't be longer than original string. Keep start to {
1674    s = ss = xmalloc(bstk->commas[1]);
1675
1676    // Append output from active braces to string
1677    for (bb = blist; bb; bb = (bnext == blist) ? 0 : bnext) {
1678
1679      // If this brace already tip of stack, pop it. (We'll re-add in a moment.)
1680      if (bstk == bb) bstk = bstk->stack;
1681      // if bb is within bstk, save prefix text from bstk's "," to bb's "{"
1682      if (brace_end(bstk)>bb->commas[0]) {
1683        i = bstk->commas[bstk->idx]+1;
1684        s = stpncpy(s, old+i, bb->commas[0]-i);
1685      }
1686      else bstk = bstk->stack; // bb past bstk so done with old bstk, pop it
1687      // push self onto stack as active
1688      bb->stack = bstk;
1689      bb->active = 1;
1690      bstk = bnext = bb;
1691
1692      // Find next active range: skip inactive spans from earlier/later commas
1693      while ((bnext = (bnext->next==blist) ? 0 : bnext->next)) {
1694
1695        // past end of this brace (always true for a..b ranges)
1696        if ((i = bnext->commas[0])>brace_end(bb)) break;
1697
1698        // in this brace but not this section
1699        if (i<bb->commas[bb->idx] || i>bb->commas[bb->idx+1]) {
1700          bnext->active = 0;
1701          bnext->stack = 0;
1702
1703        // in this section
1704        } else break;
1705      }
1706
1707      // is next span past this range?
1708      if (!bnext || bb->cnt<0 || bnext->commas[0]>bb->commas[bb->idx+1]) {
1709
1710        // output uninterrupted span
1711        if (bb->cnt<0) {
1712          k = bb->commas[2]+bb->commas[4]*bb->idx;
1713          s += sprintf(s, (bb->cnt==-1) ? "\\%c"+!ispunct(k) : "%d", k);
1714        } else {
1715          i = bb->commas[bstk->idx]+1;
1716          s = stpncpy(s, old+i, bb->commas[bb->idx+1]-i);
1717        }
1718
1719        // While not sibling, output tail and pop
1720        while (!bnext || bnext->commas[0]>brace_end(bstk)) {
1721          if (!(bb = bstk->stack)) break;
1722          i = brace_end(bstk)+1; // start of span
1723          j = bb->commas[bb->idx+1]; // enclosing comma span (can't be a..b)
1724
1725          while (bnext) {
1726            if (bnext->commas[0]<j) {
1727              j = bnext->commas[0];// sibling
1728              break;
1729            } else if (brace_end(bb)>bnext->commas[0])
1730              bnext = (bnext->next == blist) ? 0 : bnext->next;
1731            else break;
1732          }
1733          s = stpncpy(s, old+i, j-i);
1734
1735          // if next is sibling but parent _not_ a sibling, don't pop
1736          if (bnext && bnext->commas[0]<brace_end(bb)) break;
1737          bstk = bb;
1738        }
1739      }
1740    }
1741
1742    // Save result, aborting on expand error
1743    if (expand_arg_nobrace(arg, push_arg(delete, ss), flags, delete, 0)) {
1744      llist_traverse(blist, free);
1745
1746      return 1;
1747    }
1748
1749    // increment
1750    for (bb = blist->prev; bb; bb = (bb == blist) ? 0 : bb->prev) {
1751      if (!bb->stack) continue;
1752      else if (bb->cnt<0) {
1753        if (abs(bb->commas[2]-bb->commas[3]) < abs(++bb->idx*bb->commas[4]))
1754          bb->idx = 0;
1755        else break;
1756      } else if (++bb->idx > bb->cnt) bb->idx = 0;
1757      else break;
1758    }
1759
1760    // if increment went off left edge, done expanding
1761    if (!bb) break;
1762  }
1763  llist_traverse(blist, free);
1764
1765  return 0;
1766}
1767
1768// Expand exactly one arg, returning NULL on error.
1769static char *expand_one_arg(char *new, unsigned flags, struct arg_list **del)
1770{
1771  struct sh_arg arg = {0};
1772  char *s = 0;
1773
1774  if (!expand_arg(&arg, new, flags|NO_PATH|NO_SPLIT, del))
1775    if (!(s = *arg.v) && (flags&(SEMI_IFS|NO_NULL))) s = "";
1776  free(arg.v);
1777
1778  return s;
1779}
1780
1781// TODO |&
1782
1783// turn a parsed pipeline back into a string.
1784static char *pl2str(struct sh_pipeline *pl)
1785{
1786  struct sh_pipeline *end = 0;
1787  int level = 0, len = 0, i, j;
1788  char *s, *ss, *sss;
1789
1790  // measure, then allocate
1791  for (j = 0; ; j++) for (end = pl; end; end = end->next) {
1792    if (end->type == 1) level++;
1793    else if (end->type == 3 && --level<0) break;
1794
1795    for (i = 0; i<pl->arg->c; i++)
1796      if (j) ss += sprintf(ss, "%s ", pl->arg->v[i]);
1797      else len += strlen(pl->arg->v[i])+1;
1798
1799    sss = pl->arg->v[pl->arg->c];
1800    if (!sss) sss = ";";
1801    if (j) ss = stpcpy(ss, sss);
1802    else len += strlen(sss);
1803
1804// TODO test output with case and function
1805// TODO add HERE documents back in
1806    if (j) return s;
1807    s = ss = xmalloc(len+1);
1808  }
1809}
1810
1811// Expand arguments and perform redirections. Return new process object with
1812// expanded args. This can be called from command or block context.
1813static struct sh_process *expand_redir(struct sh_arg *arg, int skip, int *urd)
1814{
1815  struct sh_process *pp;
1816  char *s = s, *ss, *sss, *cv = 0;
1817  int j, to, from, here = 0;
1818
1819  TT.hfd = 10;
1820
1821  pp = xzalloc(sizeof(struct sh_process));
1822  pp->urd = urd;
1823  pp->raw = arg;
1824
1825  // When we redirect, we copy each displaced filehandle to restore it later.
1826
1827  // Expand arguments and perform redirections
1828  for (j = skip; j<arg->c; j++) {
1829    int saveclose = 0, bad = 0;
1830
1831    s = arg->v[j];
1832
1833    if (!strcmp(s, "!")) {
1834      pp->not ^= 1;
1835
1836      continue;
1837    }
1838
1839    // Handle <() >() redirectionss
1840    if ((*s == '<' || *s == '>') && s[1] == '(') {
1841      int new = pipe_subshell(s+2, strlen(s+2)-1, *s == '>');
1842
1843      // Grab subshell data
1844      if (new == -1) {
1845        pp->exit = 1;
1846
1847        return pp;
1848      }
1849      save_redirect(&pp->urd, -2, new);
1850
1851      // bash uses /dev/fd/%d which requires /dev/fd to be a symlink to
1852      // /proc/self/fd so we just produce that directly.
1853      arg_add_del(&pp->arg, ss = xmprintf("/proc/self/fd/%d", new),&pp->delete);
1854
1855      continue;
1856    }
1857
1858    // Is this a redirect? s = prefix, ss = operator
1859    ss = s + redir_prefix(arg->v[j]);
1860    sss = ss + anystart(ss, (void *)redirectors);
1861    if (ss == sss) {
1862      // Nope: save/expand argument and loop
1863      if (expand_arg(&pp->arg, s, 0, &pp->delete)) {
1864        pp->exit = 1;
1865
1866        return pp;
1867      }
1868      continue;
1869    } else if (j+1 >= arg->c) {
1870      // redirect needs one argument
1871      s = "\\n";
1872      break;
1873    }
1874    sss = arg->v[++j];
1875
1876    // It's a redirect: for [to]<from s = start of [to], ss = <, sss = from
1877    if (isdigit(*s) && ss-s>5) break;
1878
1879    // expand arguments for everything but << and <<-
1880    if (strncmp(ss, "<<", 2) && ss[2] != '<') {
1881      struct sh_arg tmp = {0};
1882
1883      if (!expand_arg(&tmp, sss, 0, &pp->delete) && tmp.c == 1) sss = *tmp.v;
1884      else {
1885        if (tmp.c > 1) error_msg("%s: ambiguous redirect", sss);
1886        s = 0;
1887      }
1888      free(tmp.v);
1889      if (!s) break;
1890    }
1891
1892    // Parse the [fd] part of [fd]<name
1893    to = *ss != '<';
1894    if (isdigit(*s)) to = atoi(s);
1895    else if (*s == '{') {
1896      if (*varend(s+1) != '}') break;
1897      // when we close a filehandle, we _read_ from {var}, not write to it
1898      if ((!strcmp(ss, "<&") || !strcmp(ss, ">&")) && !strcmp(sss, "-")) {
1899        if (!(ss = getvar(s+1))) break;
1900        to = atoi(ss); // TODO trailing garbage?
1901        if (save_redirect(&pp->urd, -1, to)) break;
1902        close(to);
1903
1904        continue;
1905      // record high file descriptor in {to}<from environment variable
1906      } else {
1907        // we don't save this, it goes in the env var and user can close it.
1908        if (-1 == (to = next_hfd())) break;
1909        cv = xmprintf("%.*s=%d", (int)(ss-s-2), s+1, to);
1910      }
1911    }
1912
1913    // HERE documents?
1914    if (!strcmp(ss, "<<<") || !strcmp(ss, "<<-") || !strcmp(ss, "<<")) {
1915      char *tmp = getvar("TMPDIR");
1916      int i, len, zap = (ss[2] == '-'), x = !ss[strcspn(ss, "\"'")];
1917
1918      // store contents in open-but-deleted /tmp file.
1919      tmp = xmprintf("%s/sh-XXXXXX", tmp ? tmp : "/tmp");
1920      if ((from = mkstemp(tmp))>=0) {
1921        if (unlink(tmp)) bad++;
1922
1923        // write contents to file (if <<< else <<) then lseek back to start
1924        else if (ss[2] == '<') {
1925          if (!(ss = expand_one_arg(sss, 0, 0))) {
1926            s = 0;
1927            break;
1928          }
1929          len = strlen(ss);
1930          if (len != writeall(from, ss, len)) bad++;
1931          if (ss != sss) free(ss);
1932        } else {
1933          struct sh_arg *hh = arg+here++;
1934
1935          for (i = 0; i<hh->c; i++) {
1936            ss = hh->v[i];
1937            sss = 0;
1938// TODO audit this ala man page
1939            // expand_parameter, commands, and arithmetic
1940            if (x && !(ss = sss = expand_one_arg(ss, ~SEMI_IFS, 0))) {
1941              s = 0;
1942              break;
1943            }
1944
1945            while (zap && *ss == '\t') ss++;
1946            x = writeall(from, ss, len = strlen(ss));
1947            free(sss);
1948            if (len != x) break;
1949          }
1950          if (i != hh->c) bad++;
1951        }
1952        if (!bad && lseek(from, 0, SEEK_SET)) bad++;
1953        if (bad) close(from);
1954      } else bad++;
1955      free(tmp);
1956      if (bad) break;
1957
1958    // from is fd<<2 (new fd to dup2() after vfork()) plus
1959    // 2 if we should close(from>>2) after dup2(from>>2, to),
1960    // 1 if we should close but dup for nofork recovery (ala <&2-)
1961
1962    // Handle file descriptor duplication/close (&> &>> <& >& with number or -)
1963    // These redirect existing fd so nothing to open()
1964    } else if (*ss == '&' || ss[1] == '&') {
1965
1966      // is there an explicit fd?
1967      for (ss = sss; isdigit(*ss); ss++);
1968      if (ss-sss>5 || (*ss && (*ss != '-' || ss[1]))) {
1969        if (*ss=='&') ss++;
1970        saveclose = 4;
1971        goto notfd;
1972      }
1973
1974      from = (ss==sss) ? to : atoi(sss);
1975      saveclose = 2-(*ss == '-');
1976    } else {
1977notfd:
1978      // Permissions to open external file with: < > >> <& >& <> >| &>> &>
1979      if (!strcmp(ss, "<>")) from = O_CREAT|O_RDWR;
1980      else if (strstr(ss, ">>")) from = O_CREAT|O_APPEND|O_WRONLY;
1981      else {
1982        from = (*ss == '<') ? O_RDONLY : O_CREAT|O_WRONLY|O_TRUNC;
1983        if (!strcmp(ss, ">") && (TT.options&OPT_NOCLOBBER)) {
1984          struct stat st;
1985
1986          // Not _just_ O_EXCL: > /dev/null allowed
1987          if (stat(sss, &st) || !S_ISREG(st.st_mode)) from |= O_EXCL;
1988        }
1989      }
1990
1991      // we expect /dev/fd/# and /dev/{stdin,stdout,stderr} to be in /dev
1992
1993// TODO: /dev/{tcp,udp}/host/port
1994
1995      // Open the file
1996      if (-1 == (from = xcreate_stdio(sss, from|WARN_ONLY, 0666))) {
1997        s = 0;
1998
1999        break;
2000      }
2001    }
2002
2003    // perform redirect, saving displaced "to".
2004    if (save_redirect(&pp->urd, from, to)) bad++;
2005    // Do we save displaced "to" in env variable instead of undo list?
2006    if (cv) {
2007      --*pp->urd;
2008      if (!setvar(cv)) bad++;
2009      cv = 0;
2010    }
2011    if ((saveclose&1) && save_redirect(&pp->urd, -1, from)) bad++;
2012    if ((saveclose&4) && save_redirect(&pp->urd, from, 2)) bad++;
2013    if (!(saveclose&2)) close(from);
2014    if (bad) break;
2015  }
2016
2017  // didn't parse everything?
2018  if (j != arg->c) {
2019    if (s) syntax_err(s);
2020    if (!pp->exit) pp->exit = 1;
2021    free(cv);
2022  }
2023
2024  return pp;
2025}
2026
2027static void shexec(char *cmd, char **argv)
2028{
2029  xsetenv(xmprintf("_=%s", cmd), 0);
2030  execve(cmd, argv, environ);
2031// TODO: why?
2032  if (errno == ENOEXEC) run_subshell("source \"$_\"", 11);
2033}
2034
2035// Call binary, or run via child shell
2036static void sh_exec(char **argv)
2037{
2038  char *pp = getvar("PATH" ? : _PATH_DEFPATH), *cc = TT.isexec ? : *argv;
2039  struct string_list *sl;
2040
2041  if (getpid() != TT.pid) signal(SIGINT, SIG_DFL);
2042  if (strchr(cc, '/')) shexec(cc, argv);
2043  else for (sl = find_in_path(pp, cc); sl; free(llist_pop(&sl)))
2044    shexec(sl->str, argv);
2045
2046  perror_msg("%s", *argv);
2047  if (!TT.isexec) _exit(127);
2048}
2049
2050// Execute a single command
2051static struct sh_process *run_command(struct sh_arg *arg)
2052{
2053  char *s, *ss = 0, *sss, **old = environ;
2054  struct sh_arg env = {0};
2055  int envlen, jj = 0, ll;
2056  struct sh_process *pp;
2057  struct arg_list *delete = 0;
2058  struct toy_list *tl;
2059
2060  // Count leading variable assignments
2061  for (envlen = 0; envlen<arg->c; envlen++) {
2062    s = varend(arg->v[envlen]);
2063    if (s == arg->v[envlen] || *s != '=') break;
2064  }
2065
2066  // perform assignments locally if there's no command
2067  if (envlen == arg->c) {
2068    while (jj<envlen) {
2069      if (!(s = expand_one_arg(arg->v[jj], SEMI_IFS, 0))) break;
2070      setvar((s == arg->v[jj++]) ? xstrdup(s) : s);
2071    }
2072    if (jj == envlen) setvarval("_", "");
2073
2074  // assign leading environment variables (if any) in temp environ copy
2075  } else if (envlen) {
2076    while (environ[env.c]) env.c++;
2077    memcpy(env.v = xmalloc(sizeof(char *)*(env.c+33)), environ,
2078      sizeof(char *)*(env.c+1));
2079    for (; jj<envlen; jj++) {
2080      if (!(sss = expand_one_arg(arg->v[jj], SEMI_IFS, &delete))) break;
2081      for (ll = 0; ll<env.c; ll++) {
2082        for (s = sss, ss = env.v[ll]; *s == *ss && *s != '='; s++, ss++);
2083        if (*s != '=') continue;
2084        env.v[ll] = sss;
2085        break;
2086      }
2087      if (ll == env.c) arg_add(&env, sss);
2088    }
2089    environ = env.v;
2090  }
2091
2092  // return early if error or assignment only
2093  if (envlen == arg->c || jj != envlen) {
2094    pp = xzalloc(sizeof(struct sh_process));
2095    pp->exit = jj != envlen;
2096
2097    goto out;
2098  }
2099
2100  // expand arguments and perform redirects
2101  pp = expand_redir(arg, envlen, 0);
2102
2103  // Do nothing if nothing to do
2104  if (pp->exit || !pp->arg.v);
2105//  else if (!strcmp(*pp->arg.v, "(("))
2106// TODO: handle ((math)) currently totally broken
2107// TODO: call functions()
2108  // Is this command a builtin that should run in this process?
2109  else if ((tl = toy_find(*pp->arg.v))
2110    && (tl->flags & (TOYFLAG_NOFORK|TOYFLAG_MAYFORK)))
2111  {
2112    sigjmp_buf rebound;
2113    char temp[jj = offsetof(struct toy_context, rebound)];
2114
2115    // This fakes lots of what toybox_main() does.
2116    memcpy(&temp, &toys, jj);
2117    memset(&toys, 0, jj);
2118
2119    // If we give the union in TT a name, the compiler complains
2120    // "declaration does not declare anything", but if we DON'T give it a name
2121    // it accepts it. So we can't use the union's type name here, and have
2122    // to offsetof() the first thing _after_ the union to get the size.
2123    memset(&TT, 0, offsetof(struct sh_data, lineno));
2124
2125    TT.pp = pp;
2126    if (!sigsetjmp(rebound, 1)) {
2127      toys.rebound = &rebound;
2128      toy_singleinit(tl, pp->arg.v);  // arg.v must be null terminated
2129      tl->toy_main();
2130      xflush(0);
2131    }
2132    TT.pp = 0;
2133    toys.rebound = 0;
2134    pp->exit = toys.exitval;
2135    if (toys.optargs != toys.argv+1) free(toys.optargs);
2136    if (toys.old_umask) umask(toys.old_umask);
2137    memcpy(&toys, &temp, jj);
2138  } else if (-1==(pp->pid = xpopen_setup(pp->arg.v, 0, sh_exec)))
2139    perror_msg("%s: vfork", *pp->arg.v);
2140
2141  // Restore environment variables
2142  environ = old;
2143  free(env.v);
2144
2145  if (pp->arg.c) setvarval("_", pp->arg.v[pp->arg.c-1]);
2146  // cleanup process
2147  unredirect(pp->urd);
2148out:
2149  llist_traverse(delete, llist_free_arg);
2150
2151  return pp;
2152}
2153
2154static void free_process(void *ppp)
2155{
2156  struct sh_process *pp = ppp;
2157  llist_traverse(pp->delete, llist_free_arg);
2158  free(pp);
2159}
2160
2161// if then fi for while until select done done case esac break continue return
2162
2163// Free one pipeline segment.
2164static void free_pipeline(void *pipeline)
2165{
2166  struct sh_pipeline *pl = pipeline;
2167  int i, j;
2168
2169  // free arguments and HERE doc contents
2170  if (pl) for (j=0; j<=pl->count; j++) {
2171    if (!pl->arg[j].v) continue;
2172    for (i = 0; i<=pl->arg[j].c; i++) free(pl->arg[j].v[i]);
2173    free(pl->arg[j].v);
2174  }
2175  free(pl);
2176}
2177
2178static void free_function(struct sh_function *sp)
2179{
2180  llist_traverse(sp->pipeline, free_pipeline);
2181  llist_traverse(sp->expect, free);
2182  memset(sp, 0, sizeof(struct sh_function));
2183}
2184
2185// TODO this has to add to a namespace context. Functions within functions...
2186static struct sh_pipeline *add_function(char *name, struct sh_pipeline *pl)
2187{
2188dprintf(2, "stub add_function");
2189
2190  return pl->end;
2191}
2192
2193static struct sh_pipeline *add_pl(struct sh_function *sp, struct sh_arg **arg)
2194{
2195  struct sh_pipeline *pl = xzalloc(sizeof(struct sh_pipeline));
2196
2197  *arg = pl->arg;
2198  dlist_add_nomalloc((void *)&sp->pipeline, (void *)pl);
2199
2200  return pl->end = pl;
2201}
2202
2203// Add a line of shell script to a shell function. Returns 0 if finished,
2204// 1 to request another line of input (> prompt), -1 for syntax err
2205static int parse_line(char *line, struct sh_function *sp)
2206{
2207  char *start = line, *delete = 0, *end, *s, *ex, done = 0,
2208    *tails[] = {"fi", "done", "esac", "}", "]]", ")", 0};
2209  struct sh_pipeline *pl = sp->pipeline ? sp->pipeline->prev : 0, *pl2, *pl3;
2210  struct sh_arg *arg = 0;
2211  long i;
2212
2213  // Resume appending to last statement?
2214  if (pl) {
2215    arg = pl->arg;
2216
2217    // Extend/resume quoted block
2218    if (arg->c<0) {
2219      delete = start = xmprintf("%s%s", arg->v[arg->c = (-arg->c)-1], start);
2220      free(arg->v[arg->c]);
2221      arg->v[arg->c] = 0;
2222
2223    // is a HERE document in progress?
2224    } else if (pl->count != pl->here) {
2225      arg += 1+pl->here;
2226
2227      // Match unquoted EOF.
2228      for (s = line, end = arg->v[arg->c]; *s && *end; s++) {
2229        s += strspn(s, "\\\"'");
2230        if (*s != *end) break;
2231      }
2232      // Add this line, else EOF hit so end HERE document
2233      if (!*s && !*end) {
2234        end = arg->v[arg->c];
2235        arg_add(arg, xstrdup(line));
2236        arg->v[arg->c] = end;
2237      } else {
2238        arg->v[arg->c] = 0;
2239        pl->here++;
2240      }
2241      start = 0;
2242
2243    // Nope, new segment if not self-managing type
2244    } else if (pl->type < 128) pl = 0;
2245  }
2246
2247  // Parse words, assemble argv[] pipelines, check flow control and HERE docs
2248  if (start) for (;;) {
2249    ex = sp->expect ? sp->expect->prev->data : 0;
2250
2251    // Look for << HERE redirections in completed pipeline segment
2252    if (pl && pl->count == -1) {
2253      pl->count = 0;
2254      arg = pl->arg;
2255
2256      // find arguments of the form [{n}]<<[-] with another one after it
2257      for (i = 0; i<arg->c; i++) {
2258        s = arg->v[i] + redir_prefix(arg->v[i]);
2259// TODO <<< is funky
2260// argc[] entries removed from main list? Can have more than one?
2261        if (strcmp(s, "<<") && strcmp(s, "<<-") && strcmp(s, "<<<")) continue;
2262        if (i+1 == arg->c) goto flush;
2263
2264        // Add another arg[] to the pipeline segment (removing/readding to list
2265        // because realloc can move pointer)
2266        dlist_lpop(&sp->pipeline);
2267        pl = xrealloc(pl, sizeof(*pl) + ++pl->count*sizeof(struct sh_arg));
2268        dlist_add_nomalloc((void *)&sp->pipeline, (void *)pl);
2269
2270        // queue up HERE EOF so input loop asks for more lines.
2271        arg[pl->count].v = xzalloc(2*sizeof(void *));
2272        arg[pl->count].v[0] = arg->v[++i];
2273        arg[pl->count].v[1] = 0;
2274        arg[pl->count].c = 0;
2275        if (s[2] == '<') pl->here++; // <<< doesn't load more data
2276      }
2277      pl = 0;
2278    }
2279    if (done) break;
2280    s = 0;
2281
2282    // skip leading whitespace/comment here to know where next word starts
2283    while (isspace(*start)) ++start;
2284    if (*start=='#') while (*start && *start != '\n') ++start;
2285
2286    // Parse next word and detect overflow (too many nested quotes).
2287    if ((end = parse_word(start, 0, 0)) == (void *)1) goto flush;
2288
2289    // Is this a new pipeline segment?
2290    if (!pl) pl = add_pl(sp, &arg);
2291
2292    // Do we need to request another line to finish word (find ending quote)?
2293    if (!end) {
2294      // Save unparsed bit of this line, we'll need to re-parse it.
2295      arg_add(arg, xstrndup(start, strlen(start)));
2296      arg->c = -arg->c;
2297      free(delete);
2298
2299      return 1;
2300    }
2301
2302    // Ok, we have a word. What does it _mean_?
2303
2304    // case/esac parsing is weird (unbalanced parentheses!), handle first
2305    i = ex && !strcmp(ex, "esac") && (pl->type || (*start==';' && end-start>1));
2306    if (i) {
2307      // Premature EOL in type 1 (case x\nin) or 2 (at start or after ;;) is ok
2308      if (end == start) {
2309        if (pl->type==128 && arg->c==2) break;  // case x\nin
2310        if (pl->type==129 && (!arg->c || (arg->c==1 && **arg->v==';'))) break;
2311        s = "newline";
2312        goto flush;
2313      }
2314
2315      // type 0 means just got ;; so start new type 2
2316      if (!pl->type) {
2317        // catch "echo | ;;" errors
2318        if (arg->v && arg->v[arg->c] && strcmp(arg->v[arg->c], "&")) goto flush;
2319        if (!arg->c) {
2320          if (pl->prev->type == 2) {
2321            // Add a call to "true" between empty ) ;;
2322            arg_add(arg, xstrdup(":"));
2323            pl = add_pl(sp, &arg);
2324          }
2325          pl->type = 129;
2326        } else {
2327          // check for here documents
2328          pl->count = -1;
2329          continue;
2330        }
2331      }
2332
2333    // Did we hit end of line or ) outside a function declaration?
2334    // ) is only saved at start of a statement, ends current statement
2335    } else if (end == start || (arg->c && *start == ')' && pl->type!='f')) {
2336      if (pl->type == 'f' && arg->c<3) {
2337        s = "function()";
2338        goto flush;
2339      }
2340
2341      // "for" on its own line is an error.
2342      if (arg->c == 1 && ex && !memcmp(ex, "do\0A", 4)) {
2343        s = "newline";
2344        goto flush;
2345      }
2346
2347      // don't save blank pipeline segments
2348      if (!arg->c) free_pipeline(dlist_lpop(&sp->pipeline));
2349
2350      // stop at EOL, else continue with new pipeline segment for )
2351      if (end == start) done++;
2352      pl->count = -1;
2353
2354      continue;
2355    }
2356
2357    // Save word and check for flow control
2358    arg_add(arg, s = xstrndup(start, end-start));
2359    start = end;
2360
2361    // Second half of case/esac parsing
2362    if (i) {
2363      // type 1 (128): case x [\n] in
2364      if (pl->type==128) {
2365        if (arg->c==2 && strchr("()|;&", *s)) goto flush;
2366        if (arg->c==3) {
2367          if (strcmp(s, "in")) goto flush;
2368          pl->type = 1;
2369          (pl = add_pl(sp, &arg))->type = 129;
2370        }
2371
2372        continue;
2373
2374      // type 2 (129): [;;] [(] pattern [|pattern...] )
2375      } else {
2376
2377        // can't start with line break or ";;" or "case ? in ;;" without ")"
2378        if (*s==';') {
2379          if (arg->c>1 || (arg->c==1 && pl->prev->type==1)) goto flush;
2380        } else pl->type = 2;
2381        i = arg->c - (**arg->v==';' && arg->v[0][1]);
2382        if (i==1 && !strcmp(s, "esac")) {
2383          // esac right after "in" or ";;" ends block, fall through
2384          if (arg->c>1) {
2385            arg->v[1] = 0;
2386            pl = add_pl(sp, &arg);
2387            arg_add(arg, s);
2388          } else pl->type = 0;
2389        } else {
2390          if (arg->c>1) i -= *arg->v[1]=='(';
2391          if (i>0 && ((i&1)==!!strchr("|)", *s) || strchr(";(", *s)))
2392            goto flush;
2393          if (*s=='&' || !strcmp(s, "||")) goto flush;
2394          if (*s==')') pl = add_pl(sp, &arg);
2395
2396          continue;
2397        }
2398      }
2399    }
2400
2401    // is it a line break token?
2402    if (strchr(";|&", *s) && strncmp(s, "&>", 2)) {
2403      arg->c--;
2404
2405      // treat ; as newline so we don't have to check both elsewhere.
2406      if (!strcmp(s, ";")) {
2407        arg->v[arg->c] = 0;
2408        free(s);
2409        s = 0;
2410// TODO enforce only one ; allowed between "for i" and in or do.
2411        if (!arg->c && ex && !memcmp(ex, "do\0C", 4)) continue;
2412
2413      // ;; and friends only allowed in case statements
2414      } else if (*s == ';') goto flush;
2415
2416      // flow control without a statement is an error
2417      if (!arg->c) goto flush;
2418      pl->count = -1;
2419
2420      continue;
2421    }
2422
2423    // is a function() in progress?
2424    if (arg->c>1 && !strcmp(s, "(")) pl->type = 'f';
2425    if (pl->type=='f') {
2426      if (arg->c == 2 && strcmp(s, "(")) goto flush;
2427      if (arg->c == 3) {
2428        if (strcmp(s, ")")) goto flush;
2429
2430        // end function segment, expect function body
2431        pl->count = -1;
2432        dlist_add(&sp->expect, "}");
2433        dlist_add(&sp->expect, 0);
2434        dlist_add(&sp->expect, "{");
2435
2436        continue;
2437      }
2438
2439    // a for/select must have at least one additional argument on same line
2440    } else if (ex && !memcmp(ex, "do\0A", 4)) {
2441
2442      // Sanity check and break the segment
2443      if (strncmp(s, "((", 2) && *varend(s)) goto flush;
2444      pl->count = -1;
2445      sp->expect->prev->data = "do\0C";
2446
2447      continue;
2448
2449    // flow control is the first word of a pipeline segment
2450    } else if (arg->c>1) continue;
2451
2452    // Do we expect something that _must_ come next? (no multiple statements)
2453    if (ex) {
2454      // When waiting for { it must be next symbol, but can be on a new line.
2455      if (!strcmp(ex, "{")) {
2456        if (strcmp(s, "{")) goto flush;
2457        free(arg->v[--arg->c]);  // don't save the {, function starts the block
2458        free(dlist_lpop(&sp->expect));
2459
2460        continue;
2461
2462      // The "test" part of for/select loops can have (at most) one "in" line,
2463      // for {((;;))|name [in...]} do
2464      } else if (!memcmp(ex, "do\0C", 4)) {
2465        if (strcmp(s, "do")) {
2466          // can only have one "in" line between for/do, but not with for(())
2467          if (pl->prev->type == 's') goto flush;
2468          if (!strncmp(pl->prev->arg->v[1], "((", 2)) goto flush;
2469          else if (strcmp(s, "in")) goto flush;
2470          pl->type = 's';
2471
2472          continue;
2473        }
2474      }
2475    }
2476
2477    // start of a new block?
2478
2479    // for/select/case require var name on same line, can't break segment yet
2480    if (!strcmp(s, "for") || !strcmp(s, "select") || !strcmp(s, "case")) {
2481// TODO why !pl->type here
2482      if (!pl->type) pl->type = (*s == 'c') ? 128 : 1;
2483      dlist_add(&sp->expect, (*s == 'c') ? "esac" : "do\0A");
2484
2485      continue;
2486    }
2487
2488    end = 0;
2489    if (!strcmp(s, "if")) end = "then";
2490    else if (!strcmp(s, "while") || !strcmp(s, "until")) end = "do\0B";
2491    else if (!strcmp(s, "{")) end = "}";
2492    else if (!strcmp(s, "[[")) end = "]]";
2493    else if (!strcmp(s, "(")) end = ")";
2494
2495    // Expecting NULL means a statement: I.E. any otherwise unrecognized word
2496    if (!ex && sp->expect) free(dlist_lpop(&sp->expect));
2497
2498    // Did we start a new statement
2499    if (end) {
2500      pl->type = 1;
2501
2502      // Only innermost statement needed in { { { echo ;} ;} ;} and such
2503      if (sp->expect && !sp->expect->prev->data) free(dlist_lpop(&sp->expect));
2504
2505    // if can't end a statement here skip next few tests
2506    } else if (!ex);
2507
2508    // If we got here we expect a specific word to end this block: is this it?
2509    else if (!strcmp(s, ex)) {
2510      struct sh_arg *aa = pl->prev->arg;
2511
2512      // can't "if | then" or "while && do", only ; & or newline works
2513      if (aa->v[aa->c] && strcmp(aa->v[aa->c], "&")) goto flush;
2514
2515      // consume word, record block end location in earlier !0 type blocks
2516      free(dlist_lpop(&sp->expect));
2517      if (3 == (pl->type = anystr(s, tails) ? 3 : 2)) {
2518        for (i = 0, pl2 = pl3 = pl; (pl2 = pl2->prev);) {
2519          if (pl2->type == 3) i++;
2520          else if (pl2->type) {
2521            if (!i) {
2522              if (pl2->type == 2) {
2523                pl2->end = pl3;
2524                pl3 = pl2;
2525              } else pl2->end = pl;
2526            }
2527            if ((pl2->type == 1 || pl2->type == 'f') && --i<0) break;
2528          }
2529        }
2530      }
2531
2532      // if it's a multipart block, what comes next?
2533      if (!strcmp(s, "do")) end = "done";
2534      else if (!strcmp(s, "then")) end = "fi\0A";
2535
2536    // fi could have elif, which queues a then.
2537    } else if (!strcmp(ex, "fi")) {
2538      if (!strcmp(s, "elif")) {
2539        free(dlist_lpop(&sp->expect));
2540        end = "then";
2541      // catch duplicate else while we're here
2542      } else if (!strcmp(s, "else")) {
2543        if (ex[3] != 'A') {
2544          s = "2 else";
2545          goto flush;
2546        }
2547        free(dlist_lpop(&sp->expect));
2548        end = "fi\0B";
2549      }
2550    }
2551
2552    // Queue up the next thing to expect, all preceded by a statement
2553    if (end) {
2554      if (!pl->type) pl->type = 2;
2555
2556      dlist_add(&sp->expect, end);
2557      if (!anystr(end, tails)) dlist_add(&sp->expect, 0);
2558      pl->count = -1;
2559    }
2560
2561    // syntax error check: these can't be the first word in an unexpected place
2562    if (!pl->type && anystr(s, (char *[]){"then", "do", "esac", "}", "]]", ")",
2563        "done", "fi", "elif", "else", 0})) goto flush;
2564  }
2565  free(delete);
2566
2567  // ignore blank and comment lines
2568  if (!sp->pipeline) return 0;
2569
2570// TODO <<< has no parsing impact, why play with it here at all?
2571  // advance past <<< arguments (stored as here documents, but no new input)
2572  pl = sp->pipeline->prev;
2573  while (pl->count<pl->here && pl->arg[pl->count].c<0)
2574    pl->arg[pl->count++].c = 0;
2575
2576  // return if HERE document pending or more flow control needed to complete
2577  if (sp->expect) return 1;
2578  if (sp->pipeline && pl->count != pl->here) return 1;
2579  if (pl->arg->v[pl->arg->c] && strcmp(pl->arg->v[pl->arg->c], "&")) return 1;
2580
2581  // Don't need more input, can start executing.
2582
2583  dlist_terminate(sp->pipeline);
2584  return 0;
2585
2586flush:
2587  if (s) syntax_err(s);
2588  free_function(sp);
2589
2590  return 0-!!s;
2591}
2592
2593// wait for every process in a pipeline to end
2594static int wait_pipeline(struct sh_process *pp)
2595{
2596  int rc = 0;
2597
2598  for (dlist_terminate(pp); pp; pp = pp->next) {
2599    if (pp->pid) {
2600      // TODO job control: not xwait, handle EINTR ourselves and check signals
2601      pp->exit = xwaitpid(pp->pid);
2602      pp->pid = 0;
2603    }
2604    // TODO handle set -o pipefail here
2605    rc = pp->not ? !pp->exit : pp->exit;
2606  }
2607
2608  return rc;
2609}
2610
2611// pipe data into and out of this segment, I.E. handle leading and trailing |
2612static int pipe_segments(char *ctl, int *pipes, int **urd)
2613{
2614  unredirect(*urd);
2615  *urd = 0;
2616
2617  // Did the previous pipe segment pipe input into us?
2618  if (*pipes != -1) {
2619    if (save_redirect(urd, *pipes, 0)) return 1;
2620    close(*pipes);
2621    *pipes = -1;
2622  }
2623
2624  // are we piping output to the next segment?
2625  if (ctl && *ctl == '|' && ctl[1] != '|') {
2626    if (pipe(pipes)) {
2627      perror_msg("pipe");
2628// TODO record pipeline rc
2629// TODO check did not reach end of pipeline after loop
2630      return 1;
2631    }
2632    if (save_redirect(urd, pipes[1], 1)) {
2633      close(pipes[0]);
2634      close(pipes[1]);
2635
2636      return 1;
2637    }
2638    if (pipes[1] != 1) close(pipes[1]);
2639    fcntl(*pipes, F_SETFD, FD_CLOEXEC);
2640    if (ctl[1] == '&') save_redirect(urd, 1, 2);
2641  }
2642
2643  return 0;
2644}
2645
2646struct blockstack {
2647  struct blockstack *next;
2648  struct sh_pipeline *start, *middle;
2649  struct sh_process *pp;       // list of processes piping in to us
2650  int run, loop, *urd, pout;
2651  struct sh_arg farg;          // for/select arg stack, case wildcard deck
2652  struct arg_list *fdelete;    // farg's cleanup list
2653  char *fvar;                  // for/select's iteration variable name
2654};
2655
2656// when ending a block, free, cleanup redirects and pop stack.
2657static struct sh_pipeline *pop_block(struct blockstack **blist, int *pout)
2658{
2659  struct blockstack *blk = *blist;
2660  struct sh_pipeline *pl = blk->start->end;
2661
2662  // when ending a block, free, cleanup redirects and pop stack.
2663  if (*pout != -1) close(*pout);
2664  *pout = blk->pout;
2665  unredirect(blk->urd);
2666  llist_traverse(blk->fdelete, free);
2667  free(blk->farg.v);
2668  free(llist_pop(blist));
2669
2670  return pl;
2671}
2672
2673// Print prompt to stderr, parsing escapes
2674// Truncated to 4k at the moment, waiting for somebody to complain.
2675static void do_prompt(char *prompt)
2676{
2677  char *s, *ss, c, cc, *pp = toybuf;
2678  int len, ll;
2679
2680  if (!prompt) return;
2681  while ((len = sizeof(toybuf)-(pp-toybuf))>0 && *prompt) {
2682    c = *(prompt++);
2683
2684    if (c=='!') {
2685      if (*prompt=='!') prompt++;
2686      else {
2687        pp += snprintf(pp, len, "%ld", TT.lineno);
2688        continue;
2689      }
2690    } else if (c=='\\') {
2691      cc = *(prompt++);
2692      if (!cc) {
2693        *pp++ = c;
2694        break;
2695      }
2696
2697      // \nnn \dD{}hHjlstT@AuvVwW!#$
2698      // Ignore bash's "nonprintable" hack; query our cursor position instead.
2699      if (cc=='[' || cc==']') continue;
2700      else if (cc=='$') *pp++ = getuid() ? '$' : '#';
2701      else if (cc=='h' || cc=='H') {
2702        *pp = 0;
2703        gethostname(pp, len);
2704        pp[len-1] = 0;
2705        if (cc=='h' && (s = strchr(pp, '.'))) *s = 0;
2706        pp += strlen(pp);
2707      } else if (cc=='s') {
2708        s = getbasename(*toys.argv);
2709        while (*s && len--) *pp++ = *s++;
2710      } else if (cc=='w') {
2711        if ((s = getvar("PWD"))) {
2712          if ((ss = getvar("HOME")) && strstart(&s, ss)) {
2713            *pp++ = '~';
2714            if (--len && *s!='/') *pp++ = '/';
2715            len--;
2716          }
2717          if (len>0) {
2718            ll = strlen(s);
2719            pp = stpncpy(pp, s, ll>len ? len : ll);
2720          }
2721        }
2722      } else if (!(c = unescape(cc))) {
2723        *pp++ = '\\';
2724        if (--len) *pp++ = c;
2725      } else *pp++ = c;
2726    } else *pp++ = c;
2727  }
2728  len = pp-toybuf;
2729  if (len>=sizeof(toybuf)) len = sizeof(toybuf);
2730  writeall(2, toybuf, len);
2731}
2732
2733// run a parsed shell function. Handle flow control blocks and characters,
2734// setup pipes and block redirection, break/continue, call builtins,
2735// vfork/exec external commands.
2736static void run_function(struct sh_pipeline *pl)
2737{
2738  struct blockstack *blk = 0, *new;
2739  struct sh_process *pplist = 0; // processes piping into current level
2740  int *urd = 0, pipes[2] = {-1, -1};
2741  long i;
2742
2743// TODO: "echo | read i" is backgroundable with ctrl-Z despite read = builtin.
2744//       probably have to inline run_command here to do that? Implicit ()
2745//       also "X=42 | true; echo $X" doesn't get X.
2746//       I.E. run_subshell() here sometimes? (But when?)
2747// TODO: bash supports "break &" and "break > file". No idea why.
2748// TODO If we just started a new pipeline, implicit parentheses (subshell)
2749// TODO can't free sh_process delete until ready to dispose else no debug output
2750/*
2751TODO: a | b | c needs subshell for builtins?
2752        - anything that can produce output
2753        - echo declare dirs
2754      (a; b; c) like { } but subshell
2755      when to auto-exec? ps vs sh -c 'ps' vs sh -c '(ps)'
2756*/
2757
2758  TT.hfd = 10;
2759
2760  // iterate through pipeline segments
2761  while (pl) {
2762    char *ctl = pl->end->arg->v[pl->end->arg->c], **vv,
2763      *s = *pl->arg->v, *ss = pl->arg->v[1];
2764
2765    // Skip disabled blocks, handle pipes
2766    if (pl->type<2) {
2767      if (blk && !blk->run) {
2768        pl = pl->end->next;
2769        continue;
2770      }
2771      if (pipe_segments(ctl, pipes, &urd)) break;
2772    }
2773
2774    // Is this an executable segment?
2775    if (!pl->type) {
2776
2777      // Is it a flow control jump? These aren't handled as normal builtins
2778      // because they move *pl to other pipeline segments which is local here.
2779      if (!strcmp(s, "break") || !strcmp(s, "continue")) {
2780
2781        // How many layers to peel off?
2782        i = ss ? atol(ss) : 0;
2783        if (i<1) i = 1;
2784        if (!blk || pl->arg->c>2 || ss[strspn(ss, "0123456789")]) {
2785          syntax_err(s);
2786          break;
2787        }
2788
2789        while (i && blk)
2790          if (!--i && *s == 'c') pl = blk->start;
2791          else pl = pop_block(&blk, pipes);
2792        if (i) {
2793          syntax_err("break");
2794          break;
2795        }
2796      } else {
2797        // Parse and run next command, saving resulting process
2798        dlist_add_nomalloc((void *)&pplist, (void *)run_command(pl->arg));
2799
2800        // Three cases: backgrounded&, pipelined|, last process in pipeline;
2801        if (ctl && !strcmp(ctl, "&")) {
2802          pplist->job = ++TT.jobcnt;
2803          arg_add(&TT.jobs, (void *)pplist);
2804          pplist = 0;
2805        }
2806      }
2807
2808    // Start of flow control block?
2809    } else if (pl->type == 1) {
2810      struct sh_process *pp = 0;
2811      int rc;
2812
2813      // Save new block and add it to the stack.
2814      new = xzalloc(sizeof(*blk));
2815      new->next = blk;
2816      blk = new;
2817      blk->start = pl;
2818      blk->run = 1;
2819
2820      // push pipe and redirect context into block
2821      blk->pout = *pipes;
2822      *pipes = -1;
2823      pp = expand_redir(pl->end->arg, 1, blk->urd = urd);
2824      urd = 0;
2825      rc = pp->exit;
2826      if (pp->arg.c) {
2827        syntax_err(*pp->arg.v);
2828        rc = 1;
2829      }
2830
2831      // Cleanup if we're not doing a subshell
2832      if (rc || strcmp(s, "(")) {
2833        llist_traverse(pp->delete, free);
2834        free(pp);
2835        if (rc) {
2836          toys.exitval = rc;
2837          break;
2838        }
2839      } else {
2840        // Create new process
2841        if (!CFG_TOYBOX_FORK) {
2842          ss = pl2str(pl->next);
2843          pp->pid = run_subshell(ss, strlen(ss));
2844          free(ss);
2845        } else if (!(pp->pid = fork())) {
2846          run_function(pl->next);
2847          _exit(toys.exitval);
2848        }
2849
2850        // add process to current pipeline same as type 0
2851        dlist_add_nomalloc((void *)&pplist, (void *)pp);
2852        pl = pl->end;
2853        continue;
2854      }
2855
2856      // What flow control statement is this?
2857
2858      // {/} if/then/elif/else/fi, while until/do/done - no special handling
2859
2860      // for/select/do/done: populate blk->farg with expanded arguments (if any)
2861      if (!strcmp(s, "for") || !strcmp(s, "select")) {
2862        if (blk->loop); // TODO: still needed?
2863        else if (!strncmp(blk->fvar = ss, "((", 2)) {
2864          blk->loop = 1;
2865dprintf(2, "TODO skipped init for((;;)), need math parser\n");
2866
2867        // in LIST
2868        } else if (pl->next->type == 's') {
2869          for (i = 1; i<pl->next->arg->c; i++)
2870            if (expand_arg(&blk->farg, pl->next->arg->v[i], 0, &blk->fdelete))
2871              break;
2872          if (i != pl->next->arg->c) pl = pop_block(&blk, pipes);
2873        // in without LIST. (This expansion can't return error.)
2874        } else expand_arg(&blk->farg, "\"$@\"", 0, &blk->fdelete);
2875
2876        // TODO: ls -C style output
2877        if (*s == 's') for (i = 0; i<blk->farg.c; i++)
2878          dprintf(2, "%ld) %s\n", i+1, blk->farg.v[i]);
2879
2880      // TODO: bash man page says it performs <(process substituion) here?!?
2881      } else if (!strcmp(s, "case"))
2882        if (!(blk->fvar = expand_one_arg(ss, NO_NULL, &blk->fdelete))) break;
2883
2884// TODO [[/]] ((/)) function/}
2885
2886    // gearshift from block start to block body (end of flow control test)
2887    } else if (pl->type == 2) {
2888      int match, err;
2889
2890      blk->middle = pl;
2891
2892      // ;; end, ;& continue through next block, ;;& test next block
2893      if (!strcmp(*blk->start->arg->v, "case")) {
2894        if (!strcmp(s, ";;")) {
2895          while (pl->type!=3) pl = pl->end;
2896          continue;
2897        } else if (strcmp(s, ";&")) {
2898          struct sh_arg arg = {0}, arg2 = {0};
2899
2900          for (err = 0, vv = 0;;) {
2901            if (!vv) {
2902              vv = pl->arg->v + (**pl->arg->v == ';');
2903              if (!*vv) {
2904                pl = pl->next; // TODO syntax err if not type==3, catch above
2905                break;
2906              } else vv += **vv == '(';
2907            }
2908            arg.c = 0;
2909            if ((err = expand_arg_nobrace(&arg, *vv++, NO_SPLIT, &blk->fdelete,
2910              &arg2))) break;
2911            s = arg.c ? *arg.v : "";
2912            match = wildcard_match(blk->fvar, s, &arg2, 0);
2913            if (match>=0 && !s[match]) break;
2914            else if (**vv++ == ')') {
2915              vv = 0;
2916              if ((pl = pl->end)->type!=2) break;
2917            }
2918          }
2919          free(arg.v);
2920          free(arg2.v);
2921          if (err) break;
2922          if (pl->type==3) continue;
2923        }
2924
2925      // Handle if/else/elif statement
2926      } else if (!strcmp(s, "then")) blk->run = blk->run && !toys.exitval;
2927      else if (!strcmp(s, "else") || !strcmp(s, "elif")) blk->run = !blk->run;
2928
2929      // Loop
2930      else if (!strcmp(s, "do")) {
2931        ss = *blk->start->arg->v;
2932        if (!strcmp(ss, "while")) blk->run = blk->run && !toys.exitval;
2933        else if (!strcmp(ss, "until")) blk->run = blk->run && toys.exitval;
2934        else if (!strcmp(ss, "select")) {
2935          do_prompt(getvar("PS3"));
2936// TODO: ctrl-c not breaking out of this?
2937          if (!(ss = xgetline(stdin, 0))) {
2938            pl = pop_block(&blk, pipes);
2939            printf("\n");
2940          } else if (!*ss) {
2941            pl = blk->start;
2942            continue;
2943          } else {
2944            match = atoi(ss);
2945            setvarval(blk->fvar, (match<1 || match>blk->farg.c)
2946              ? "" : blk->farg.v[match-1]);
2947          }
2948        } else if (blk->loop >= blk->farg.c) pl = pop_block(&blk, pipes);
2949        else if (!strncmp(blk->fvar, "((", 2)) {
2950dprintf(2, "TODO skipped running for((;;)), need math parser\n");
2951        } else setvarval(blk->fvar, blk->farg.v[blk->loop++]);
2952      }
2953
2954    // end of block, may have trailing redirections and/or pipe
2955    } else if (pl->type == 3) {
2956
2957      // if we end a block we're not in, we started in a block (subshell)
2958      if (!blk) break;
2959
2960      // repeating block?
2961      if (blk->run && !strcmp(s, "done")) {
2962        pl = blk->middle;
2963        continue;
2964      }
2965
2966      pop_block(&blk, pipes);
2967    } else if (pl->type == 'f') pl = add_function(s, pl);
2968
2969    // If we ran a process and didn't pipe output or background, wait for exit
2970    if (pplist && *pipes == -1) {
2971      toys.exitval = wait_pipeline(pplist);
2972      llist_traverse(pplist, free_process);
2973      pplist = 0;
2974    }
2975
2976    // for && and || skip pipeline segment(s) based on return code
2977    if (!pl->type || pl->type == 3) {
2978      while (ctl && !strcmp(ctl, toys.exitval ? "&&" : "||")) {
2979        if ((pl = pl->next)->type) pl = pl->end;
2980        ctl = pl->arg->v[pl->arg->c];
2981      }
2982    }
2983    pl = pl->next;
2984  }
2985
2986  // did we exit with unfinished stuff?
2987  // TODO: current context isn't packaged into a block, so can't just pop it
2988  if (*pipes != -1) close(*pipes);
2989  if (pplist) {
2990    toys.exitval = wait_pipeline(pplist);
2991    llist_traverse(pplist, free_process);
2992  }
2993  unredirect(urd);
2994
2995  // Cleanup from syntax_err();
2996  while (blk) pop_block(&blk, pipes);
2997}
2998
2999// Parse and run a self-contained command line with no prompt/continuation
3000static int sh_run(char *new)
3001{
3002  struct sh_function scratch;
3003
3004// TODO switch the fmemopen for -c to use this? Error checking? $(blah)
3005
3006  memset(&scratch, 0, sizeof(struct sh_function));
3007  if (!parse_line(new, &scratch)) run_function(scratch.pipeline);
3008  free_function(&scratch);
3009
3010  return toys.exitval;
3011}
3012
3013// only set local variable when global not present, does not extend array
3014static struct sh_vars *initlocal(char *name, char *val)
3015{
3016  return addvar(xmprintf("%s=%s", name, val ? val : ""));
3017}
3018
3019static struct sh_vars *initlocaldef(char *name, char *val, char *def)
3020{
3021  return initlocal(name, (!val || !*val) ? def : val);
3022}
3023
3024// export existing "name" or assign/export name=value string (making new copy)
3025static void export(char *str)
3026{
3027  struct sh_vars *shv = 0;
3028  char *s;
3029
3030  // Make sure variable exists and is updated
3031  if (strchr(str, '=')) shv = setvar(xstrdup(str));
3032  else if (!(shv = findvar(str))) shv = addvar(str = xmprintf("%s=", str));
3033  if (!shv || (shv->flags&VAR_GLOBAL)) return;
3034
3035  // Resolve local magic for export
3036  if (shv->flags&VAR_MAGIC) {
3037    s = shv->str;
3038    shv->str = xmprintf("%.*s=%s", (int)(varend(str)-str), str, getvar(str));
3039    free(s);
3040  }
3041
3042  xsetenv(shv->str, 0);
3043  shv->flags |= VAR_GLOBAL;
3044}
3045
3046static void unexport(char *str)
3047{
3048  struct sh_vars *shv = findvar(str);
3049
3050  if (shv) {
3051    if (shv->flags&VAR_GLOBAL) shv->str = xpop_env(str);
3052    shv->flags &=~VAR_GLOBAL;
3053  }
3054  if (strchr(str, '=')) setvar(str);
3055}
3056
3057// init locals, sanitize environment, handle nommu subshell handoff
3058static void subshell_setup(void)
3059{
3060  int ii, to, from, pid, ppid, zpid, myppid = getppid(), len, uid = getuid();
3061  struct passwd *pw = getpwuid(uid);
3062  char *s, *ss, *magic[] = {"SECONDS","RANDOM","LINENO","GROUPS"},
3063    *readonly[] = {xmprintf("EUID=%d", geteuid()), xmprintf("UID=%d", uid),
3064                   xmprintf("PPID=%d", myppid)};
3065  struct stat st;
3066  struct utsname uu;
3067  FILE *fp;
3068
3069  // Initialize magic and read only local variables
3070  srandom(TT.SECONDS = millitime());
3071  for (ii = 0; ii<ARRAY_LEN(magic); ii++)
3072    initlocal(magic[ii], "")->flags = VAR_MAGIC|(VAR_INT*('G'!=*magic[ii]));
3073  for (ii = 0; ii<ARRAY_LEN(readonly); ii++)
3074    addvar(readonly[ii])->flags = VAR_READONLY|VAR_INT;
3075
3076  // Add local variables that can be overwritten
3077  initlocal("PATH", _PATH_DEFPATH);
3078  if (!pw) pw = (void *)toybuf; // first use, so still zeroed
3079  sprintf(toybuf+1024, "%u", uid);
3080  initlocaldef("HOME", pw->pw_dir, "/");
3081  initlocaldef("SHELL", pw->pw_shell, "/bin/sh");
3082  initlocaldef("USER", pw->pw_name, toybuf+1024);
3083  initlocaldef("LOGNAME", pw->pw_name, toybuf+1024);
3084  gethostname(toybuf, sizeof(toybuf)-1);
3085  initlocal("HOSTNAME", toybuf);
3086  uname(&uu);
3087  initlocal("HOSTTYPE", uu.machine);
3088  sprintf(toybuf, "%s-unknown-linux", uu.machine);
3089  initlocal("MACHTYPE", toybuf);
3090  initlocal("OSTYPE", uu.sysname);
3091  // sprintf(toybuf, "%s-toybox", TOYBOX_VERSION);
3092  // initlocal("BASH_VERSION", toybuf);
3093  initlocal("OPTERR", "1"); // TODO: test if already exported?
3094  if (readlink0("/proc/self/exe", s = toybuf, sizeof(toybuf))||(s=getenv("_")))
3095    initlocal("BASH", s);
3096  initlocal("PS2", "> ");
3097  initlocal("PS3", "#? ");
3098
3099  // Ensure environ copied and toys.envc set, and clean out illegal entries
3100  TT.ifs = " \t\n";
3101  xsetenv("", 0);
3102  for (to = from = pid = ppid = zpid = 0; (s = environ[from]); from++) {
3103
3104    // If nommu subshell gets handoff
3105    if (!CFG_TOYBOX_FORK && !toys.stacktop) {
3106      len = 0;
3107      sscanf(s, "@%d,%d%n", &pid, &ppid, &len);
3108      if (s[len]) pid = ppid = 0;
3109      if (*s == '$' && s[1] == '=') zpid = atoi(s+2);
3110// TODO marshall $- to subshell like $$
3111    }
3112
3113    // Filter out non-shell variable names from inherited environ.
3114    // (haven't xsetenv() yet so no need to free() or adjust toys.envc)
3115    ss = varend(s);
3116    if (*ss == '=') {
3117      struct sh_vars *shv = findvar(s);
3118
3119      if (!shv) addvar(environ[from])->flags = VAR_GLOBAL;
3120      else if (shv->flags&VAR_READONLY) continue;
3121      else {
3122        shv->flags |= VAR_GLOBAL;
3123        free(shv->str);
3124        shv->str = s;
3125      }
3126      environ[to++] = s;
3127    }
3128    if (!memcmp(s, "IFS=", 4)) TT.ifs = s+4;
3129  }
3130  environ[toys.optc = to] = 0;
3131
3132  // set/update PWD
3133  sh_run("cd .");
3134
3135  // set _ to path to this shell
3136  s = toys.argv[0];
3137  ss = 0;
3138  if (!strchr(s, '/')) {
3139    if ((ss = getcwd(0, 0))) {
3140      s = xmprintf("%s/%s", ss, s);
3141      free(ss);
3142      ss = s;
3143    } else if (*toybuf) s = toybuf;
3144  }
3145  s = xsetenv("_", s);
3146  if (!findvar(s)) addvar(s)->flags = VAR_GLOBAL;
3147  free(ss);
3148  if (!(ss = getvar("SHLVL"))) export("SHLVL=1");
3149  else {
3150    char buf[16];
3151
3152    sprintf(buf, "%u", atoi(ss+6)+1);
3153    xsetenv("SHLVL", buf);
3154    export("SHLVL");
3155  }
3156
3157//TODO indexed array,associative array,integer,local,nameref,readonly,uppercase
3158//          if (s+1<ss && strchr("aAilnru", *s)) {
3159
3160  // sanity check: magic env variable, pipe status
3161  if (CFG_TOYBOX_FORK || toys.stacktop || pid!=getpid() || ppid!=myppid) return;
3162  if (fstat(254, &st) || !S_ISFIFO(st.st_mode)) error_exit(0);
3163  TT.pid = zpid;
3164  fcntl(254, F_SETFD, FD_CLOEXEC);
3165  fp = fdopen(254, "r");
3166
3167// TODO This is not efficient, could array_add the local vars.
3168// TODO implicit exec when possible
3169  while ((s = xgetline(fp, 0))) toys.exitval = sh_run(s);
3170  fclose(fp);
3171
3172  xexit();
3173}
3174
3175FILE *fpathopen(char *name)
3176{
3177  struct string_list *sl = 0;
3178  FILE *f = fopen(name, "r");
3179  char *pp = getvar("PATH") ? : _PATH_DEFPATH;
3180
3181  if (!f) {
3182    for (sl = find_in_path(pp, *toys.optargs); sl; free(llist_pop(&sl)))
3183      if ((f = fopen(sl->str, "r"))) break;
3184    if (sl) llist_traverse(sl, free);
3185  }
3186
3187  return f;
3188}
3189
3190void sh_main(void)
3191{
3192  char *new, *cc = 0;
3193  struct sh_function scratch;
3194  int prompt = 0;
3195  struct string_list *sl = 0;
3196  struct sh_arg arg;
3197  FILE *f;
3198
3199  signal(SIGPIPE, SIG_IGN);
3200  TT.options = OPT_BRACE;
3201
3202  TT.pid = getpid();
3203  TT.SECONDS = time(0);
3204  TT.arg = &arg;
3205  if (!(arg.c = toys.optc)) {
3206    arg.v = xmalloc(2*sizeof(char *));
3207    arg.v[arg.c++] = *toys.argv;
3208    arg.v[arg.c] = 0;
3209  } else memcpy(arg.v = xmalloc((arg.c+1)*sizeof(char *)), toys.optargs,
3210      (arg.c+1)*sizeof(char *));
3211
3212  // TODO euid stuff?
3213  // TODO login shell?
3214  // TODO read profile, read rc
3215
3216  // if (!FLAG(noprofile)) { }
3217
3218  // Is this an interactive shell?
3219  if (toys.stacktop) {
3220    cc = TT.sh.c;
3221    if (FLAG(s) || (!FLAG(c) && !toys.optc)) TT.options |= OPT_S;
3222    if (FLAG(i) || (!FLAG(c) && (TT.options&OPT_S) && isatty(0)))
3223      TT.options |= OPT_I;
3224    if (FLAG(c)) TT.options |= OPT_C;
3225  }
3226
3227  // Read environment for exports from parent shell. Note, calls run_sh()
3228  // which blanks argument sections of TT and this, so parse everything
3229  // we need from shell command line before that.
3230  subshell_setup();
3231  if (TT.options&OPT_I) {
3232    if (!getvar("PS1")) setvarval("PS1", getpid() ? "\\$ " : "# ");
3233    // TODO Set up signal handlers and grab control of this tty.
3234    // ^C SIGINT ^\ SIGQUIT ^Z SIGTSTP SIGTTIN SIGTTOU SIGCHLD
3235    // setsid(), setpgid(), tcsetpgrp()...
3236    xsignal(SIGINT, SIG_IGN);
3237  }
3238
3239  memset(&scratch, 0, sizeof(scratch));
3240
3241// TODO unify fmemopen() here with sh_run
3242  if (cc) f = fmemopen(cc, strlen(cc), "r");
3243  else if (TT.options&OPT_S) f = stdin;
3244  else if (!(f = fpathopen(*toys.optargs))) perror_exit_raw(*toys.optargs);
3245
3246  // Loop prompting and reading lines
3247  for (;;) {
3248    TT.lineno++;
3249    if ((TT.options&(OPT_I|OPT_S|OPT_C)) == (OPT_I|OPT_S))
3250      do_prompt(getvar(prompt ? "PS2" : "PS1"));
3251
3252// TODO line editing/history, should set $COLUMNS $LINES and sigwinch update
3253    if (!(new = xgetline(f, 0))) {
3254// TODO: after first EINTR getline returns always closed?
3255      if (errno != EINTR) break;
3256      free_function(&scratch);
3257      prompt = 0;
3258      if (f != stdin) break;
3259      continue;
3260// TODO: ctrl-z during script read having already read partial line,
3261// SIGSTOP and SIGTSTP need need SA_RESTART, but child proc should stop
3262    }
3263
3264    if (sl) {
3265      if (*new == 0x7f) error_exit("'%s' is ELF", sl->str);
3266      free(sl);
3267      sl = 0;
3268    }
3269// TODO if (!isspace(*new)) add_to_history(line);
3270
3271    // returns 0 if line consumed, command if it needs more data
3272    if (1 != (prompt = parse_line(new, &scratch))) {
3273// TODO: ./blah.sh one two three: put one two three in scratch.arg
3274      if (!prompt) run_function(scratch.pipeline);
3275      free_function(&scratch);
3276      prompt = 0;
3277    }
3278    free(new);
3279  }
3280
3281  if (prompt) error_exit("%ld:unfinished line"+4*!TT.lineno, TT.lineno);
3282}
3283
3284/********************* shell builtin functions *************************/
3285
3286#define CLEANUP_sh
3287#define FOR_cd
3288#include "generated/flags.h"
3289void cd_main(void)
3290{
3291  char *home = getvar("HOME") ? : "/", *pwd = getvar("PWD"), *from, *to = 0,
3292    *dd = xstrdup(*toys.optargs ? *toys.optargs : home);
3293  int bad = 0;
3294
3295  // TODO: CDPATH? Really?
3296
3297  // prepend cwd or $PWD to relative path
3298  if (*dd != '/') {
3299    from = pwd ? : (to = getcwd(0, 0));
3300    if (!from) setvarval("PWD", "(nowhere)");
3301    else {
3302      from = xmprintf("%s/%s", from, dd);
3303      free(dd);
3304      free(to);
3305      dd = from;
3306    }
3307  }
3308
3309  if (FLAG(P)) {
3310    struct stat st;
3311    char *pp;
3312
3313    // Does this directory exist?
3314    if ((pp = xabspath(dd, 1)) && stat(pp, &st) && !S_ISDIR(st.st_mode))
3315      bad++, errno = ENOTDIR;
3316    else {
3317      free(dd);
3318      dd = pp;
3319    }
3320  } else {
3321
3322    // cancel out . and .. in the string
3323    for (from = to = dd; *from;) {
3324      if (*from=='/' && from[1]=='/') from++;
3325      else if (*from!='/' || from[1]!='.') *to++ = *from++;
3326      else if (!from[2] || from[2]=='/') from += 2;
3327      else if (from[2]=='.' && (!from[3] || from[3]=='/')) {
3328        from += 3;
3329        while (to>dd && *--to != '/');
3330      } else *to++ = *from++;
3331    }
3332    if (to == dd) to++;
3333    if (to-dd>1 && to[-1]=='/') to--;
3334    *to = 0;
3335  }
3336
3337  if (bad || chdir(dd)) perror_msg("chdir '%s'", dd);
3338  else {
3339    if (pwd) {
3340      setvarval("OLDPWD", pwd);
3341      if (TT.cdcount == 1) {
3342        export("OLDPWD");
3343        TT.cdcount++;
3344      }
3345    }
3346    setvarval("PWD", dd);
3347    if (!TT.cdcount) {
3348      export("PWD");
3349      TT.cdcount++;
3350    }
3351  }
3352  free(dd);
3353}
3354
3355void exit_main(void)
3356{
3357  exit(*toys.optargs ? atoi(*toys.optargs) : 0);
3358}
3359
3360void unset_main(void)
3361{
3362  char **arg, *s;
3363
3364  for (arg = toys.optargs; *arg; arg++) {
3365    s = varend(*arg);
3366    if (s == *arg || *s) {
3367      error_msg("bad '%s'", *arg);
3368      continue;
3369    }
3370
3371    // unset magic variable?
3372    if (!strcmp(*arg, "IFS")) TT.ifs = " \t\n";
3373    unsetvar(*arg);
3374  }
3375}
3376
3377#define CLEANUP_cd
3378#define FOR_export
3379#include "generated/flags.h"
3380
3381void export_main(void)
3382{
3383  char **arg, *eq;
3384
3385  // list existing variables?
3386  if (!toys.optc) {
3387    for (arg = environ; *arg; arg++) xprintf("declare -x %s\n", *arg);
3388    return;
3389  }
3390
3391  // set/move variables
3392  for (arg = toys.optargs; *arg; arg++) {
3393    eq = varend(*arg);
3394    if (eq == *arg || (*eq && *eq != '=')) {
3395      error_msg("bad %s", *arg);
3396      continue;
3397    }
3398
3399    if (FLAG(n)) unexport(*arg);
3400    else export(*arg);
3401  }
3402}
3403
3404void eval_main(void)
3405{
3406  struct sh_arg *old = TT.arg, new = {toys.argv, toys.optc+1};
3407  char *s;
3408
3409  TT.arg = &new;
3410  s = expand_one_arg("\"$*\"", SEMI_IFS, 0);
3411  TT.arg = old;
3412  sh_run(s);
3413  free(s);
3414}
3415
3416#define CLEANUP_export
3417#define FOR_exec
3418#include "generated/flags.h"
3419
3420void exec_main(void)
3421{
3422  char *ee[1] = {0}, **old = environ;
3423
3424  // discard redirects and return if nothing to exec
3425  free(TT.pp->urd);
3426  TT.pp->urd = 0;
3427  if (!toys.optc) return;
3428
3429  // exec, handling -acl
3430  TT.isexec = *toys.optargs;
3431  if (FLAG(c)) environ = ee;
3432  if (TT.exec.a || FLAG(l))
3433    *toys.optargs = xmprintf("%s%s", FLAG(l) ? "-" : "", TT.exec.a?:TT.isexec);
3434  sh_exec(toys.optargs);
3435
3436  // report error (usually ENOENT) and return
3437  perror_msg("%s", TT.isexec);
3438  if (*toys.optargs != TT.isexec) free(*toys.optargs);
3439  TT.isexec = 0;
3440  toys.exitval = 127;
3441  environ = old;
3442}
3443
3444// Find + and - jobs. Returns index of plus, writes minus to *minus
3445int find_plus_minus(int *minus)
3446{
3447  long long when, then;
3448  int i, plus;
3449
3450  if (minus) *minus = 0;
3451  for (then = i = plus = 0; i<TT.jobs.c; i++) {
3452    if ((when = ((struct sh_process *)TT.jobs.v[i])->when) > then) {
3453      then = when;
3454      if (minus) *minus = plus;
3455      plus = i;
3456    }
3457  }
3458
3459  return plus;
3460}
3461
3462// Return T.jobs index or -1 from identifier
3463// Note, we don't return "ambiguous job spec", we return the first hit or -1.
3464// TODO %% %+ %- %?ab
3465int find_job(char *s)
3466{
3467  char *ss;
3468  long ll = strtol(s, &ss, 10);
3469  int i, j;
3470
3471  if (!TT.jobs.c) return -1;
3472  if (!*s || (!s[1] && strchr("%+-", *s))) {
3473    int minus, plus = find_plus_minus(&minus);
3474
3475    return (*s == '-') ? minus : plus;
3476  }
3477
3478  // Is this a %1 numeric jobspec?
3479  if (s != ss && !*ss)
3480    for (i = 0; i<TT.jobs.c; i++)
3481      if (((struct sh_process *)TT.jobs.v[i])->job == ll) return i;
3482
3483  // Match start of command or %?abc
3484  for (i = 0; i<TT.jobs.c; i++) {
3485    struct sh_process *pp = (void *)TT.jobs.v[i];
3486
3487    if (strstart(&s, *pp->arg.v)) return i;
3488    if (*s != '?' || !s[1]) continue;
3489    for (j = 0; j<pp->arg.c; j++) if (strstr(pp->arg.v[j], s+1)) return i;
3490  }
3491
3492  return -1;
3493}
3494
3495// We pass in dash to avoid looping over every job each time
3496void print_job(int i, char dash)
3497{
3498  struct sh_process *pp = (void *)TT.jobs.v[i];
3499  char *s = "Run";
3500  int j;
3501
3502// TODO Terminated (Exited)
3503  if (pp->exit<0) s = "Stop";
3504  else if (pp->exit>126) s = "Kill";
3505  else if (pp->exit>0) s = "Done";
3506  printf("[%d]%c  %-6s", pp->job, dash, s);
3507  for (j = 0; j<pp->raw->c; j++) printf(" %s"+!j, pp->raw->v[j]);
3508  printf("\n");
3509}
3510
3511void jobs_main(void)
3512{
3513  int i, j, minus, plus = find_plus_minus(&minus);
3514  char *s;
3515
3516// TODO -lnprs
3517
3518  for (i = 0;;i++) {
3519    if (toys.optc) {
3520      if (!(s = toys.optargs[i])) break;
3521      if ((j = find_job(s+('%' == *s))) == -1) {
3522        perror_msg("%s: no such job", s);
3523
3524        continue;
3525      }
3526    } else if ((j = i) >= TT.jobs.c) break;
3527
3528    print_job(i, (i == plus) ? '+' : (i == minus) ? '-' : ' ');
3529  }
3530}
3531
3532void shift_main(void)
3533{
3534  long long by = 1;
3535
3536  if (toys.optc) by = atolx(*toys.optargs);
3537  by += TT.shift;
3538  if (by<0 || by>=TT.arg->c) toys.exitval++;
3539  else TT.shift = by;
3540}
3541
3542void source_main(void)
3543{
3544  struct sh_function scratch;
3545  FILE *ff = fpathopen(*toys.optargs);
3546  long lineno = TT.lineno, shift = TT.shift, prompt;
3547  struct sh_arg arg, *old = TT.arg;
3548  char *new;
3549
3550  if (!ff) return perror_msg_raw(*toys.optargs);
3551
3552  arg.c = toys.optc;
3553  arg.v = toys.optargs;
3554  TT.arg = &arg;
3555  memset(&scratch, 0, sizeof(scratch));
3556
3557  // TODO: factor out and combine with sh_main() plumbing?
3558  for (TT.lineno = TT.shift = 0;;) {
3559    new = xgetline(ff, 0);
3560    if (!TT.lineno++ && new && *new == 0x7f) {
3561      error_msg("'%s' is ELF", *toys.optargs);
3562      free(new);
3563
3564      break;
3565    }
3566    if (1!=(prompt = parse_line(new ? : " ", &scratch))) {
3567      if (!prompt) run_function(scratch.pipeline);
3568      free_function(&scratch);
3569      if (!new) {
3570        if (prompt) syntax_err("unexpected end of file");
3571
3572        break;
3573      }
3574    }
3575    free(new);
3576  }
3577  fclose(ff);
3578  TT.lineno = lineno;
3579  TT.shift = shift;
3580  TT.arg = old;
3581}
3582