1 /* $OpenBSD: exec.c,v 1.52 2015/09/10 22:48:58 nicm Exp $ */
4 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5 * 2011, 2012, 2013, 2014, 2015
6 * mirabilos <m@mirbsd.org>
8 * Provided that these terms and disclaimer and all copyright notices
9 * are retained or reproduced in an accompanying document, permission
10 * is granted to deal in this work without restriction, including un-
11 * limited rights to use, publicly perform, distribute, sell, modify,
12 * merge, give away, or sublicence.
14 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
15 * the utmost extent permitted by applicable law, neither express nor
16 * implied; without malicious intent or gross negligence. In no event
17 * may a licensor, author or contributor be held liable for indirect,
18 * direct, other damage, loss, or other issues arising in any way out
19 * of dealing in the work, even if advised of the possibility of such
20 * damage or existence of a defect, except proven that it results out
21 * of said person's immediate fault when using the work as intended.
26 __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.170 2015/12/31 21:03:47 tg Exp $");
28 #ifndef MKSH_DEFAULT_EXECSHELL
29 #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
32 static int comexec(struct op *, struct tbl * volatile, const char **,
33 int volatile, volatile int *);
34 static void scriptexec(struct op *, const char **) MKSH_A_NORETURN;
35 static int call_builtin(struct tbl *, const char **, const char *, bool);
36 static int iosetup(struct ioword *, struct tbl *);
37 static int herein(struct ioword *, char **);
38 static const char *do_selectargs(const char **, bool);
39 static Test_op dbteste_isa(Test_env *, Test_meta);
40 static const char *dbteste_getopnd(Test_env *, Test_op, bool);
41 static void dbteste_error(Test_env *, int, const char *);
42 /* XXX: horrible kludge to fit within the framework */
43 static void plain_fmt_entry(char *, size_t, unsigned int, const void *);
44 static void select_fmt_entry(char *, size_t, unsigned int, const void *);
47 * execute command tree
50 execute(struct op * volatile t,
51 /* if XEXEC don't fork */
53 volatile int * volatile xerrok)
56 volatile int rv = 0, dummy = 0;
58 const char ** volatile ap = NULL;
62 struct tbl *tp = NULL;
68 /* Caller doesn't care if XERROK should propagate. */
72 if ((flags&XFORK) && !(flags&XEXEC) && t->type != TPIPE)
73 /* run in sub-process */
74 return (exchild(t, flags & ~XTIME, xerrok, -1));
80 /* we want to run an executable, do some variance checks */
81 if (t->type == TCOM) {
82 /* check if this is 'var=<<EOF' */
83 /*XXX this is broken, don’t use! */
84 /*XXX https://bugs.launchpad.net/mksh/+bug/1380389 */
86 /* we have zero arguments, i.e. no programme to run */
88 /* we have exactly one variable assignment */
89 t->vars[0] != NULL && t->vars[1] == NULL &&
90 /* we have exactly one I/O redirection */
91 t->ioact != NULL && t->ioact[0] != NULL &&
92 t->ioact[1] == NULL &&
93 /* of type "here document" (or "here string") */
94 (t->ioact[0]->ioflag & IOTYPE) == IOHERE &&
95 /* the variable assignment begins with a valid varname */
96 (ccp = skip_wdvarname(t->vars[0], true)) != t->vars[0] &&
97 /* and has no right-hand side (i.e. "varname=") */
98 ccp[0] == CHAR && ((ccp[1] == '=' && ccp[2] == EOS) ||
99 /* or "varname+=" */ (ccp[1] == '+' && ccp[2] == CHAR &&
100 ccp[3] == '=' && ccp[4] == EOS)) &&
101 /* plus we can have a here document content */
102 herein(t->ioact[0], &cp) == 0 && cp && *cp) {
104 size_t n = ccp - t->vars[0] + (ccp[1] == '+' ? 4 : 2);
107 /* drop redirection (will be garbage collected) */
110 /* set variable to its expanded value */
112 if (notoktomul(z, 2) || notoktoadd(z * 2, n + 1))
113 internal_errorf(Toomem, (size_t)-1);
114 dp = alloc(z * 2 + n + 1, APERM);
115 memcpy(dp, t->vars[0], n);
123 /* free the expanded value */
128 * Clear subst_exstat before argument expansion. Used by
129 * null commands (see comexec() and c_eval()) and by c_set().
134 current_lineno = t->lineno;
137 * POSIX says expand command words first, then redirections,
138 * and assignments last..
140 up = eval(t->args, t->u.evalflags | DOBLANK | DOGLOB | DOTILDE);
142 /* Allow option parsing (bizarre, but POSIX) */
144 ap = (const char **)up;
146 tp = findcom(ap[0], FC_BI|FC_FUNC);
150 if (t->ioact != NULL || t->type == TPIPE || t->type == TCOPROC) {
151 e->savefd = alloc2(NUFILE, sizeof(short), ATEMP);
152 /* initialise to not redirected */
153 memset(e->savefd, 0, NUFILE * sizeof(short));
156 /* mark for replacement later (unless TPIPE) */
157 vp_pipest->flag |= INT_L;
159 /* do redirection, to be restored in quitenv() */
160 if (t->ioact != NULL)
161 for (iowp = t->ioact; *iowp != NULL; iowp++) {
162 if (iosetup(*iowp, tp) < 0) {
165 * Redirection failures for special commands
166 * cause (non-interactive) shell to exit.
168 if (tp && tp->type == CSHELL &&
169 (tp->flag & SPEC_BI))
171 /* Deal with FERREXIT, quitenv(), etc. */
178 rv = comexec(t, tp, (const char **)ap, flags, xerrok);
182 rv = execute(t->left, flags | XFORK, xerrok);
188 e->savefd[0] = savefd(0);
189 e->savefd[1] = savefd(1);
190 while (t->type == TPIPE) {
193 ksh_dup2(pv[1], 1, false);
195 * Let exchild() close pv[0] in child
196 * (if this isn't done, commands like
197 * (: ; cat /etc/termcap) | sleep 1
198 * will hang forever).
200 exchild(t->left, flags | XPIPEO | XCCLOSE,
203 ksh_dup2(pv[0], 0, false);
209 restfd(1, e->savefd[1]);
210 /* no need to re-restore this */
212 /* Let exchild() close 0 in parent, after fork, before wait */
213 i = exchild(t, flags | XPCLOSE | XPIPEST, xerrok, 0);
214 if (!(flags&XBGND) && !(flags&XXCOM))
219 while (t->type == TLIST) {
220 execute(t->left, flags & XERROK, NULL);
223 rv = execute(t, flags & XERROK, xerrok);
227 #ifndef MKSH_NOPROSPECTOFWORK
231 * Block sigchild as we are using things changed in the
234 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
236 if ((i = kshsetjmp(e->jbuf))) {
237 sigprocmask(SIG_SETMASK, &omask, NULL);
243 /* Already have a (live) co-process? */
244 if (coproc.job && coproc.write >= 0)
245 errorf("coprocess already exists");
247 /* Can we re-use the existing co-process pipe? */
248 coproc_cleanup(true);
250 /* do this before opening pipes, in case these fail */
251 e->savefd[0] = savefd(0);
252 e->savefd[1] = savefd(1);
256 ksh_dup2(pv[0], 0, false);
259 coproc.write = pv[1];
262 if (coproc.readw >= 0)
263 ksh_dup2(coproc.readw, 1, false);
267 ksh_dup2(pv[1], 1, false);
268 /* closed before first read */
269 coproc.readw = pv[1];
271 /* create new coprocess id */
274 #ifndef MKSH_NOPROSPECTOFWORK
275 sigprocmask(SIG_SETMASK, &omask, NULL);
276 /* no more need for error handler */
281 * exchild() closes coproc.* in child after fork,
282 * will also increment coproc.njobs when the
283 * job is actually created.
286 exchild(t->left, flags | XBGND | XFORK | XCOPROC | XCCLOSE,
293 * XXX non-optimal, I think - "(foo &)", forks for (),
294 * forks again for async... parent should optimise
297 rv = execute(t->left, (flags&~XEXEC)|XBGND|XFORK, xerrok);
302 rv = execute(t->left, XERROK, xerrok);
303 if ((rv == 0) == (t->type == TAND))
304 rv = execute(t->right, flags & XERROK, xerrok);
313 rv = !execute(t->right, XERROK, xerrok);
322 te.flags = TEF_DBRACKET;
324 te.isa = dbteste_isa;
325 te.getopnd = dbteste_getopnd;
327 te.error = dbteste_error;
329 rv = test_parse(&te);
335 volatile bool is_first = true;
337 ap = (t->vars == NULL) ? e->loc->argv + 1 :
338 (const char **)eval((const char **)t->vars,
339 DOBLANK | DOGLOB | DOTILDE);
341 while ((i = kshsetjmp(e->jbuf))) {
342 if ((e->flags&EF_BRKCONT_PASS) ||
343 (i != LBREAK && i != LCONTIN)) {
346 } else if (i == LBREAK) {
351 /* in case of a continue */
353 if (t->type == TFOR) {
354 while (*ap != NULL) {
355 setstr(global(t->str), *ap++, KSH_UNWIND_ERROR);
356 rv = execute(t->left, flags & XERROK, xerrok);
361 if (!(ccp = do_selectargs(ap, is_first))) {
366 setstr(global(t->str), ccp, KSH_UNWIND_ERROR);
367 execute(t->left, flags & XERROK, xerrok);
376 while ((i = kshsetjmp(e->jbuf))) {
377 if ((e->flags&EF_BRKCONT_PASS) ||
378 (i != LBREAK && i != LCONTIN)) {
381 } else if (i == LBREAK) {
386 /* in case of a continue */
388 while ((execute(t->left, XERROK, NULL) == 0) ==
390 rv = execute(t->right, flags & XERROK, xerrok);
395 if (t->right == NULL)
396 /* should be error */
398 rv = execute(t->left, XERROK, NULL) == 0 ?
399 execute(t->right->left, flags & XERROK, xerrok) :
400 execute(t->right->right, flags & XERROK, xerrok);
405 ccp = evalstr(t->str, DOTILDE | DOSCALAR);
406 for (t = t->left; t != NULL && t->type == TPAT; t = t->right) {
407 for (ap = (const char **)t->vars; *ap; ap++) {
408 if (i || ((s = evalstr(*ap, DOTILDE|DOPAT)) &&
409 gmatchx(ccp, s, false))) {
410 rv = execute(t->left, flags & XERROK,
413 switch (t->u.charflag) {
431 rv = execute(t->left, flags & XERROK, xerrok);
435 rv = define(t->str, t);
440 * Clear XEXEC so nested execute() call doesn't exit
441 * (allows "ls -l | time grep foo").
443 rv = timex(t, flags & ~XEXEC, xerrok);
452 union mksh_ccphack cargs;
455 execve(t->str, cargs.rw, up);
459 scriptexec(t, (const char **)up);
461 errorf("%s: %s", t->str, cstrerror(rv));
465 if (vp_pipest->flag & INT_L) {
467 vp_pipest->flag = DEFINED | ISSET | INTEGER | RDONLY |
468 ARRAY | INT_U | INT_L;
469 vp_pipest->val.i = rv;
477 if (rv != 0 && !(flags & XERROK) &&
478 (xerrok == NULL || !*xerrok)) {
479 if (Flag(FERREXIT) & 0x80) {
492 * execute simple command
496 comexec(struct op *t, struct tbl * volatile tp, const char **ap,
497 volatile int flags, volatile int *xerrok)
503 /* Must be static (XXX but why?) */
504 static struct op texec;
507 int fcflags = FC_BI|FC_FUNC|FC_PATH;
508 struct block *l_expand, *l_assign;
510 const char *exec_argv0 = NULL;
511 bool exec_clrenv = false;
513 /* snag the last argument for $_ */
514 if (Flag(FTALKING) && *(lastp = ap)) {
516 * XXX not the same as AT&T ksh, which only seems to set $_
517 * after a newline (but not in functions/dot scripts, but in
518 * interactive and script) - perhaps save last arg here and
519 * set it in shell()?.
523 /* setstr() can't fail here */
524 setstr(typeset("_", LOCAL, 0, INTEGER, 0), *--lastp,
529 * Deal with the shell builtins builtin, exec and command since
530 * they can be followed by other commands. This must be done before
531 * we know if we should create a local block which must be done
532 * before we can do a path search (in case the assignments change
535 * FOO=bar exec >/dev/null FOO is kept but not exported
536 * FOO=bar exec foobar FOO is exported
537 * FOO=bar command exec >/dev/null FOO is neither kept nor exported
538 * FOO=bar command FOO is neither kept nor exported
539 * PATH=... foobar use new PATH in foobar search
542 while (tp && tp->type == CSHELL) {
543 /* undo effects of command */
544 fcflags = FC_BI|FC_FUNC|FC_PATH;
545 if (tp->val.f == c_builtin) {
546 if ((cp = *++ap) == NULL ||
547 (!strcmp(cp, "--") && (cp = *++ap) == NULL)) {
551 if ((tp = findcom(cp, FC_BI)) == NULL)
552 errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin");
553 if (tp->type == CSHELL && (tp->val.f == c_cat
554 #ifdef MKSH_PRINTF_BUILTIN
555 || tp->val.f == c_printf
560 } else if (tp->val.f == c_exec) {
563 ksh_getopt_reset(&builtin_opt, GF_ERROR);
564 while ((optc = ksh_getopt(ap, &builtin_opt, "a:c")) != -1)
567 exec_argv0 = builtin_opt.optarg;
571 /* ensure we can actually do this */
578 ap += builtin_opt.optind;
580 } else if (tp->val.f == c_command) {
584 * Ugly dealing with options in two places (here
585 * and in c_command(), but such is life)
587 ksh_getopt_reset(&builtin_opt, 0);
588 while ((optc = ksh_getopt(ap, &builtin_opt, ":p")) == 'p')
591 /* command -vV or something */
593 /* don't look for functions */
594 fcflags = FC_BI|FC_PATH;
596 if (Flag(FRESTRICTED)) {
597 warningf(true, "%s: %s",
598 "command -p", "restricted");
602 fcflags |= FC_DEFPATH;
604 ap += builtin_opt.optind;
606 * POSIX says special builtins lose their status
607 * if accessed using command.
611 /* ensure command with no args exits with 0 */
615 } else if (tp->val.f == c_cat) {
616 /* if we have any flags, do not use the builtin */
617 if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' &&
618 /* argument, begins with -, is not - or -- */
619 (ap[1][1] != '-' || ap[1][2] != '\0')) {
622 ext_cat = findcom(Tcat, FC_PATH | FC_FUNC);
623 if (ext_cat && (ext_cat->type != CTALIAS ||
624 (ext_cat->flag & ISSET)))
628 #ifdef MKSH_PRINTF_BUILTIN
629 } else if (tp->val.f == c_printf) {
630 struct tbl *ext_printf;
632 ext_printf = findcom(Tprintf, FC_PATH | FC_FUNC);
633 if (ext_printf && (ext_printf->type != CTALIAS ||
634 (ext_printf->flag & ISSET)))
638 } else if (tp->val.f == c_trap) {
639 t->u.evalflags &= ~DOTCOMEXEC;
643 tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC));
645 if (t->u.evalflags & DOTCOMEXEC)
648 if (!resetspec && (!ap[0] || (tp && (tp->flag & KEEPASN))))
651 /* create new variable/function block */
653 /* ksh functions don't keep assignments, POSIX functions do. */
654 if (!resetspec && tp && tp->type == CFUNC &&
658 type_flags = LOCAL|LOCAL_COPY|EXPORT;
662 l_assign->flags |= BF_STOPENV;
664 type_flags |= EXPORT;
666 change_xtrace(2, false);
667 for (i = 0; t->vars[i]; i++) {
668 /* do NOT lookup in the new var/fn block just created */
670 cp = evalstr(t->vars[i], DOASNTILDE | DOSCALAR);
675 ccp = skip_varname(cp, true);
680 shf_write(cp, ccp - cp, shl_xtrace);
681 print_value_quoted(shl_xtrace, ccp);
682 shf_putc(' ', shl_xtrace);
684 /* but assign in there as usual */
685 typeset(cp, type_flags, 0, 0, 0);
689 change_xtrace(2, false);
692 print_value_quoted(shl_xtrace, ap[rv]);
694 shf_putc(' ', shl_xtrace);
698 change_xtrace(1, false);
701 if ((cp = *ap) == NULL) {
705 if (Flag(FRESTRICTED) && vstrchr(cp, '/')) {
706 warningf(true, "%s: %s", cp, "restricted");
710 tp = findcom(cp, fcflags);
718 rv = call_builtin(tp, (const char **)ap, null, resetspec);
719 if (resetspec && tp->val.f == c_shift) {
720 l_expand->argc = l_assign->argc;
721 l_expand->argv = l_assign->argv;
727 volatile uint32_t old_inuse;
728 const char * volatile old_kshname;
729 volatile uint8_t old_flags[FNFLAGS];
731 if (!(tp->flag & ISSET)) {
735 rv = (tp->u2.errnov == ENOENT) ? 127 : 126;
736 warningf(true, "%s: %s %s: %s", cp,
737 "can't find", "function definition file",
738 cstrerror(tp->u2.errnov));
741 if (include(tp->u.fpath, 0, NULL, false) < 0) {
742 if (!strcmp(cp, Tcat)) {
744 tp = findcom(Tcat, FC_BI);
745 goto do_call_builtin;
747 #ifdef MKSH_PRINTF_BUILTIN
748 if (!strcmp(cp, Tprintf)) {
750 tp = findcom(Tprintf, FC_BI);
751 goto do_call_builtin;
754 warningf(true, "%s: %s %s %s: %s", cp,
755 "can't open", "function definition file",
756 tp->u.fpath, cstrerror(errno));
760 if (!(ftp = findfunc(cp, hash(cp), false)) ||
761 !(ftp->flag & ISSET)) {
762 if (!strcmp(cp, Tcat))
763 goto no_cat_in_FPATH;
764 #ifdef MKSH_PRINTF_BUILTIN
765 if (!strcmp(cp, Tprintf))
766 goto no_printf_in_FPATH;
768 warningf(true, "%s: %s %s", cp,
769 "function not defined by", tp->u.fpath);
777 * ksh functions set $0 to function name, POSIX
778 * functions leave $0 unchanged.
780 old_kshname = kshname;
786 for (i = 0; *ap++ != NULL; i++)
788 e->loc->argc = i - 1;
790 * ksh-style functions handle getopts sanely,
791 * Bourne/POSIX functions are insane...
793 if (tp->flag & FKSH) {
794 e->loc->flags |= BF_DOGETOPTS;
795 e->loc->getopts_state = user_opt;
799 for (type_flags = 0; type_flags < FNFLAGS; ++type_flags)
800 old_flags[type_flags] = shell_flags[type_flags];
801 change_xtrace((Flag(FXTRACEREC) ? Flag(FXTRACE) : 0) |
802 ((tp->flag & TRACE) ? 1 : 0), false);
803 old_inuse = tp->flag & FINUSE;
807 if (!(i = kshsetjmp(e->jbuf))) {
808 execute(tp->val.t, flags & XERROK, NULL);
812 kshname = old_kshname;
813 change_xtrace(old_flags[(int)FXTRACE], false);
814 #ifndef MKSH_LEGACY_MODE
815 if (tp->flag & FKSH) {
816 /* Korn style functions restore Flags on return */
817 old_flags[(int)FXTRACE] = Flag(FXTRACE);
818 for (type_flags = 0; type_flags < FNFLAGS; ++type_flags)
819 shell_flags[type_flags] = old_flags[type_flags];
822 tp->flag = (tp->flag & ~FINUSE) | old_inuse;
825 * Were we deleted while executing? If so, free the
828 if ((tp->flag & (FDELETE|FINUSE)) == FDELETE) {
829 if (tp->flag & ALLOC) {
831 tfree(tp->val.t, tp->areap);
849 internal_errorf("%s %d", "CFUNC", i);
854 /* executable command */
858 if (!(tp->flag&ISSET)) {
859 if (tp->u2.errnov == ENOENT) {
861 warningf(true, "%s: %s", cp, "not found");
864 warningf(true, "%s: %s: %s", cp, "can't execute",
865 cstrerror(tp->u2.errnov));
870 /* set $_ to program's full path */
871 /* setstr() can't fail here */
872 setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0),
873 tp->val.s, KSH_RETURN_ERROR);
875 /* to fork, we set up a TEXEC node and call execute */
877 /* for vistree/dumptree */
879 texec.str = tp->val.s;
882 /* in this case we do not fork, of course */
885 texec.args[0] = exec_argv0;
888 #ifndef MKSH_UNEMPLOYED
892 setexecsig(&sigtraps[SIGINT], SS_RESTORE_ORIG);
893 setexecsig(&sigtraps[SIGQUIT], SS_RESTORE_ORIG);
897 rv = exchild(&texec, flags, xerrok, -1);
909 scriptexec(struct op *tp, const char **ap)
914 unsigned char buf[68];
916 union mksh_ccphack args, cap;
918 sh = str_val(global("EXECSHELL"));
920 sh = search_path(sh, path, X_OK, NULL);
922 sh = MKSH_DEFAULT_EXECSHELL;
924 *tp->args-- = tp->str;
927 if ((fd = binopen2(tp->str, O_RDONLY)) >= 0) {
932 /* read first couple of octets from file */
933 n = read(fd, buf, sizeof(buf) - 1);
935 /* read error or short read? */
938 /* terminate buffer */
941 /* skip UTF-8 Byte Order Mark, if present */
942 cp = buf + (n = ((buf[0] == 0xEF) && (buf[1] == 0xBB) &&
943 (buf[2] == 0xBF)) ? 3 : 0);
945 /* scan for newline or NUL (end of buffer) */
946 while (*cp && *cp != '\n')
948 /* if the shebang line is longer than MAXINTERP, bail out */
951 /* replace newline by NUL */
954 /* restore begin of shebang position (buf+0 or buf+3) */
956 /* bail out if no shebang magic found */
957 if (cp[0] == '#' && cp[1] == '!')
960 else if (!strncmp(cp, Textproc, 7) &&
961 (cp[7] == ' ' || cp[7] == '\t'))
966 /* skip whitespace before shell name */
967 while (*cp == ' ' || *cp == '\t')
969 /* just whitespace on the line? */
972 /* no, we actually found an interpreter name */
974 /* look for end of shell/interpreter name */
975 while (*cp != ' ' && *cp != '\t' && *cp != '\0')
980 /* skip spaces before arguments */
981 while (*cp == ' ' || *cp == '\t')
983 /* pass it all in ONE argument (historic reasons) */
985 *tp->args-- = (char *)cp;
989 m = buf[0] << 8 | buf[1];
990 if (m == 0x7F45 && buf[2] == 'L' && buf[3] == 'F')
991 errorf("%s: not executable: %d-bit ELF file", tp->str,
993 if ((m == /* OMAGIC */ 0407) ||
994 (m == /* NMAGIC */ 0410) ||
995 (m == /* ZMAGIC */ 0413) ||
996 (m == /* QMAGIC */ 0314) ||
997 (m == /* ECOFF_I386 */ 0x4C01) ||
998 (m == /* ECOFF_M68K */ 0x0150 || m == 0x5001) ||
999 (m == /* ECOFF_SH */ 0x0500 || m == 0x0005) ||
1000 (m == /* bzip */ 0x425A) || (m == /* "MZ" */ 0x4D5A) ||
1001 (m == /* "NE" */ 0x4E45) || (m == /* "LX" */ 0x4C58) ||
1002 (m == /* ksh93 */ 0x0B13) || (m == /* LZIP */ 0x4C5A) ||
1003 (m == /* xz */ 0xFD37 && buf[2] == 'z' && buf[3] == 'X' &&
1004 buf[4] == 'Z') || (m == /* 7zip */ 0x377A) ||
1005 (m == /* gzip */ 0x1F8B) || (m == /* .Z */ 0x1F9D))
1006 errorf("%s: not executable: magic %04X", tp->str, m);
1015 execve(args.rw[0], args.rw, cap.rw);
1017 /* report both the programme that was run and the bogus interpreter */
1018 errorf("%s: %s: %s", tp->str, sh, cstrerror(errno));
1022 shcomexec(const char **wp)
1026 tp = ktsearch(&builtins, *wp, hash(*wp));
1027 return (call_builtin(tp, wp, "shcomexec", false));
1031 * Search function tables for a function. If create set, a table entry
1032 * is created if none is found.
1035 findfunc(const char *name, uint32_t h, bool create)
1038 struct tbl *tp = NULL;
1040 for (l = e->loc; l; l = l->next) {
1041 tp = ktsearch(&l->funs, name, h);
1044 if (!l->next && create) {
1045 tp = ktenter(&l->funs, name, h);
1056 * define function. Returns 1 if function is being undefined (t == 0) and
1057 * function did not exist, returns 0 otherwise.
1060 define(const char *name, struct op *t)
1064 bool was_set = false;
1068 while (/* CONSTCOND */ 1) {
1069 tp = findfunc(name, nhash, true);
1071 if (tp->flag & ISSET)
1074 * If this function is currently being executed, we zap
1075 * this table entry so findfunc() won't see it
1077 if (tp->flag & FINUSE) {
1079 /* ensure it won't be found */
1080 tp->flag &= ~DEFINED;
1081 tp->flag |= FDELETE;
1086 if (tp->flag & ALLOC) {
1087 tp->flag &= ~(ISSET|ALLOC);
1088 tfree(tp->val.t, tp->areap);
1094 return (was_set ? 0 : 1);
1097 tp->val.t = tcopy(t->left, tp->areap);
1098 tp->flag |= (ISSET|ALLOC);
1109 builtin(const char *name, int (*func) (const char **))
1112 uint32_t flag = DEFINED;
1114 /* see if any flags should be set for this builtin */
1117 /* command does variable assignment */
1119 else if (*name == '*')
1120 /* POSIX special builtin */
1127 tp = ktenter(&builtins, name, hash(name));
1137 * either function, hashed command, or built-in (in that order)
1140 findcom(const char *name, int flags)
1142 static struct tbl temp;
1143 uint32_t h = hash(name);
1144 struct tbl *tp = NULL, *tbi;
1145 /* insert if not found */
1146 unsigned char insert = Flag(FTRACKALL);
1147 /* for function autoloading */
1149 union mksh_cchack npath;
1151 if (vstrchr(name, '/')) {
1153 /* prevent FPATH search below */
1157 tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h) : NULL;
1159 * POSIX says special builtins first, then functions, then
1160 * regular builtins, then search path...
1162 if ((flags & FC_SPECBI) && tbi && (tbi->flag & SPEC_BI))
1164 if (!tp && (flags & FC_FUNC)) {
1165 tp = findfunc(name, h, false);
1166 if (tp && !(tp->flag & ISSET)) {
1167 if ((fpath = str_val(global("FPATH"))) == null) {
1169 tp->u2.errnov = ENOENT;
1171 tp->u.fpath = search_path(name, fpath, R_OK,
1175 if (!tp && (flags & FC_NORMBI) && tbi)
1177 if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
1178 tp = ktsearch(&taliases, name, h);
1179 if (tp && (tp->flag & ISSET) &&
1180 ksh_access(tp->val.s, X_OK) != 0) {
1181 if (tp->flag & ALLOC) {
1183 afree(tp->val.s, APERM);
1190 if ((!tp || (tp->type == CTALIAS && !(tp->flag&ISSET))) &&
1191 (flags & FC_PATH)) {
1193 if (insert && !(flags & FC_DEFPATH)) {
1194 tp = ktenter(&taliases, name, h);
1203 npath.ro = search_path(name,
1204 (flags & FC_DEFPATH) ? def_path : path,
1205 X_OK, &tp->u2.errnov);
1207 strdupx(tp->val.s, npath.ro, APERM);
1208 if (npath.ro != name)
1209 afree(npath.rw, ATEMP);
1210 tp->flag |= ISSET|ALLOC;
1211 } else if ((flags & FC_FUNC) &&
1212 (fpath = str_val(global("FPATH"))) != null &&
1213 (npath.ro = search_path(name, fpath, R_OK,
1214 &tp->u2.errnov)) != NULL) {
1216 * An undocumented feature of AT&T ksh is that
1217 * it searches FPATH if a command is not found,
1218 * even if the command hasn't been set up as an
1219 * autoloaded function (ie, no typeset -uf).
1225 tp->u.fpath = npath.ro;
1232 * flush executable commands with relative paths
1233 * (just relative or all?)
1241 for (ktwalk(&ts, &taliases); (tp = ktnext(&ts)) != NULL; )
1242 if ((tp->flag&ISSET) && (all || !mksh_abspath(tp->val.s))) {
1243 if (tp->flag&ALLOC) {
1244 tp->flag &= ~(ALLOC|ISSET);
1245 afree(tp->val.s, APERM);
1251 /* check if path is something we want to find */
1253 search_access(const char *fn, int mode)
1257 if (stat(fn, &sb) < 0)
1258 /* file does not exist */
1260 /* LINTED use of access */
1261 if (access(fn, mode) < 0) {
1262 /* file exists, but we can't access it */
1266 return (eno ? eno : EACCES);
1268 if (mode == X_OK && (!S_ISREG(sb.st_mode) ||
1269 !(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))))
1270 /* access(2) may say root can execute everything */
1271 return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES);
1276 * search for command with PATH
1279 search_path(const char *name, const char *lpath,
1282 /* set if candidate found, but not suitable */
1291 if (vstrchr(name, '/')) {
1292 if ((ec = search_access(name, mode)) == 0) {
1298 goto search_path_err;
1301 namelen = strlen(name) + 1;
1302 Xinit(xs, xp, 128, ATEMP);
1305 while (sp != NULL) {
1306 xp = Xstring(xs, xp);
1307 if (!(p = cstrchr(sp, MKSH_PATHSEPC)))
1308 p = sp + strlen(sp);
1310 XcheckN(xs, xp, p - sp);
1311 memcpy(xp, sp, p - sp);
1316 XcheckN(xs, xp, namelen);
1317 memcpy(xp, name, namelen);
1318 if ((ev = search_access(Xstring(xs, xp), mode)) == 0) {
1319 name = Xclose(xs, xp + namelen);
1320 goto search_path_ok;
1322 /* accumulate non-ENOENT errors only */
1323 if (ev != ENOENT && ec == 0)
1331 *errnop = ec ? ec : ENOENT;
1336 call_builtin(struct tbl *tp, const char **wp, const char *where, bool resetspec)
1341 internal_errorf("%s: %s", where, wp[0]);
1342 builtin_argv0 = wp[0];
1343 builtin_spec = tobool(!resetspec &&
1344 /*XXX odd use of KEEPASN */
1345 ((tp->flag & SPEC_BI) || (Flag(FPOSIX) && (tp->flag & KEEPASN))));
1346 shf_reopen(1, SHF_WR, shl_stdout);
1347 shl_stdout_ok = true;
1348 ksh_getopt_reset(&builtin_opt, GF_ERROR);
1349 rv = (*tp->val.f)(wp);
1350 shf_flush(shl_stdout);
1351 shl_stdout_ok = false;
1352 builtin_argv0 = NULL;
1353 builtin_spec = false;
1358 * set up redirection, saving old fds in e->savefd
1361 iosetup(struct ioword *iop, struct tbl *tp)
1364 char *cp = iop->ioname;
1365 int iotype = iop->ioflag & IOTYPE;
1366 bool do_open = true, do_close = false, do_fstat = false;
1368 struct ioword iotmp;
1371 if (iotype != IOHERE)
1372 cp = evalonestr(cp, DOTILDE|(Flag(FTALKING_I) ? DOGLOB : 0));
1374 /* Used for tracing and error messages to print expanded cp */
1376 iotmp.ioname = (iotype == IOHERE) ? NULL : cp;
1377 iotmp.ioflag |= IONAMEXP;
1379 if (Flag(FXTRACE)) {
1380 change_xtrace(2, false);
1381 fptreef(shl_xtrace, 0, "%R", &iotmp);
1382 change_xtrace(1, false);
1391 flags = O_WRONLY | O_APPEND | O_CREAT;
1395 if (Flag(FNOCLOBBER) && !(iop->ioflag & IOCLOB)) {
1396 /* >file under set -C */
1397 if (stat(cp, &statb)) {
1398 /* nonexistent file */
1399 flags = O_WRONLY | O_CREAT | O_EXCL;
1400 } else if (S_ISREG(statb.st_mode)) {
1401 /* regular file, refuse clobbering */
1402 goto clobber_refused;
1405 * allow redirections to things
1406 * like /dev/null without error
1409 /* but check again after opening */
1413 /* >|file or set +C */
1414 flags = O_WRONLY | O_CREAT | O_TRUNC;
1419 flags = O_RDWR | O_CREAT;
1424 /* herein() returns -2 if error has been printed */
1425 u = herein(iop, NULL);
1426 /* cp may have wrong name */
1433 if (ksh_isdash(cp)) {
1434 /* prevent error return below */
1437 } else if ((u = check_fd(cp,
1438 X_OK | ((iop->ioflag & IORDUP) ? R_OK : W_OK),
1442 warningf(true, "%s: %s",
1443 (sp = snptreef(NULL, 32, "%R", &iotmp)), emsg);
1447 if (u == (int)iop->unit)
1448 /* "dup from" == "dup to" */
1455 if (Flag(FRESTRICTED) && (flags & O_CREAT)) {
1456 warningf(true, "%s: %s", cp, "restricted");
1459 u = binopen3(cp, flags, 0666);
1460 if (do_fstat && u >= 0) {
1461 /* prevent race conditions */
1462 if (fstat(u, &statb) || S_ISREG(statb.st_mode)) {
1471 /* herein() may already have printed message */
1474 warningf(true, "can't %s %s: %s",
1475 iotype == IODUP ? "dup" :
1476 (iotype == IOREAD || iotype == IOHERE) ?
1477 "open" : "create", cp, cstrerror(u));
1481 /* Do not save if it has already been redirected (i.e. "cat >x >y"). */
1482 if (e->savefd[iop->unit] == 0) {
1483 /* If these are the same, it means unit was previously closed */
1484 if (u == (int)iop->unit)
1485 e->savefd[iop->unit] = -1;
1488 * c_exec() assumes e->savefd[fd] set for any
1489 * redirections. Ask savefd() not to close iop->unit;
1490 * this allows error messages to be seen if iop->unit
1491 * is 2; also means we can't lose the fd (eg, both
1492 * dup2 below and dup2 in restfd() failing).
1494 e->savefd[iop->unit] = savefd(iop->unit);
1499 else if (u != (int)iop->unit) {
1500 if (ksh_dup2(u, iop->unit, true) < 0) {
1505 warningf(true, "%s %s: %s",
1506 "can't finish (dup) redirection",
1507 (sp = snptreef(NULL, 32, "%R", &iotmp)),
1510 if (iotype != IODUP)
1514 if (iotype != IODUP)
1517 * Touching any co-process fd in an empty exec
1518 * causes the shell to close its copies
1520 else if (tp && tp->type == CSHELL && tp->val.f == c_exec) {
1521 if (iop->ioflag & IORDUP)
1522 /* possible exec <&p */
1523 coproc_read_close(u);
1525 /* possible exec >&p */
1526 coproc_write_close(u);
1530 /* Clear any write errors */
1531 shf_reopen(2, SHF_WR, shl_out);
1536 * Process here documents by providing the content, either as
1537 * result (globally allocated) string or in a temp file; if
1538 * unquoted, the string is expanded first.
1541 hereinval(struct ioword *iop, int sub, char **resbuf, struct shf *shf)
1543 const char * volatile ccp = iop->heredoc;
1544 struct source *s, *osource;
1548 if (kshsetjmp(e->jbuf)) {
1551 /* special to iosetup(): don't print error */
1554 if (iop->ioflag & IOHERESTR) {
1555 ccp = evalstr(iop->delim, DOHERESTR | DOSCALAR | DOHEREDOC);
1557 /* do substitutions on the content of heredoc */
1558 s = pushs(SSTRING, ATEMP);
1559 s->start = s->str = ccp;
1561 if (yylex(sub) != LWORD)
1562 internal_errorf("%s: %s", "herein", "yylex");
1564 ccp = evalstr(yylval.cp, DOSCALAR | DOHEREDOC);
1570 strdupx(*resbuf, ccp, APERM);
1577 herein(struct ioword *iop, char **resbuf)
1584 /* ksh -c 'cat <<EOF' can cause this... */
1585 if (iop->heredoc == NULL && !(iop->ioflag & IOHERESTR)) {
1586 warningf(true, "%s missing", "here document");
1587 /* special to iosetup(): don't print error */
1591 /* lexer substitution flags */
1592 i = (iop->ioflag & IOEVAL) ? (ONEWORD | HEREDOC) : 0;
1594 /* skip all the fd setup if we just want the value */
1596 return (hereinval(iop, i, resbuf, NULL));
1599 * Create temp file to hold content (done before newenv
1600 * so temp doesn't get removed too soon).
1602 h = maketemp(ATEMP, TT_HEREDOC_EXP, &e->temps);
1603 if (!(shf = h->shf) || (fd = binopen3(h->tffn, O_RDONLY, 0)) < 0) {
1605 warningf(true, "can't %s temporary file %s: %s",
1606 !shf ? "create" : "open", h->tffn, cstrerror(i));
1609 /* special to iosetup(): don't print error */
1613 if (hereinval(iop, i, NULL, shf) == -2) {
1615 /* special to iosetup(): don't print error */
1619 if (shf_close(shf) == -1) {
1622 warningf(true, "can't %s temporary file %s: %s",
1623 "write", h->tffn, cstrerror(i));
1624 /* special to iosetup(): don't print error */
1632 * ksh special - the select command processing section
1633 * print the args in column form - assuming that we can
1636 do_selectargs(const char **ap, bool print_menu)
1638 static const char *read_args[] = {
1639 "read", "-r", "REPLY", NULL
1644 for (argct = 0; ap[argct]; argct++)
1646 while (/* CONSTCOND */ 1) {
1648 * Menu is printed if
1649 * - this is the first time around the select loop
1650 * - the user enters a blank line
1651 * - the REPLY parameter is empty
1653 if (print_menu || !*str_val(global("REPLY")))
1655 shellf("%s", str_val(global("PS3")));
1656 if (call_builtin(findcom("read", FC_BI), read_args, Tselect,
1659 if (*(s = str_val(global("REPLY"))))
1660 return ((getn(s, &i) && i >= 1 && i <= argct) ?
1666 struct select_menu_info {
1667 const char * const *args;
1671 /* format a single select menu item */
1673 select_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
1675 const struct select_menu_info *smi =
1676 (const struct select_menu_info *)arg;
1678 shf_snprintf(buf, buflen, "%*u) %s",
1679 smi->num_width, i + 1, smi->args[i]);
1683 * print a select style menu
1686 pr_menu(const char * const *ap)
1688 struct select_menu_info smi;
1689 const char * const *pp;
1690 size_t acols = 0, aocts = 0, i;
1694 * width/column calculations were done once and saved, but this
1695 * means select can't be used recursively so we re-calculate
1696 * each time (could save in a structure that is returned, but
1697 * it's probably not worth the bother)
1701 * get dimensions of the list
1703 for (n = 0, pp = ap; *pp; n++, pp++) {
1707 i = utf_mbswidth(*pp);
1713 * we will print an index of the form "%d) " in front of
1714 * each entry, so get the maximum width of this
1716 for (i = n, smi.num_width = 1; i >= 10; i /= 10)
1720 print_columns(shl_out, n, select_fmt_entry, (void *)&smi,
1721 smi.num_width + 2 + aocts, smi.num_width + 2 + acols,
1726 plain_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
1728 strlcpy(buf, ((const char * const *)arg)[i], buflen);
1732 pr_list(char * const *ap)
1734 size_t acols = 0, aocts = 0, i;
1738 for (n = 0, pp = ap; *pp; n++, pp++) {
1742 i = utf_mbswidth(*pp);
1747 print_columns(shl_out, n, plain_fmt_entry, (const void *)ap,
1748 aocts, acols, false);
1752 * [[ ... ]] evaluation routines
1756 * Test if the current token is a whatever. Accepts the current token if
1757 * it is. Returns 0 if it is not, non-zero if it is (in the case of
1758 * TM_UNOP and TM_BINOP, the returned value is a Test_op).
1761 dbteste_isa(Test_env *te, Test_meta meta)
1763 Test_op ret = TO_NONOP;
1768 return (meta == TM_END ? TO_NONNULL : TO_NONOP);
1770 /* unquoted word? */
1771 for (p = *te->pos.wp; *p == CHAR; p += 2)
1775 if (meta == TM_UNOP || meta == TM_BINOP) {
1777 /* longer than the longest operator */
1782 while (*p++ == CHAR &&
1783 (size_t)(q - buf) < sizeof(buf) - 1)
1786 ret = test_isop(meta, buf);
1788 } else if (meta == TM_END)
1791 ret = (uqword && !strcmp(*te->pos.wp,
1792 dbtest_tokens[(int)meta])) ? TO_NONNULL : TO_NONOP;
1794 /* Accept the token? */
1795 if (ret != TO_NONOP)
1802 dbteste_getopnd(Test_env *te, Test_op op, bool do_eval)
1804 const char *s = *te->pos.wp;
1805 int flags = DOTILDE | DOSCALAR;
1815 if (op == TO_STEQL || op == TO_STNEQ)
1818 return (evalstr(s, flags));
1822 dbteste_error(Test_env *te, int offset, const char *msg)
1824 te->flags |= TEF_ERROR;
1825 internal_warningf("dbteste_error: %s (offset %d)", msg, offset);