14 /* -------- exec.c -------- */
21 static char *signame
[] = {
24 (char *)NULL
, /* interrupt */
26 "Illegal instruction",
35 (char *)NULL
, /* broken pipe */
39 #define NSIGNAL (sizeof(signame)/sizeof(signame[0]))
42 _PROTOTYPE(static int forkexec
, (struct op
*t
, int *pin
, int *pout
, int act
, char **wp
, int *pforked
));
43 _PROTOTYPE(static int parent
, (void));
44 _PROTOTYPE(int iosetup
, (struct ioword
*iop
, int pipein
, int pipeout
));
45 _PROTOTYPE(static void echo
, (char **wp
));
46 _PROTOTYPE(static struct op
**find1case
, (struct op
*t
, char *w
));
47 _PROTOTYPE(static struct op
*findcase
, (struct op
*t
, char *w
));
48 _PROTOTYPE(static void brkset
, (struct brkcon
*bc
));
49 _PROTOTYPE(int dolabel
, (void));
50 _PROTOTYPE(int dochdir
, (struct op
*t
));
51 _PROTOTYPE(int doshift
, (struct op
*t
));
52 _PROTOTYPE(int dologin
, (struct op
*t
));
53 _PROTOTYPE(int doumask
, (struct op
*t
));
54 _PROTOTYPE(int doexec
, (struct op
*t
));
55 _PROTOTYPE(int dodot
, (struct op
*t
));
56 _PROTOTYPE(int dowait
, (struct op
*t
));
57 _PROTOTYPE(int doread
, (struct op
*t
));
58 _PROTOTYPE(int doeval
, (struct op
*t
));
59 _PROTOTYPE(int dotrap
, (struct op
*t
));
60 _PROTOTYPE(int getsig
, (char *s
));
61 _PROTOTYPE(void setsig
, (int n
, void (*f
)()));
62 _PROTOTYPE(int getn
, (char *as
));
63 _PROTOTYPE(int dobreak
, (struct op
*t
));
64 _PROTOTYPE(int docontinue
, (struct op
*t
));
65 _PROTOTYPE(static int brkcontin
, (char *cp
, int val
));
66 _PROTOTYPE(int doexit
, (struct op
*t
));
67 _PROTOTYPE(int doexport
, (struct op
*t
));
68 _PROTOTYPE(int doreadonly
, (struct op
*t
));
69 _PROTOTYPE(static void rdexp
, (char **wp
, void (*f
)(), int key
));
70 _PROTOTYPE(static void badid
, (char *s
));
71 _PROTOTYPE(int doset
, (struct op
*t
));
72 _PROTOTYPE(void varput
, (char *s
, int out
));
73 _PROTOTYPE(int dotimes
, (void));
76 execute(t
, pin
, pout
, act
)
77 register struct op
*t
;
81 register struct op
*t1
;
82 int i
, pv
[2], rv
, child
, a
;
83 char *cp
, **wp
, **wp2
;
91 wp
= (wp2
= t
->words
) != NULL
92 ? eval(wp2
, t
->type
== TCOM
? DOALL
: DOALL
& ~DOKEY
)
98 rv
= forkexec(t
, pin
, pout
, act
, wp
, &child
);
106 if ((rv
= openpipe(pv
)) < 0)
108 pv
[0] = remap(pv
[0]);
109 pv
[1] = remap(pv
[1]);
110 (void) execute(t
->left
, pin
, pv
, 0);
111 rv
= execute(t
->right
, pv
, pout
, 0);
115 (void) execute(t
->left
, pin
, pout
, 0);
116 rv
= execute(t
->right
, pin
, pout
, 0);
123 setval(lookup("!"), putn(i
));
134 signal(SIGINT
, SIG_IGN
);
135 signal(SIGQUIT
, SIG_IGN
);
137 signal(SIGTERM
, SIG_DFL
);
141 open("/dev/null", 0);
143 exit(execute(t
->left
, pin
, pout
, FEXEC
));
149 rv
= execute(t
->left
, pin
, pout
, 0);
150 if ((t1
= t
->right
)!=NULL
&& (rv
== 0) == (t
->type
== TAND
))
151 rv
= execute(t1
, pin
, pout
, 0);
161 while (*wp
++ != NULL
)
165 while (setjmp(bc
.brkpt
))
169 for (t1
= t
->left
; i
-- && *wp
!= NULL
;) {
171 rv
= execute(t1
, pin
, pout
, 0);
173 brklist
= brklist
->nextlev
;
178 while (setjmp(bc
.brkpt
))
183 while ((execute(t1
, pin
, pout
, 0) == 0) == (t
->type
== TWHILE
))
184 rv
= execute(t
->right
, pin
, pout
, 0);
185 brklist
= brklist
->nextlev
;
190 if (t
->right
!= NULL
) {
191 rv
= !execute(t
->left
, pin
, pout
, 0) ?
192 execute(t
->right
->left
, pin
, pout
, 0):
193 execute(t
->right
->right
, pin
, pout
, 0);
198 if ((cp
= evalstr(t
->str
, DOSUB
|DOTRIM
)) == 0)
200 if ((t1
= findcase(t
->left
, cp
)) != NULL
)
201 rv
= execute(t1
, pin
, pout
, 0);
208 if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) {
213 if (rv
>= 0 && (t1
= t
->left
))
214 rv
= execute(t1
, pin
, pout
, 0);
224 if (talking
&& intr
) {
228 if ((i
= trapset
) != 0) {
236 forkexec(t
, pin
, pout
, act
, wp
, pforked
)
237 register struct op
*t
;
243 int i
, rv
, (*shcom
)();
246 struct ioword
**iopp
;
254 rv
= -1; /* system-detected error */
255 if (t
->type
== TCOM
) {
256 while ((cp
= *wp
++) != NULL
)
260 /* strip all initial assignments */
261 /* not correct wrt PATH=yyy command etc */
264 if (cp
== NULL
&& t
->ioact
== NULL
) {
265 while ((cp
= *owp
++) != NULL
&& assign(cp
, COPYV
))
267 return(setstatus(0));
274 if (shcom
== NULL
&& (f
& FEXEC
) == 0) {
281 return(pout
==NULL
? setstatus(waitfor(i
,0)): 0);
284 signal(SIGINT
, SIG_IGN
);
285 signal(SIGQUIT
, SIG_IGN
);
295 while ((cp
= *owp
++) != NULL
&& assign(cp
, COPYV
))
299 if ((pin
!= NULL
|| pout
!= NULL
) && shcom
!= NULL
&& shcom
!= doexec
) {
300 err("piping to/from shell builtins not yet done");
312 if ((iopp
= t
->ioact
) != NULL
) {
313 if (shcom
!= NULL
&& shcom
!= doexec
) {
315 err(": cannot redirect shell command");
319 if (iosetup(*iopp
++, pin
!=NULL
, pout
!=NULL
))
323 return(setstatus((*shcom
)(t
)));
324 /* should use FIOCEXCL */
325 for (i
=FDBASE
; i
<NOFILE
; i
++)
328 signal(SIGINT
, SIG_DFL
);
329 signal(SIGQUIT
, SIG_DFL
);
331 if (t
->type
== TPAREN
)
332 exit(execute(t
->left
, NOPIPE
, NOPIPE
, FEXEC
));
335 cp
= rexecve(wp
[0], wp
, makenv());
336 prs(wp
[0]); prs(": "); warn(cp
);
344 * common actions when creating a new child
360 * 0< 1> are ignored as required
364 iosetup(iop
, pipein
, pipeout
)
365 register struct ioword
*iop
;
371 if (iop
->io_unit
== IODEFAULT
) /* take default */
372 iop
->io_unit
= iop
->io_flag
&(IOREAD
|IOHERE
)? 0: 1;
373 if (pipein
&& iop
->io_unit
== 0)
375 if (pipeout
&& iop
->io_unit
== 1)
377 msg
= iop
->io_flag
&(IOREAD
|IOHERE
)? "open": "create";
378 if ((iop
->io_flag
& IOHERE
) == 0) {
380 if ((cp
= evalstr(cp
, DOSUB
|DOTRIM
)) == NULL
)
383 if (iop
->io_flag
& IODUP
) {
384 if (cp
[1] || (!digit(*cp
) && *cp
!= '-')) {
386 err(": illegal >& argument");
390 iop
->io_flag
= IOCLOSE
;
391 iop
->io_flag
&= ~(IOREAD
|IOWRITE
);
393 switch (iop
->io_flag
) {
400 u
= herein(iop
->io_name
, iop
->io_flag
&IOXHERE
);
405 if ((u
= open(cp
, 1)) >= 0) {
406 lseek(u
, (long)0, 2);
414 u
= dup2(*cp
-'0', iop
->io_unit
);
424 if (iop
->io_flag
&IOHERE
) prs(iop
->io_name
);
432 if (u
!= iop
->io_unit
) {
433 dup2(u
, iop
->io_unit
);
447 for (i
=0; wp
[i
]; i
++) {
460 register struct op
*t1
;
462 register char **wp
, *cp
;
465 return((struct op
**)NULL
);
466 if (t
->type
== TLIST
) {
467 if ((tp
= find1case(t
->left
, w
)) != NULL
)
469 t1
= t
->right
; /* TPAT */
472 for (wp
= t1
->words
; *wp
;)
473 if ((cp
= evalstr(*wp
++, DOSUB
)) && gmatch(w
, cp
))
475 return((struct op
**)NULL
);
483 register struct op
**tp
;
485 return((tp
= find1case(t
, w
)) != NULL
? *tp
: (struct op
*)NULL
);
489 * Enter a new loop level (marked for break/continue).
495 bc
->nextlev
= brklist
;
500 * Wait for the last process created.
501 * Print a message for each process found
502 * that was killed by a signal.
503 * Ignore interrupt signals while waiting
504 * unless `canintr' is true.
507 waitfor(lastpid
, canintr
)
508 register int lastpid
;
511 register int pid
, rv
;
513 int oheedint
= heedint
;
520 if (errno
!= EINTR
|| canintr
)
523 if ((rv
= WAITSIG(s
)) != 0) {
525 if (signame
[rv
] != NULL
) {
526 if (pid
!= lastpid
) {
533 if (pid
!= lastpid
) {
537 prs("Signal "); prn(rv
); prs(" ");
540 prs(" - core dumped");
541 if (rv
>= NSIGNAL
|| signame
[rv
])
547 } while (pid
!= lastpid
);
554 if (exstat
== 0) exstat
= rv
;
565 setval(lookup("?"), putn(s
));
570 * PATH-searching interface to execve.
571 * If getenv("PATH") were kept up-to-date,
572 * execvp might be used.
576 char *c
, **v
, **envp
;
579 register char *sp
, *tp
;
580 int eacces
= 0, asis
= 0;
582 sp
= any('/', c
)? "": path
->value
;
584 while (asis
|| *sp
!= '\0') {
587 for (; *sp
!= '\0'; tp
++)
588 if ((*tp
= *sp
++) == ':') {
594 for (i
= 0; (*tp
++ = c
[i
++]) != '\0';)
596 execve(e
.linep
, v
, envp
);
602 execve("/bin/sh", v
, envp
);
607 return("program too big");
610 return("argument list too long");
617 return(errno
==ENOENT
? "not found" : "cannot execute");
621 * Run the command produced by generator `f'
622 * applied to stream `arg'.
630 struct wdblock
*swdlist
;
631 struct wdblock
*siolist
;
642 if (newenv(setjmp(errpt
= ev
)) == 0) {
648 if (setjmp(failpt
= rt
) == 0 && yyparse() == 0)
649 rv
= execute(outtree
, NOPIPE
, NOPIPE
, 0);
660 /* -------- do.c -------- */
661 /* #include "sh.h" */
664 * built-in commands: doX
675 register struct op
*t
;
677 register char *cp
, *er
;
679 if ((cp
= t
->words
[1]) == NULL
&& (cp
= homedir
->value
) == NULL
)
680 er
= ": no home directory";
681 else if(chdir(cp
) < 0)
682 er
= ": bad directory";
685 prs(cp
!= NULL
? cp
: "cd");
692 register struct op
*t
;
696 n
= t
->words
[1]? getn(t
->words
[1]): 1;
698 err("nothing to shift");
704 setval(lookup("#"), putn(dolc
));
709 * execute login and newgrp directly
718 signal(SIGINT
, SIG_DFL
);
719 signal(SIGQUIT
, SIG_DFL
);
721 cp
= rexecve(t
->words
[0], t
->words
, makenv());
722 prs(t
->words
[0]); prs(": "); err(cp
);
728 register struct op
*t
;
733 if ((cp
= t
->words
[1]) == NULL
) {
736 for (n
=3*4; (n
-=3) >= 0;)
737 putc('0'+((i
>>n
)&07));
740 for (n
=0; *cp
>='0' && *cp
<='9'; cp
++)
749 register struct op
*t
;
756 for(i
= 0; (t
->words
[i
]=t
->words
[i
+1]) != NULL
; i
++)
762 if (setjmp(failpt
= ex
) == 0)
763 execute(t
, NOPIPE
, NOPIPE
, FEXEC
);
774 register char *sp
, *tp
;
777 if ((cp
= t
->words
[1]) == NULL
)
779 sp
= any('/', cp
)? ":": path
->value
;
782 while (*sp
&& (*tp
= *sp
++) != ':')
786 for (i
= 0; (*tp
++ = cp
[i
++]) != '\0';)
788 if ((i
= open(e
.linep
, 0)) >= 0) {
806 if ((cp
= t
->words
[1]) != NULL
) {
812 setstatus(waitfor(i
, 1));
820 register char *cp
, **wp
;
824 if (t
->words
[1] == NULL
) {
825 err("Usage: read name ...");
828 for (wp
= t
->words
+1; *wp
; wp
++) {
829 for (cp
= e
.linep
; !nl
&& cp
< elinep
-1; cp
++)
830 if ((nb
= read(0, cp
, sizeof(*cp
))) != sizeof(*cp
) ||
831 (nl
= (*cp
== '\n')) ||
832 (wp
[1] && any(*cp
, ifs
->value
)))
837 setval(lookup(*wp
), e
.linep
);
844 register struct op
*t
;
846 return(RUN(awordlist
, t
->words
+1, wdchar
));
851 register struct op
*t
;
854 register int resetsig
;
856 if (t
->words
[1] == NULL
) {
857 for (i
=0; i
<_NSIG
; i
++)
866 resetsig
= digit(*t
->words
[1]);
867 for (i
= resetsig
? 1 : 2; t
->words
[i
] != NULL
; ++i
) {
868 n
= getsig(t
->words
[i
]);
872 if (*t
->words
[1] != '\0') {
873 trap
[n
] = strsave(t
->words
[1], 0);
882 setsig(n
, n
== SIGQUIT
? SIG_IGN
897 if ((n
= getn(s
)) < 0 || n
>= _NSIG
) {
898 err("trap: bad signal number");
907 _PROTOTYPE(void (*f
), (int));
911 if (signal(n
, SIG_IGN
) != SIG_IGN
|| ourtrap
[n
]) {
930 for (n
= 0; digit(*s
); s
++)
931 n
= (n
*10) + (*s
-'0');
943 return(brkcontin(t
->words
[1], 1));
950 return(brkcontin(t
->words
[1], 0));
958 register struct brkcon
*bc
;
961 nl
= cp
== NULL
? 1: getn(cp
);
965 if ((bc
= brklist
) == NULL
)
967 brklist
= bc
->nextlev
;
970 err("bad break/continue level");
974 longjmp(bc
->brkpt
, 1);
985 if ((cp
= t
->words
[1]) != NULL
)
995 rdexp(t
->words
+1, export
, EXPORT
);
1003 rdexp(t
->words
+1, ronly
, RONLY
);
1014 for (; *wp
!= NULL
; wp
++)
1028 err(": bad identifier");
1033 register struct op
*t
;
1035 register struct var
*vp
;
1039 if ((cp
= t
->words
[1]) == NULL
) {
1040 for (vp
= vlist
; vp
; vp
= vp
->next
)
1041 varput(vp
->name
, 1);
1045 /* bad: t->words++; */
1046 for(n
= 0; (t
->words
[n
]=t
->words
[n
+1]) != NULL
; n
++)
1049 flag
['x'] = flag
['v'] = 0;
1059 if (*cp
>='a' && *cp
<='z')
1066 t
->words
[0] = dolv
[0];
1067 for (n
=1; t
->words
[n
]; n
++)
1068 setarea((char *)t
->words
[n
], 0);
1071 setval(lookup("#"), putn(dolc
));
1072 setarea((char *)(dolv
-1), 0);
1083 write(out
, s
, strlen(s
));
1084 write(out
, "\n", 1);
1099 prn((int)(tbuf
.tms_cutime
/ MINS
));
1101 prn((int)((tbuf
.tms_cutime
% MINS
) / SECS
));
1103 prn((int)(tbuf
.tms_cstime
/ MINS
));
1105 prn((int)((tbuf
.tms_cstime
% MINS
) / SECS
));
1114 static struct builtin builtin
[] = {
1124 "continue", docontinue
,
1127 "readonly", doreadonly
,
1140 register struct builtin
*bp
;
1142 for (bp
= builtin
; bp
->command
!= NULL
; bp
++)
1143 if (strcmp(bp
->command
, s
) == 0)
1145 return((int(*)())NULL
);