15 /* -------- exec.c -------- */
22 static char *signame[] = {
25 (char *)NULL, /* interrupt */
27 "Illegal instruction",
36 (char *)NULL, /* broken pipe */
40 #define NSIGNAL (sizeof(signame)/sizeof(signame[0]))
43 _PROTOTYPE(static int forkexec, (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked ));
44 _PROTOTYPE(static int parent, (void));
45 _PROTOTYPE(int iosetup, (struct ioword *iop, int pipein, int pipeout ));
46 _PROTOTYPE(static void echo, (char **wp ));
47 _PROTOTYPE(static struct op **find1case, (struct op *t, char *w ));
48 _PROTOTYPE(static struct op *findcase, (struct op *t, char *w ));
49 _PROTOTYPE(static void brkset, (struct brkcon *bc ));
50 _PROTOTYPE(int dolabel, (void));
51 _PROTOTYPE(int dochdir, (struct op *t ));
52 _PROTOTYPE(int doshift, (struct op *t ));
53 _PROTOTYPE(int dologin, (struct op *t ));
54 _PROTOTYPE(int doumask, (struct op *t ));
55 _PROTOTYPE(int doexec, (struct op *t ));
56 _PROTOTYPE(int dodot, (struct op *t ));
57 _PROTOTYPE(int dowait, (struct op *t ));
58 _PROTOTYPE(int doread, (struct op *t ));
59 _PROTOTYPE(int doeval, (struct op *t ));
60 _PROTOTYPE(int dotrap, (struct op *t ));
61 _PROTOTYPE(int getsig, (char *s ));
62 _PROTOTYPE(void setsig, (int n, void (*f)()));
63 _PROTOTYPE(int getn, (char *as ));
64 _PROTOTYPE(int dobreak, (struct op *t ));
65 _PROTOTYPE(int docontinue, (struct op *t ));
66 _PROTOTYPE(static int brkcontin, (char *cp, int val ));
67 _PROTOTYPE(int doexit, (struct op *t ));
68 _PROTOTYPE(int doexport, (struct op *t ));
69 _PROTOTYPE(int doreadonly, (struct op *t ));
70 _PROTOTYPE(static void rdexp, (char **wp, void (*f)(), int key));
71 _PROTOTYPE(static void badid, (char *s ));
72 _PROTOTYPE(int doset, (struct op *t ));
73 _PROTOTYPE(void varput, (char *s, int out ));
74 _PROTOTYPE(int dotimes, (void));
77 execute(t, pin, pout, act)
78 register struct op *t;
82 register struct op *t1;
83 int i, pv[2], rv, child, a;
84 char *cp, **wp, **wp2;
92 wp = (wp2 = t->words) != NULL
93 ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY)
99 rv = forkexec(t, pin, pout, act, wp, &child);
107 if ((rv = openpipe(pv)) < 0)
109 pv[0] = remap(pv[0]);
110 pv[1] = remap(pv[1]);
111 (void) execute(t->left, pin, pv, 0);
112 rv = execute(t->right, pv, pout, 0);
116 (void) execute(t->left, pin, pout, 0);
117 rv = execute(t->right, pin, pout, 0);
124 setval(lookup("!"), putn(i));
135 signal(SIGINT, SIG_IGN);
136 signal(SIGQUIT, SIG_IGN);
138 signal(SIGTERM, SIG_DFL);
142 open("/dev/null", 0);
144 exit(execute(t->left, pin, pout, FEXEC));
150 rv = execute(t->left, pin, pout, 0);
151 if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND))
152 rv = execute(t1, pin, pout, 0);
162 while (*wp++ != NULL)
166 while (setjmp(bc.brkpt))
170 for (t1 = t->left; i-- && *wp != NULL;) {
172 rv = execute(t1, pin, pout, 0);
174 brklist = brklist->nextlev;
179 while (setjmp(bc.brkpt))
184 while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE))
185 rv = execute(t->right, pin, pout, 0);
186 brklist = brklist->nextlev;
191 if (t->right != NULL) {
192 rv = !execute(t->left, pin, pout, 0) ?
193 execute(t->right->left, pin, pout, 0):
194 execute(t->right->right, pin, pout, 0);
199 if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0)
201 if ((t1 = findcase(t->left, cp)) != NULL)
202 rv = execute(t1, pin, pout, 0);
209 if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) {
214 if (rv >= 0 && (t1 = t->left))
215 rv = execute(t1, pin, pout, 0);
225 if (talking && intr) {
229 if ((i = trapset) != 0) {
237 forkexec(t, pin, pout, act, wp, pforked)
238 register struct op *t;
244 int i, rv, (*shcom)();
247 struct ioword **iopp;
255 rv = -1; /* system-detected error */
256 if (t->type == TCOM) {
257 while ((cp = *wp++) != NULL)
261 /* strip all initial assignments */
262 /* not correct wrt PATH=yyy command etc */
265 if (cp == NULL && t->ioact == NULL) {
266 while ((cp = *owp++) != NULL && assign(cp, COPYV))
268 return(setstatus(0));
275 if (shcom == NULL && (f & FEXEC) == 0) {
282 return(pout==NULL? setstatus(waitfor(i,0)): 0);
285 signal(SIGINT, SIG_IGN);
286 signal(SIGQUIT, SIG_IGN);
296 while ((cp = *owp++) != NULL && assign(cp, COPYV))
300 if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) {
301 err("piping to/from shell builtins not yet done");
313 if ((iopp = t->ioact) != NULL) {
314 if (shcom != NULL && shcom != doexec) {
316 err(": cannot redirect shell command");
320 if (iosetup(*iopp++, pin!=NULL, pout!=NULL))
324 return(setstatus((*shcom)(t)));
325 /* should use FIOCEXCL */
326 for (i=FDBASE; i<NOFILE; i++)
329 signal(SIGINT, SIG_DFL);
330 signal(SIGQUIT, SIG_DFL);
332 if (t->type == TPAREN)
333 exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));
336 cp = rexecve(wp[0], wp, makenv());
337 prs(wp[0]); prs(": "); warn(cp);
345 * common actions when creating a new child
361 * 0< 1> are ignored as required
365 iosetup(iop, pipein, pipeout)
366 register struct ioword *iop;
372 if (iop->io_unit == IODEFAULT) /* take default */
373 iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1;
374 if (pipein && iop->io_unit == 0)
376 if (pipeout && iop->io_unit == 1)
378 msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create";
379 if ((iop->io_flag & IOHERE) == 0) {
381 if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL)
384 if (iop->io_flag & IODUP) {
385 if (cp[1] || (!digit(*cp) && *cp != '-')) {
387 err(": illegal >& argument");
391 iop->io_flag = IOCLOSE;
392 iop->io_flag &= ~(IOREAD|IOWRITE);
394 switch (iop->io_flag) {
401 u = herein(iop->io_name, iop->io_flag&IOXHERE);
406 if ((u = open(cp, 1)) >= 0) {
407 lseek(u, (long)0, 2);
415 u = dup2(*cp-'0', iop->io_unit);
428 if (u != iop->io_unit) {
429 dup2(u, iop->io_unit);
443 for (i=0; wp[i]; i++) {
456 register struct op *t1;
458 register char **wp, *cp;
461 return((struct op **)NULL);
462 if (t->type == TLIST) {
463 if ((tp = find1case(t->left, w)) != NULL)
465 t1 = t->right; /* TPAT */
468 for (wp = t1->words; *wp;)
469 if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp))
471 return((struct op **)NULL);
479 register struct op **tp;
481 return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL);
485 * Enter a new loop level (marked for break/continue).
491 bc->nextlev = brklist;
496 * Wait for the last process created.
497 * Print a message for each process found
498 * that was killed by a signal.
499 * Ignore interrupt signals while waiting
500 * unless `canintr' is true.
503 waitfor(lastpid, canintr)
504 register int lastpid;
507 register int pid, rv;
509 int oheedint = heedint;
516 if (errno != EINTR || canintr)
519 if ((rv = WAITSIG(s)) != 0) {
521 if (signame[rv] != NULL) {
522 if (pid != lastpid) {
529 if (pid != lastpid) {
533 prs("Signal "); prn(rv); prs(" ");
536 prs(" - core dumped");
537 if (rv >= NSIGNAL || signame[rv])
543 } while (pid != lastpid);
550 if (exstat == 0) exstat = rv;
561 setval(lookup("?"), putn(s));
566 * PATH-searching interface to execve.
567 * If getenv("PATH") were kept up-to-date,
568 * execvp might be used.
572 char *c, **v, **envp;
575 register char *sp, *tp;
576 int eacces = 0, asis = 0;
578 sp = any('/', c)? "": path->value;
580 while (asis || *sp != '\0') {
583 for (; *sp != '\0'; tp++)
584 if ((*tp = *sp++) == ':') {
590 for (i = 0; (*tp++ = c[i++]) != '\0';)
592 execve(e.linep, v, envp);
598 execve("/bin/sh", v, envp);
603 return("program too big");
606 return("argument list too long");
613 return(errno==ENOENT ? "not found" : "cannot execute");
617 * Run the command produced by generator `f'
618 * applied to stream `arg'.
626 struct wdblock *swdlist;
627 struct wdblock *siolist;
638 if (newenv(setjmp(errpt = ev)) == 0) {
644 if (setjmp(failpt = rt) == 0 && yyparse() == 0)
645 rv = execute(outtree, NOPIPE, NOPIPE, 0);
656 /* -------- do.c -------- */
657 /* #include "sh.h" */
660 * built-in commands: doX
671 register struct op *t;
673 register char *cp, *er;
675 if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL)
676 er = ": no home directory";
677 else if(chdir(cp) < 0)
678 er = ": bad directory";
681 prs(cp != NULL? cp: "cd");
688 register struct op *t;
692 n = t->words[1]? getn(t->words[1]): 1;
694 err("nothing to shift");
700 setval(lookup("#"), putn(dolc));
705 * execute login and newgrp directly
714 signal(SIGINT, SIG_DFL);
715 signal(SIGQUIT, SIG_DFL);
717 cp = rexecve(t->words[0], t->words, makenv());
718 prs(t->words[0]); prs(": "); err(cp);
724 register struct op *t;
729 if ((cp = t->words[1]) == NULL) {
732 for (n=3*4; (n-=3) >= 0;)
733 putc('0'+((i>>n)&07));
736 for (n=0; *cp>='0' && *cp<='9'; cp++)
745 register struct op *t;
752 for(i = 0; (t->words[i]=t->words[i+1]) != NULL; i++)
758 if (setjmp(failpt = ex) == 0)
759 execute(t, NOPIPE, NOPIPE, FEXEC);
770 register char *sp, *tp;
773 if ((cp = t->words[1]) == NULL)
775 sp = any('/', cp)? ":": path->value;
778 while (*sp && (*tp = *sp++) != ':')
782 for (i = 0; (*tp++ = cp[i++]) != '\0';)
784 if ((i = open(e.linep, 0)) >= 0) {
802 if ((cp = t->words[1]) != NULL) {
808 setstatus(waitfor(i, 1));
816 register char *cp, **wp;
820 if (t->words[1] == NULL) {
821 err("usage: read name ...");
824 for (wp = t->words+1; *wp; wp++) {
825 for (cp = e.linep; !nl && cp < elinep-1; cp++)
826 if ((nb = read(0, cp, sizeof(*cp))) != sizeof(*cp) ||
827 (nl = (*cp == '\n')) ||
828 (wp[1] && any(*cp, ifs->value)))
833 setval(lookup(*wp), e.linep);
840 register struct op *t;
842 return(RUN(awordlist, t->words+1, wdchar));
847 register struct op *t;
850 register int resetsig;
852 if (t->words[1] == NULL) {
853 for (i=0; i<=_NSIG; i++)
862 resetsig = digit(*t->words[1]);
863 for (i = resetsig ? 1 : 2; t->words[i] != NULL; ++i) {
864 n = getsig(t->words[i]);
868 if (*t->words[1] != '\0') {
869 trap[n] = strsave(t->words[1], 0);
878 setsig(n, n == SIGQUIT ? SIG_IGN
893 if ((n = getn(s)) < 0 || n > _NSIG) {
894 err("trap: bad signal number");
903 _PROTOTYPE(void (*f), (int));
907 if (signal(n, SIG_IGN) != SIG_IGN || ourtrap[n]) {
926 for (n = 0; digit(*s); s++)
927 n = (n*10) + (*s-'0');
939 return(brkcontin(t->words[1], 1));
946 return(brkcontin(t->words[1], 0));
954 register struct brkcon *bc;
957 nl = cp == NULL? 1: getn(cp);
961 if ((bc = brklist) == NULL)
963 brklist = bc->nextlev;
966 err("bad break/continue level");
970 longjmp(bc->brkpt, 1);
981 if ((cp = t->words[1]) != NULL)
991 rdexp(t->words+1, export, EXPORT);
999 rdexp(t->words+1, ronly, RONLY);
1010 for (; *wp != NULL; wp++)
1024 err(": bad identifier");
1029 register struct op *t;
1031 register struct var *vp;
1035 if ((cp = t->words[1]) == NULL) {
1036 for (vp = vlist; vp; vp = vp->next)
1037 varput(vp->name, 1);
1041 /* bad: t->words++; */
1042 for(n = 0; (t->words[n]=t->words[n+1]) != NULL; n++)
1045 flag['x'] = flag['v'] = 0;
1055 if (*cp>='a' && *cp<='z')
1062 t->words[0] = dolv[0];
1063 for (n=1; t->words[n]; n++)
1064 setarea((char *)t->words[n], 0);
1067 setval(lookup("#"), putn(dolc));
1068 setarea((char *)(dolv-1), 0);
1079 write(out, s, strlen(s));
1080 write(out, "\n", 1);
1095 prn((int)(tbuf.tms_cutime / MINS));
1097 prn((int)((tbuf.tms_cutime % MINS) / SECS));
1099 prn((int)(tbuf.tms_cstime / MINS));
1101 prn((int)((tbuf.tms_cstime % MINS) / SECS));
1110 static struct builtin builtin[] = {
1120 "continue", docontinue,
1123 "readonly", doreadonly,
1136 register struct builtin *bp;
1138 for (bp = builtin; bp->command != NULL; bp++)
1139 if (strcmp(bp->command, s) == 0)
1141 return((int(*)())NULL);