don't bother resolving onbld python module deps
[unleashed.git] / bin / ksh / exec.c
blob1d274919fcb3ebd59128ab9b1ec646727304f717
1 /* $OpenBSD: exec.c,v 1.73 2018/03/15 16:51:29 anton Exp $ */
3 /*
4 * execute command tree
5 */
7 #include <sys/stat.h>
9 #include <ctype.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <paths.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
18 #include "sh.h"
19 #include "c_test.h"
21 /* Does ps4 get parameter substitutions done? */
22 # define PS4_SUBSTITUTE(s) substitute((s), 0)
24 static int comexec(struct op *, struct tbl *volatile, char **,
25 int volatile, volatile int *);
26 static void scriptexec(struct op *, char **);
27 static int call_builtin(struct tbl *, char **);
28 static int iosetup(struct ioword *, struct tbl *);
29 static int herein(const char *, int);
30 static char *do_selectargs(char **, bool);
31 static int dbteste_isa(Test_env *, Test_meta);
32 static const char *dbteste_getopnd(Test_env *, Test_op, int);
33 static int dbteste_eval(Test_env *, Test_op, const char *, const char *,
34 int);
35 static void dbteste_error(Test_env *, int, const char *);
39 * execute command tree
41 int
42 execute(struct op *volatile t,
43 volatile int flags, /* if XEXEC don't fork */
44 volatile int *xerrok) /* inform recursive callers in -e mode that
45 * short-circuit && or || shouldn't be treated
46 * as an error */
48 int i, dummy = 0, save_xerrok = 0;
49 volatile int rv = 0;
50 int pv[2];
51 char ** volatile ap;
52 char *s, *cp;
53 struct ioword **iowp;
54 struct tbl *tp = NULL;
56 if (t == NULL)
57 return 0;
59 /* Caller doesn't care if XERROK should propagate. */
60 if (xerrok == NULL)
61 xerrok = &dummy;
63 /* Is this the end of a pipeline? If so, we want to evaluate the
64 * command arguments
65 bool eval_done = false;
66 if ((flags&XFORK) && !(flags&XEXEC) && (flags&XPCLOSE)) {
67 eval_done = true;
68 tp = eval_execute_args(t, &ap);
71 if ((flags&XFORK) && !(flags&XEXEC) && t->type != TPIPE)
72 return exchild(t, flags & ~XTIME, xerrok, -1); /* run in sub-process */
74 newenv(E_EXEC);
75 if (trap)
76 runtraps(0);
78 if (t->type == TCOM) {
79 /* Clear subst_exstat before argument expansion. Used by
80 * null commands (see comexec() and c_eval()) and by c_set().
82 subst_exstat = 0;
84 current_lineno = t->lineno; /* for $LINENO */
86 /* POSIX says expand command words first, then redirections,
87 * and assignments last..
89 ap = eval(t->args, t->u.evalflags | DOBLANK | DOGLOB | DOTILDE);
90 if (flags & XTIME)
91 /* Allow option parsing (bizarre, but POSIX) */
92 timex_hook(t, &ap);
93 if (Flag(FXTRACE) && ap[0]) {
94 shf_fprintf(shl_out, "%s",
95 PS4_SUBSTITUTE(str_val(global("PS4"))));
96 for (i = 0; ap[i]; i++)
97 shf_fprintf(shl_out, "%s%s", ap[i],
98 ap[i + 1] ? " " : "\n");
99 shf_flush(shl_out);
101 if (ap[0])
102 tp = findcom(ap[0], FC_BI|FC_FUNC);
104 flags &= ~XTIME;
106 if (t->ioact != NULL || t->type == TPIPE || t->type == TCOPROC) {
107 genv->savefd = areallocarray(NULL, NUFILE, sizeof(short), ATEMP);
108 /* initialize to not redirected */
109 memset(genv->savefd, 0, NUFILE * sizeof(short));
112 /* do redirection, to be restored in quitenv() */
113 if (t->ioact != NULL)
114 for (iowp = t->ioact; *iowp != NULL; iowp++) {
115 if (iosetup(*iowp, tp) < 0) {
116 exstat = rv = 1;
117 /* Redirection failures for special commands
118 * cause (non-interactive) shell to exit.
120 if (tp && tp->type == CSHELL &&
121 (tp->flag & SPEC_BI))
122 errorf(NULL);
123 /* Deal with FERREXIT, quitenv(), etc. */
124 goto Break;
128 switch (t->type) {
129 case TCOM:
130 rv = comexec(t, tp, ap, flags, xerrok);
131 break;
133 case TPAREN:
134 rv = execute(t->left, flags|XFORK, xerrok);
135 break;
137 case TPIPE:
138 flags |= XFORK;
139 flags &= ~XEXEC;
140 genv->savefd[0] = savefd(0);
141 genv->savefd[1] = savefd(1);
142 while (t->type == TPIPE) {
143 openpipe(pv);
144 (void) ksh_dup2(pv[1], 1, false); /* stdout of curr */
145 /* Let exchild() close pv[0] in child
146 * (if this isn't done, commands like
147 * (: ; cat /etc/termcap) | sleep 1
148 * will hang forever).
150 exchild(t->left, flags|XPIPEO|XCCLOSE, NULL, pv[0]);
151 (void) ksh_dup2(pv[0], 0, false); /* stdin of next */
152 closepipe(pv);
153 flags |= XPIPEI;
154 t = t->right;
156 restfd(1, genv->savefd[1]); /* stdout of last */
157 genv->savefd[1] = 0; /* no need to re-restore this */
158 /* Let exchild() close 0 in parent, after fork, before wait */
159 i = exchild(t, flags|XPCLOSE, xerrok, 0);
160 if (!(flags&XBGND) && !(flags&XXCOM))
161 rv = i;
162 break;
164 case TLIST:
165 while (t->type == TLIST) {
166 execute(t->left, flags & XERROK, NULL);
167 t = t->right;
169 rv = execute(t, flags & XERROK, xerrok);
170 break;
172 case TCOPROC:
174 sigset_t omask;
176 /* Block sigchild as we are using things changed in the
177 * signal handler
179 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
180 genv->type = E_ERRH;
181 i = sigsetjmp(genv->jbuf, 0);
182 if (i) {
183 sigprocmask(SIG_SETMASK, &omask, NULL);
184 quitenv(NULL);
185 unwind(i);
186 /* NOTREACHED */
188 /* Already have a (live) co-process? */
189 if (coproc.job && coproc.write >= 0)
190 errorf("coprocess already exists");
192 /* Can we re-use the existing co-process pipe? */
193 coproc_cleanup(true);
195 /* do this before opening pipes, in case these fail */
196 genv->savefd[0] = savefd(0);
197 genv->savefd[1] = savefd(1);
199 openpipe(pv);
200 if (pv[0] != 0) {
201 ksh_dup2(pv[0], 0, false);
202 close(pv[0]);
204 coproc.write = pv[1];
205 coproc.job = NULL;
207 if (coproc.readw >= 0)
208 ksh_dup2(coproc.readw, 1, false);
209 else {
210 openpipe(pv);
211 coproc.read = pv[0];
212 ksh_dup2(pv[1], 1, false);
213 coproc.readw = pv[1]; /* closed before first read */
214 coproc.njobs = 0;
215 /* create new coprocess id */
216 ++coproc.id;
218 sigprocmask(SIG_SETMASK, &omask, NULL);
219 genv->type = E_EXEC; /* no more need for error handler */
221 /* exchild() closes coproc.* in child after fork,
222 * will also increment coproc.njobs when the
223 * job is actually created.
225 flags &= ~XEXEC;
226 exchild(t->left, flags|XBGND|XFORK|XCOPROC|XCCLOSE,
227 NULL, coproc.readw);
228 break;
231 case TASYNC:
232 /* XXX non-optimal, I think - "(foo &)", forks for (),
233 * forks again for async... parent should optimize
234 * this to "foo &"...
236 rv = execute(t->left, (flags&~XEXEC)|XBGND|XFORK, xerrok);
237 break;
239 case TOR:
240 case TAND:
241 rv = execute(t->left, XERROK, xerrok);
242 if ((rv == 0) == (t->type == TAND))
243 rv = execute(t->right, flags & XERROK, xerrok);
244 else {
245 flags |= XERROK;
246 *xerrok = 1;
248 break;
250 case TBANG:
251 rv = !execute(t->right, XERROK, xerrok);
252 flags |= XERROK;
253 *xerrok = 1;
254 break;
256 case TDBRACKET:
258 Test_env te;
260 te.flags = TEF_DBRACKET;
261 te.pos.wp = t->args;
262 te.isa = dbteste_isa;
263 te.getopnd = dbteste_getopnd;
264 te.eval = dbteste_eval;
265 te.error = dbteste_error;
267 rv = test_parse(&te);
268 break;
271 case TFOR:
272 case TSELECT:
274 volatile bool is_first = true;
275 ap = (t->vars != NULL) ? eval(t->vars, DOBLANK|DOGLOB|DOTILDE) :
276 genv->loc->argv + 1;
277 genv->type = E_LOOP;
278 while (1) {
279 i = sigsetjmp(genv->jbuf, 0);
280 if (!i)
281 break;
282 if ((genv->flags&EF_BRKCONT_PASS) ||
283 (i != LBREAK && i != LCONTIN)) {
284 quitenv(NULL);
285 unwind(i);
286 } else if (i == LBREAK) {
287 rv = 0;
288 goto Break;
291 rv = 0; /* in case of a continue */
292 if (t->type == TFOR) {
293 save_xerrok = *xerrok;
294 while (*ap != NULL) {
295 setstr(global(t->str), *ap++, KSH_UNWIND_ERROR);
296 /* undo xerrok in all iterations except the
297 * last */
298 *xerrok = save_xerrok;
299 rv = execute(t->left, flags & XERROK, xerrok);
301 /* ripple xerrok set at final iteration */
302 } else { /* TSELECT */
303 for (;;) {
304 if (!(cp = do_selectargs(ap, is_first))) {
305 rv = 1;
306 break;
308 is_first = false;
309 setstr(global(t->str), cp, KSH_UNWIND_ERROR);
310 rv = execute(t->left, flags & XERROK, xerrok);
314 break;
316 case TWHILE:
317 case TUNTIL:
318 genv->type = E_LOOP;
319 while (1) {
320 i = sigsetjmp(genv->jbuf, 0);
321 if (!i)
322 break;
323 if ((genv->flags&EF_BRKCONT_PASS) ||
324 (i != LBREAK && i != LCONTIN)) {
325 quitenv(NULL);
326 unwind(i);
327 } else if (i == LBREAK) {
328 rv = 0;
329 goto Break;
332 rv = 0; /* in case of a continue */
333 while ((execute(t->left, XERROK, NULL) == 0) == (t->type == TWHILE))
334 rv = execute(t->right, flags & XERROK, xerrok);
335 break;
337 case TIF:
338 case TELIF:
339 if (t->right == NULL)
340 break; /* should be error */
341 rv = execute(t->left, XERROK, NULL) == 0 ?
342 execute(t->right->left, flags & XERROK, xerrok) :
343 execute(t->right->right, flags & XERROK, xerrok);
344 break;
346 case TCASE:
347 cp = evalstr(t->str, DOTILDE);
348 for (t = t->left; t != NULL && t->type == TPAT; t = t->right) {
349 for (ap = t->vars; *ap; ap++) {
350 if ((s = evalstr(*ap, DOTILDE|DOPAT)) &&
351 gmatch(cp, s, false))
352 goto Found;
355 break;
356 Found:
357 rv = execute(t->left, flags & XERROK, xerrok);
358 break;
360 case TBRACE:
361 rv = execute(t->left, flags & XERROK, xerrok);
362 break;
364 case TFUNCT:
365 rv = define(t->str, t);
366 break;
368 case TTIME:
369 /* Clear XEXEC so nested execute() call doesn't exit
370 * (allows "ls -l | time grep foo").
372 rv = timex(t, flags & ~XEXEC, xerrok);
373 break;
375 case TEXEC: /* an eval'd TCOM */
376 s = t->args[0];
377 ap = makenv();
378 restoresigs();
379 cleanup_proc_env();
380 execve(t->str, t->args, ap);
381 if (errno == ENOEXEC)
382 scriptexec(t, ap);
383 else
384 errorf("%s: %s", s, strerror(errno));
386 Break:
387 exstat = rv;
389 quitenv(NULL); /* restores IO */
390 if ((flags&XEXEC))
391 unwind(LEXIT); /* exit child */
392 if (rv != 0 && !(flags & XERROK) && !*xerrok) {
393 trapsig(SIGERR_);
394 if (Flag(FERREXIT))
395 unwind(LERROR);
397 return rv;
401 * execute simple command
404 static int
405 comexec(struct op *t, struct tbl *volatile tp, char **ap, volatile int flags,
406 volatile int *xerrok)
408 int i;
409 volatile int rv = 0;
410 char *cp;
411 char **lastp;
412 struct op texec;
413 int type_flags;
414 int keepasn_ok;
415 int fcflags = FC_BI|FC_FUNC|FC_PATH;
416 int bourne_function_call = 0;
418 /* snag the last argument for $_ XXX not the same as at&t ksh,
419 * which only seems to set $_ after a newline (but not in
420 * functions/dot scripts, but in interactive and script) -
421 * perhaps save last arg here and set it in shell()?.
423 if (!Flag(FSH) && Flag(FTALKING) && *(lastp = ap)) {
424 while (*++lastp)
426 /* setstr() can't fail here */
427 setstr(typeset("_", LOCAL, 0, INTEGER, 0), *--lastp,
428 KSH_RETURN_ERROR);
431 /* Deal with the shell builtins builtin, exec and command since
432 * they can be followed by other commands. This must be done before
433 * we know if we should create a local block, which must be done
434 * before we can do a path search (in case the assignments change
435 * PATH).
436 * Odd cases:
437 * FOO=bar exec > /dev/null FOO is kept but not exported
438 * FOO=bar exec foobar FOO is exported
439 * FOO=bar command exec > /dev/null FOO is neither kept nor exported
440 * FOO=bar command FOO is neither kept nor exported
441 * PATH=... foobar use new PATH in foobar search
443 keepasn_ok = 1;
444 while (tp && tp->type == CSHELL) {
445 fcflags = FC_BI|FC_FUNC|FC_PATH;/* undo effects of command */
446 if (tp->val.f == c_builtin) {
447 if ((cp = *++ap) == NULL) {
448 tp = NULL;
449 break;
451 tp = findcom(cp, FC_BI);
452 if (tp == NULL)
453 errorf("builtin: %s: not a builtin", cp);
454 continue;
455 } else if (tp->val.f == c_exec) {
456 if (ap[1] == NULL)
457 break;
458 ap++;
459 flags |= XEXEC;
460 } else if (tp->val.f == c_command) {
461 int optc, saw_p = 0;
463 /* Ugly dealing with options in two places (here and
464 * in c_command(), but such is life)
466 ksh_getopt_reset(&builtin_opt, 0);
467 while ((optc = ksh_getopt(ap, &builtin_opt, ":p")) == 'p')
468 saw_p = 1;
469 if (optc != EOF)
470 break; /* command -vV or something */
471 /* don't look for functions */
472 fcflags = FC_BI|FC_PATH;
473 if (saw_p) {
474 if (Flag(FRESTRICTED)) {
475 warningf(true,
476 "command -p: restricted");
477 rv = 1;
478 goto Leave;
480 fcflags |= FC_DEFPATH;
482 ap += builtin_opt.optind;
483 /* POSIX says special builtins lose their status
484 * if accessed using command.
486 keepasn_ok = 0;
487 if (!ap[0]) {
488 /* ensure command with no args exits with 0 */
489 subst_exstat = 0;
490 break;
492 } else
493 break;
494 tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC));
496 if (keepasn_ok && (!ap[0] || (tp && (tp->flag & KEEPASN))))
497 type_flags = 0;
498 else {
499 /* create new variable/function block */
500 newblock();
501 /* ksh functions don't keep assignments, POSIX functions do. */
502 if (keepasn_ok && tp && tp->type == CFUNC &&
503 !(tp->flag & FKSH)) {
504 bourne_function_call = 1;
505 type_flags = 0;
506 } else
507 type_flags = LOCAL|LOCAL_COPY|EXPORT;
509 if (Flag(FEXPORT))
510 type_flags |= EXPORT;
511 for (i = 0; t->vars[i]; i++) {
512 cp = evalstr(t->vars[i], DOASNTILDE);
513 if (Flag(FXTRACE)) {
514 if (i == 0)
515 shf_fprintf(shl_out, "%s",
516 PS4_SUBSTITUTE(str_val(global("PS4"))));
517 shf_fprintf(shl_out, "%s%s", cp,
518 t->vars[i + 1] ? " " : "\n");
519 if (!t->vars[i + 1])
520 shf_flush(shl_out);
522 typeset(cp, type_flags, 0, 0, 0);
523 if (bourne_function_call && !(type_flags & EXPORT))
524 typeset(cp, LOCAL|LOCAL_COPY|EXPORT, 0, 0, 0);
527 if ((cp = *ap) == NULL) {
528 rv = subst_exstat;
529 goto Leave;
530 } else if (!tp) {
531 if (Flag(FRESTRICTED) && strchr(cp, '/')) {
532 warningf(true, "%s: restricted", cp);
533 rv = 1;
534 goto Leave;
536 tp = findcom(cp, fcflags);
539 switch (tp->type) {
540 case CSHELL: /* shell built-in */
541 rv = call_builtin(tp, ap);
542 break;
544 case CFUNC: /* function call */
546 volatile int old_xflag, old_inuse;
547 const char *volatile old_kshname;
549 if (!(tp->flag & ISSET)) {
550 struct tbl *ftp;
552 if (!tp->u.fpath) {
553 if (tp->u2.errno_) {
554 warningf(true,
555 "%s: can't find function "
556 "definition file - %s",
557 cp, strerror(tp->u2.errno_));
558 rv = 126;
559 } else {
560 warningf(true,
561 "%s: can't find function "
562 "definition file", cp);
563 rv = 127;
565 break;
567 if (include(tp->u.fpath, 0, NULL, 0) < 0) {
568 warningf(true,
569 "%s: can't open function definition file %s - %s",
570 cp, tp->u.fpath, strerror(errno));
571 rv = 127;
572 break;
574 if (!(ftp = findfunc(cp, hash(cp), false)) ||
575 !(ftp->flag & ISSET)) {
576 warningf(true,
577 "%s: function not defined by %s",
578 cp, tp->u.fpath);
579 rv = 127;
580 break;
582 tp = ftp;
585 /* ksh functions set $0 to function name, POSIX functions leave
586 * $0 unchanged.
588 old_kshname = kshname;
589 if (tp->flag & FKSH)
590 kshname = ap[0];
591 else
592 ap[0] = (char *) kshname;
593 genv->loc->argv = ap;
594 for (i = 0; *ap++ != NULL; i++)
596 genv->loc->argc = i - 1;
597 /* ksh-style functions handle getopts sanely,
598 * bourne/posix functions are insane...
600 if (tp->flag & FKSH) {
601 genv->loc->flags |= BF_DOGETOPTS;
602 genv->loc->getopts_state = user_opt;
603 getopts_reset(1);
606 old_xflag = Flag(FXTRACE);
607 Flag(FXTRACE) = tp->flag & TRACE ? true : false;
609 old_inuse = tp->flag & FINUSE;
610 tp->flag |= FINUSE;
612 genv->type = E_FUNC;
613 i = sigsetjmp(genv->jbuf, 0);
614 if (i == 0) {
615 /* seems odd to pass XERROK here, but at&t ksh does */
616 exstat = execute(tp->val.t, flags & XERROK, xerrok);
617 i = LRETURN;
619 kshname = old_kshname;
620 Flag(FXTRACE) = old_xflag;
621 tp->flag = (tp->flag & ~FINUSE) | old_inuse;
622 /* Were we deleted while executing? If so, free the execution
623 * tree. todo: Unfortunately, the table entry is never re-used
624 * until the lookup table is expanded.
626 if ((tp->flag & (FDELETE|FINUSE)) == FDELETE) {
627 if (tp->flag & ALLOC) {
628 tp->flag &= ~ALLOC;
629 tfree(tp->val.t, tp->areap);
631 tp->flag = 0;
633 switch (i) {
634 case LRETURN:
635 case LERROR:
636 rv = exstat;
637 break;
638 case LINTR:
639 case LEXIT:
640 case LLEAVE:
641 case LSHELL:
642 quitenv(NULL);
643 unwind(i);
644 /* NOTREACHED */
645 default:
646 quitenv(NULL);
647 internal_errorf("CFUNC %d", i);
649 break;
652 case CEXEC: /* executable command */
653 case CTALIAS: /* tracked alias */
654 if (!(tp->flag&ISSET)) {
655 /* errno_ will be set if the named command was found
656 * but could not be executed (permissions, no execute
657 * bit, directory, etc). Print out a (hopefully)
658 * useful error message and set the exit status to 126.
660 if (tp->u2.errno_) {
661 warningf(true, "%s: cannot execute - %s", cp,
662 strerror(tp->u2.errno_));
663 rv = 126; /* POSIX */
664 } else {
665 warningf(true, "%s: not found", cp);
666 rv = 127;
668 break;
671 if (!Flag(FSH)) {
672 /* set $_ to program's full path */
673 /* setstr() can't fail here */
674 setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0),
675 tp->val.s, KSH_RETURN_ERROR);
678 if (flags&XEXEC) {
679 j_exit();
680 if (!(flags&XBGND) || Flag(FMONITOR)) {
681 setexecsig(&sigtraps[SIGINT], SS_RESTORE_ORIG);
682 setexecsig(&sigtraps[SIGQUIT], SS_RESTORE_ORIG);
686 /* to fork we set up a TEXEC node and call execute */
687 memset(&texec, 0, sizeof(texec));
688 texec.type = TEXEC;
689 texec.left = t; /* for tprint */
690 texec.str = tp->val.s;
691 texec.args = ap;
692 rv = exchild(&texec, flags, xerrok, -1);
693 break;
695 Leave:
696 if (flags & XEXEC) {
697 exstat = rv;
698 unwind(LLEAVE);
700 return rv;
703 static void
704 scriptexec(struct op *tp, char **ap)
706 char *shell;
708 shell = str_val(global("EXECSHELL"));
709 if (shell && *shell)
710 shell = search(shell, search_path, X_OK, NULL);
711 if (!shell || !*shell)
712 shell = _PATH_BSHELL;
714 *tp->args-- = tp->str;
715 *tp->args = shell;
717 execve(tp->args[0], tp->args, ap);
719 /* report both the program that was run and the bogus shell */
720 errorf("%s: %s: %s", tp->str, shell, strerror(errno));
724 shcomexec(char **wp)
726 struct tbl *tp;
728 tp = ktsearch(&builtins, *wp, hash(*wp));
729 if (tp == NULL)
730 internal_errorf("%s: %s", __func__, *wp);
731 return call_builtin(tp, wp);
735 * Search function tables for a function. If create set, a table entry
736 * is created if none is found.
738 struct tbl *
739 findfunc(const char *name, unsigned int h, int create)
741 struct block *l;
742 struct tbl *tp = NULL;
744 for (l = genv->loc; l; l = l->next) {
745 tp = ktsearch(&l->funs, name, h);
746 if (tp)
747 break;
748 if (!l->next && create) {
749 tp = ktenter(&l->funs, name, h);
750 tp->flag = DEFINED;
751 tp->type = CFUNC;
752 tp->val.t = NULL;
753 break;
756 return tp;
760 * define function. Returns 1 if function is being undefined (t == 0) and
761 * function did not exist, returns 0 otherwise.
764 define(const char *name, struct op *t)
766 struct tbl *tp;
767 int was_set = 0;
769 while (1) {
770 tp = findfunc(name, hash(name), true);
772 if (tp->flag & ISSET)
773 was_set = 1;
774 /* If this function is currently being executed, we zap this
775 * table entry so findfunc() won't see it
777 if (tp->flag & FINUSE) {
778 tp->name[0] = '\0';
779 tp->flag &= ~DEFINED; /* ensure it won't be found */
780 tp->flag |= FDELETE;
781 } else
782 break;
785 if (tp->flag & ALLOC) {
786 tp->flag &= ~(ISSET|ALLOC);
787 tfree(tp->val.t, tp->areap);
790 if (t == NULL) { /* undefine */
791 ktdelete(tp);
792 return was_set ? 0 : 1;
795 tp->val.t = tcopy(t->left, tp->areap);
796 tp->flag |= (ISSET|ALLOC);
797 if (t->u.ksh_func)
798 tp->flag |= FKSH;
800 return 0;
804 * add builtin
806 void
807 builtin(const char *name, int (*func) (char **))
809 struct tbl *tp;
810 int flag;
812 /* see if any flags should be set for this builtin */
813 for (flag = 0; ; name++) {
814 if (*name == '=') /* command does variable assignment */
815 flag |= KEEPASN;
816 else if (*name == '*') /* POSIX special builtin */
817 flag |= SPEC_BI;
818 else if (*name == '+') /* POSIX regular builtin */
819 flag |= REG_BI;
820 else
821 break;
824 tp = ktenter(&builtins, name, hash(name));
825 tp->flag = DEFINED | flag;
826 tp->type = CSHELL;
827 tp->val.f = func;
831 * find command
832 * either function, hashed command, or built-in (in that order)
834 struct tbl *
835 findcom(const char *name, int flags)
837 static struct tbl temp;
838 unsigned int h = hash(name);
839 struct tbl *tp = NULL, *tbi;
840 int insert = Flag(FTRACKALL); /* insert if not found */
841 char *fpath; /* for function autoloading */
842 char *npath;
844 if (strchr(name, '/') != NULL) {
845 insert = 0;
846 /* prevent FPATH search below */
847 flags &= ~FC_FUNC;
848 goto Search;
850 tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h) : NULL;
851 /* POSIX says special builtins first, then functions, then
852 * POSIX regular builtins, then search path...
854 if ((flags & FC_SPECBI) && tbi && (tbi->flag & SPEC_BI))
855 tp = tbi;
856 if (!tp && (flags & FC_FUNC)) {
857 tp = findfunc(name, h, false);
858 if (tp && !(tp->flag & ISSET)) {
859 if ((fpath = str_val(global("FPATH"))) == null) {
860 tp->u.fpath = NULL;
861 tp->u2.errno_ = 0;
862 } else
863 tp->u.fpath = search(name, fpath, R_OK,
864 &tp->u2.errno_);
867 if (!tp && (flags & FC_REGBI) && tbi && (tbi->flag & REG_BI))
868 tp = tbi;
869 /* todo: posix says non-special/non-regular builtins must
870 * be triggered by some user-controllable means like a
871 * special directory in PATH. Requires modifications to
872 * the search() function. Tracked aliases should be
873 * modified to allow tracking of builtin commands.
874 * This should be under control of the FPOSIX flag.
875 * If this is changed, also change c_whence...
877 if (!tp && (flags & FC_UNREGBI) && tbi)
878 tp = tbi;
879 if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
880 tp = ktsearch(&taliases, name, h);
881 if (tp && (tp->flag & ISSET) && access(tp->val.s, X_OK) != 0) {
882 if (tp->flag & ALLOC) {
883 tp->flag &= ~ALLOC;
884 afree(tp->val.s, APERM);
886 tp->flag &= ~ISSET;
890 Search:
891 if ((!tp || (tp->type == CTALIAS && !(tp->flag&ISSET))) &&
892 (flags & FC_PATH)) {
893 if (!tp) {
894 if (insert && !(flags & FC_DEFPATH)) {
895 tp = ktenter(&taliases, name, h);
896 tp->type = CTALIAS;
897 } else {
898 tp = &temp;
899 tp->type = CEXEC;
901 tp->flag = DEFINED; /* make ~ISSET */
903 npath = search(name, flags & FC_DEFPATH ? def_path :
904 search_path, X_OK, &tp->u2.errno_);
905 if (npath) {
906 if (tp == &temp) {
907 tp->val.s = npath;
908 } else {
909 tp->val.s = str_save(npath, APERM);
910 if (npath != name)
911 afree(npath, ATEMP);
913 tp->flag |= ISSET|ALLOC;
914 } else if ((flags & FC_FUNC) &&
915 (fpath = str_val(global("FPATH"))) != null &&
916 (npath = search(name, fpath, R_OK,
917 &tp->u2.errno_)) != NULL) {
918 /* An undocumented feature of at&t ksh is that it
919 * searches FPATH if a command is not found, even
920 * if the command hasn't been set up as an autoloaded
921 * function (ie, no typeset -uf).
923 tp = &temp;
924 tp->type = CFUNC;
925 tp->flag = DEFINED; /* make ~ISSET */
926 tp->u.fpath = npath;
929 return tp;
933 * flush executable commands with relative paths
935 void
936 flushcom(int all) /* just relative or all */
938 struct tbl *tp;
939 struct tstate ts;
941 for (ktwalk(&ts, &taliases); (tp = ktnext(&ts)) != NULL; )
942 if ((tp->flag&ISSET) && (all || tp->val.s[0] != '/')) {
943 if (tp->flag&ALLOC) {
944 tp->flag &= ~(ALLOC|ISSET);
945 afree(tp->val.s, APERM);
947 tp->flag &= ~ISSET;
951 /* Check if path is something we want to find. Returns -1 for failure. */
953 search_access(const char *path, int mode,
954 int *errnop) /* set if candidate found, but not suitable */
956 int ret, err = 0;
957 struct stat statb;
959 if (stat(path, &statb) < 0)
960 return -1;
961 ret = access(path, mode);
962 if (ret < 0)
963 err = errno; /* File exists, but we can't access it */
964 else if (mode == X_OK && (!S_ISREG(statb.st_mode) ||
965 !(statb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))) {
966 /* This 'cause access() says root can execute everything */
967 ret = -1;
968 err = S_ISDIR(statb.st_mode) ? EISDIR : EACCES;
970 if (err && errnop && !*errnop)
971 *errnop = err;
972 return ret;
976 * search for command with PATH
978 char *
979 search(const char *name, const char *path,
980 int mode, /* R_OK or X_OK */
981 int *errnop) /* set if candidate found, but not suitable */
983 const char *sp, *p;
984 char *xp;
985 XString xs;
986 int namelen;
988 if (errnop)
989 *errnop = 0;
990 if (strchr(name, '/')) {
991 if (search_access(name, mode, errnop) == 0)
992 return (char *) name;
993 return NULL;
996 namelen = strlen(name) + 1;
997 Xinit(xs, xp, 128, ATEMP);
999 sp = path;
1000 while (sp != NULL) {
1001 xp = Xstring(xs, xp);
1002 if (!(p = strchr(sp, ':')))
1003 p = sp + strlen(sp);
1004 if (p != sp) {
1005 XcheckN(xs, xp, p - sp);
1006 memcpy(xp, sp, p - sp);
1007 xp += p - sp;
1008 *xp++ = '/';
1010 sp = p;
1011 XcheckN(xs, xp, namelen);
1012 memcpy(xp, name, namelen);
1013 if (search_access(Xstring(xs, xp), mode, errnop) == 0)
1014 return Xclose(xs, xp + namelen);
1015 if (*sp++ == '\0')
1016 sp = NULL;
1018 Xfree(xs, xp);
1019 return NULL;
1022 static int
1023 call_builtin(struct tbl *tp, char **wp)
1025 int rv;
1027 builtin_argv0 = wp[0];
1028 builtin_flag = tp->flag;
1029 shf_reopen(1, SHF_WR, shl_stdout);
1030 shl_stdout_ok = 1;
1031 ksh_getopt_reset(&builtin_opt, GF_ERROR);
1032 rv = (*tp->val.f)(wp);
1033 shf_flush(shl_stdout);
1034 shl_stdout_ok = 0;
1035 builtin_flag = 0;
1036 builtin_argv0 = NULL;
1037 return rv;
1041 * set up redirection, saving old fd's in e->savefd
1043 static int
1044 iosetup(struct ioword *iop, struct tbl *tp)
1046 int u = -1;
1047 char *cp = iop->name;
1048 int iotype = iop->flag & IOTYPE;
1049 int do_open = 1, do_close = 0, flags = 0;
1050 struct ioword iotmp;
1051 struct stat statb;
1053 if (iotype != IOHERE)
1054 cp = evalonestr(cp, DOTILDE|(Flag(FTALKING_I) ? DOGLOB : 0));
1056 /* Used for tracing and error messages to print expanded cp */
1057 iotmp = *iop;
1058 iotmp.name = (iotype == IOHERE) ? NULL : cp;
1059 iotmp.flag |= IONAMEXP;
1061 if (Flag(FXTRACE))
1062 shellf("%s%s\n",
1063 PS4_SUBSTITUTE(str_val(global("PS4"))),
1064 snptreef(NULL, 32, "%R", &iotmp));
1066 switch (iotype) {
1067 case IOREAD:
1068 flags = O_RDONLY;
1069 break;
1071 case IOCAT:
1072 flags = O_WRONLY | O_APPEND | O_CREAT;
1073 break;
1075 case IOWRITE:
1076 flags = O_WRONLY | O_CREAT | O_TRUNC;
1077 /* The stat() is here to allow redirections to
1078 * things like /dev/null without error.
1080 if (Flag(FNOCLOBBER) && !(iop->flag & IOCLOB) &&
1081 (stat(cp, &statb) < 0 || S_ISREG(statb.st_mode)))
1082 flags |= O_EXCL;
1083 break;
1085 case IORDWR:
1086 flags = O_RDWR | O_CREAT;
1087 break;
1089 case IOHERE:
1090 do_open = 0;
1091 /* herein() returns -2 if error has been printed */
1092 u = herein(iop->heredoc, iop->flag & IOEVAL);
1093 /* cp may have wrong name */
1094 break;
1096 case IODUP:
1098 const char *emsg;
1100 do_open = 0;
1101 if (*cp == '-' && !cp[1]) {
1102 u = 1009; /* prevent error return below */
1103 do_close = 1;
1104 } else if ((u = check_fd(cp,
1105 X_OK | ((iop->flag & IORDUP) ? R_OK : W_OK),
1106 &emsg)) < 0) {
1107 warningf(true, "%s: %s",
1108 snptreef(NULL, 32, "%R", &iotmp), emsg);
1109 return -1;
1111 if (u == iop->unit)
1112 return 0; /* "dup from" == "dup to" */
1113 break;
1117 if (do_open) {
1118 if (Flag(FRESTRICTED) && (flags & O_CREAT)) {
1119 warningf(true, "%s: restricted", cp);
1120 return -1;
1122 u = open(cp, flags, 0666);
1124 if (u < 0) {
1125 /* herein() may already have printed message */
1126 if (u == -1)
1127 warningf(true, "cannot %s %s: %s",
1128 iotype == IODUP ? "dup" :
1129 (iotype == IOREAD || iotype == IOHERE) ?
1130 "open" : "create", cp, strerror(errno));
1131 return -1;
1133 /* Do not save if it has already been redirected (i.e. "cat >x >y"). */
1134 if (genv->savefd[iop->unit] == 0) {
1135 /* If these are the same, it means unit was previously closed */
1136 if (u == iop->unit)
1137 genv->savefd[iop->unit] = -1;
1138 else
1139 /* c_exec() assumes e->savefd[fd] set for any
1140 * redirections. Ask savefd() not to close iop->unit;
1141 * this allows error messages to be seen if iop->unit
1142 * is 2; also means we can't lose the fd (eg, both
1143 * dup2 below and dup2 in restfd() failing).
1145 genv->savefd[iop->unit] = savefd(iop->unit);
1148 if (do_close)
1149 close(iop->unit);
1150 else if (u != iop->unit) {
1151 if (ksh_dup2(u, iop->unit, true) < 0) {
1152 warningf(true,
1153 "could not finish (dup) redirection %s: %s",
1154 snptreef(NULL, 32, "%R", &iotmp),
1155 strerror(errno));
1156 if (iotype != IODUP)
1157 close(u);
1158 return -1;
1160 if (iotype != IODUP)
1161 close(u);
1162 /* Touching any co-process fd in an empty exec
1163 * causes the shell to close its copies
1165 else if (tp && tp->type == CSHELL && tp->val.f == c_exec) {
1166 if (iop->flag & IORDUP) /* possible exec <&p */
1167 coproc_read_close(u);
1168 else /* possible exec >&p */
1169 coproc_write_close(u);
1172 if (u == 2) /* Clear any write errors */
1173 shf_reopen(2, SHF_WR, shl_out);
1174 return 0;
1178 * open here document temp file.
1179 * if unquoted here, expand here temp file into second temp file.
1181 static int
1182 herein(const char *content, int sub)
1184 volatile int fd = -1;
1185 struct source *s, *volatile osource;
1186 struct shf *volatile shf;
1187 struct temp *h;
1188 int i;
1190 /* ksh -c 'cat << EOF' can cause this... */
1191 if (content == NULL) {
1192 warningf(true, "here document missing");
1193 return -2; /* special to iosetup(): don't print error */
1196 /* Create temp file to hold content (done before newenv so temp
1197 * doesn't get removed too soon).
1199 h = maketemp(ATEMP, TT_HEREDOC_EXP, &genv->temps);
1200 if (!(shf = h->shf) || (fd = open(h->name, O_RDONLY, 0)) < 0) {
1201 warningf(true, "can't %s temporary file %s: %s",
1202 !shf ? "create" : "open",
1203 h->name, strerror(errno));
1204 if (shf)
1205 shf_close(shf);
1206 return -2 /* special to iosetup(): don't print error */;
1209 osource = source;
1210 newenv(E_ERRH);
1211 i = sigsetjmp(genv->jbuf, 0);
1212 if (i) {
1213 source = osource;
1214 quitenv(shf);
1215 close(fd);
1216 return -2; /* special to iosetup(): don't print error */
1218 if (sub) {
1219 /* Do substitutions on the content of heredoc */
1220 s = pushs(SSTRING, ATEMP);
1221 s->start = s->str = content;
1222 source = s;
1223 if (yylex(ONEWORD|HEREDOC) != LWORD)
1224 internal_errorf("%s: yylex", __func__);
1225 source = osource;
1226 shf_puts(evalstr(yylval.cp, 0), shf);
1227 } else
1228 shf_puts(content, shf);
1230 quitenv(NULL);
1232 if (shf_close(shf) == EOF) {
1233 close(fd);
1234 warningf(true, "error writing %s: %s", h->name,
1235 strerror(errno));
1236 return -2; /* special to iosetup(): don't print error */
1239 return fd;
1243 * ksh special - the select command processing section
1244 * print the args in column form - assuming that we can
1246 static char *
1247 do_selectargs(char **ap, bool print_menu)
1249 static const char *const read_args[] = {
1250 "read", "-r", "REPLY", NULL
1252 const char *errstr;
1253 char *s;
1254 int i, argct;
1256 for (argct = 0; ap[argct]; argct++)
1258 while (1) {
1259 /* Menu is printed if
1260 * - this is the first time around the select loop
1261 * - the user enters a blank line
1262 * - the REPLY parameter is empty
1264 if (print_menu || !*str_val(global("REPLY")))
1265 pr_menu(ap);
1266 shellf("%s", str_val(global("PS3")));
1267 if (call_builtin(findcom("read", FC_BI), (char **) read_args))
1268 return NULL;
1269 s = str_val(global("REPLY"));
1270 if (*s) {
1271 i = strtonum(s, 1, argct, &errstr);
1272 if (errstr)
1273 return null;
1274 return ap[i - 1];
1276 print_menu = 1;
1280 struct select_menu_info {
1281 char *const *args;
1282 int arg_width;
1283 int num_width;
1286 static char *select_fmt_entry(void *arg, int i, char *buf, int buflen);
1288 /* format a single select menu item */
1289 static char *
1290 select_fmt_entry(void *arg, int i, char *buf, int buflen)
1292 struct select_menu_info *smi = (struct select_menu_info *) arg;
1294 shf_snprintf(buf, buflen, "%*d) %s",
1295 smi->num_width, i + 1, smi->args[i]);
1296 return buf;
1300 * print a select style menu
1303 pr_menu(char *const *ap)
1305 struct select_menu_info smi;
1306 char *const *pp;
1307 int nwidth, dwidth;
1308 int i, n;
1310 /* Width/column calculations were done once and saved, but this
1311 * means select can't be used recursively so we re-calculate each
1312 * time (could save in a structure that is returned, but its probably
1313 * not worth the bother).
1317 * get dimensions of the list
1319 for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) {
1320 i = strlen(*pp);
1321 nwidth = (i > nwidth) ? i : nwidth;
1324 * we will print an index of the form
1325 * %d)
1326 * in front of each entry
1327 * get the max width of this
1329 for (i = n, dwidth = 1; i >= 10; i /= 10)
1330 dwidth++;
1332 smi.args = ap;
1333 smi.arg_width = nwidth;
1334 smi.num_width = dwidth;
1335 print_columns(shl_out, n, select_fmt_entry, (void *) &smi,
1336 dwidth + nwidth + 2, 1);
1338 return n;
1341 /* XXX: horrible kludge to fit within the framework */
1343 static char *plain_fmt_entry(void *arg, int i, char *buf, int buflen);
1345 static char *
1346 plain_fmt_entry(void *arg, int i, char *buf, int buflen)
1348 shf_snprintf(buf, buflen, "%s", ((char *const *)arg)[i]);
1349 return buf;
1353 pr_list(char *const *ap)
1355 char *const *pp;
1356 int nwidth;
1357 int i, n;
1359 for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) {
1360 i = strlen(*pp);
1361 nwidth = (i > nwidth) ? i : nwidth;
1363 print_columns(shl_out, n, plain_fmt_entry, (void *) ap, nwidth + 1, 0);
1365 return n;
1369 * [[ ... ]] evaluation routines
1372 extern const char *const dbtest_tokens[];
1373 extern const char db_close[];
1375 /* Test if the current token is a whatever. Accepts the current token if
1376 * it is. Returns 0 if it is not, non-zero if it is (in the case of
1377 * TM_UNOP and TM_BINOP, the returned value is a Test_op).
1379 static int
1380 dbteste_isa(Test_env *te, Test_meta meta)
1382 int ret = 0;
1383 int uqword;
1384 char *p;
1386 if (!*te->pos.wp)
1387 return meta == TM_END;
1389 /* unquoted word? */
1390 for (p = *te->pos.wp; *p == CHAR; p += 2)
1392 uqword = *p == EOS;
1394 if (meta == TM_UNOP || meta == TM_BINOP) {
1395 if (uqword) {
1396 char buf[8]; /* longer than the longest operator */
1397 char *q = buf;
1398 for (p = *te->pos.wp;
1399 *p == CHAR && q < &buf[sizeof(buf) - 1]; p += 2)
1400 *q++ = p[1];
1401 *q = '\0';
1402 ret = (int) test_isop(te, meta, buf);
1404 } else if (meta == TM_END)
1405 ret = 0;
1406 else
1407 ret = uqword &&
1408 strcmp(*te->pos.wp, dbtest_tokens[(int) meta]) == 0;
1410 /* Accept the token? */
1411 if (ret)
1412 te->pos.wp++;
1414 return ret;
1417 static const char *
1418 dbteste_getopnd(Test_env *te, Test_op op, int do_eval)
1420 char *s = *te->pos.wp;
1422 if (!s)
1423 return NULL;
1425 te->pos.wp++;
1427 if (!do_eval)
1428 return null;
1430 if (op == TO_STEQL || op == TO_STNEQ)
1431 s = evalstr(s, DOTILDE | DOPAT);
1432 else
1433 s = evalstr(s, DOTILDE);
1435 return s;
1438 static int
1439 dbteste_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
1440 int do_eval)
1442 return test_eval(te, op, opnd1, opnd2, do_eval);
1445 static void
1446 dbteste_error(Test_env *te, int offset, const char *msg)
1448 te->flags |= TEF_ERROR;
1449 internal_warningf("%s: %s (offset %d)", __func__, msg, offset);