13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * Maybe `simple' is a misnomer.
33e12c5d1SDavid du Colombier */
43e12c5d1SDavid du Colombier #include "rc.h"
53e12c5d1SDavid du Colombier #include "getflags.h"
63e12c5d1SDavid du Colombier #include "exec.h"
73e12c5d1SDavid du Colombier #include "io.h"
83e12c5d1SDavid du Colombier #include "fns.h"
93e12c5d1SDavid du Colombier /*
103e12c5d1SDavid du Colombier * Search through the following code to see if we're just going to exit.
113e12c5d1SDavid du Colombier */
12d3907fe5SDavid du Colombier int
exitnext(void)1399eb86a7SDavid du Colombier exitnext(void){
143e12c5d1SDavid du Colombier union code *c=&runq->code[runq->pc];
1599eb86a7SDavid du Colombier while(c->f==Xpopredir) c++;
163e12c5d1SDavid du Colombier return c->f==Xexit;
173e12c5d1SDavid du Colombier }
18dc5a79c1SDavid du Colombier
19dc5a79c1SDavid du Colombier void
Xsimple(void)20dc5a79c1SDavid du Colombier Xsimple(void)
21dc5a79c1SDavid du Colombier {
223e12c5d1SDavid du Colombier word *a;
233e12c5d1SDavid du Colombier thread *p = runq;
243e12c5d1SDavid du Colombier var *v;
253e12c5d1SDavid du Colombier struct builtin *bp;
26dc5a79c1SDavid du Colombier int pid;
273e12c5d1SDavid du Colombier globlist();
283e12c5d1SDavid du Colombier a = runq->argv->words;
293e12c5d1SDavid du Colombier if(a==0){
309a747e4fSDavid du Colombier Xerror1("empty argument list");
313e12c5d1SDavid du Colombier return;
323e12c5d1SDavid du Colombier }
333e12c5d1SDavid du Colombier if(flag['x'])
343e12c5d1SDavid du Colombier pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */
353e12c5d1SDavid du Colombier v = gvlook(a->word);
363e12c5d1SDavid du Colombier if(v->fn)
373e12c5d1SDavid du Colombier execfunc(v);
383e12c5d1SDavid du Colombier else{
393e12c5d1SDavid du Colombier if(strcmp(a->word, "builtin")==0){
403e12c5d1SDavid du Colombier if(count(a)==1){
413e12c5d1SDavid du Colombier pfmt(err, "builtin: empty argument list\n");
423e12c5d1SDavid du Colombier setstatus("empty arg list");
433e12c5d1SDavid du Colombier poplist();
443e12c5d1SDavid du Colombier return;
453e12c5d1SDavid du Colombier }
463e12c5d1SDavid du Colombier a = a->next;
473e12c5d1SDavid du Colombier popword();
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier for(bp = Builtin;bp->name;bp++)
503e12c5d1SDavid du Colombier if(strcmp(a->word, bp->name)==0){
513e12c5d1SDavid du Colombier (*bp->fnc)();
523e12c5d1SDavid du Colombier return;
533e12c5d1SDavid du Colombier }
543e12c5d1SDavid du Colombier if(exitnext()){
553e12c5d1SDavid du Colombier /* fork and wait is redundant */
563e12c5d1SDavid du Colombier pushword("exec");
573e12c5d1SDavid du Colombier execexec();
583e12c5d1SDavid du Colombier Xexit();
593e12c5d1SDavid du Colombier }
603e12c5d1SDavid du Colombier else{
613e12c5d1SDavid du Colombier flush(err);
629a747e4fSDavid du Colombier Updenv(); /* necessary so changes don't go out again */
63dc5a79c1SDavid du Colombier if((pid = execforkexec()) < 0){
647dd7cddfSDavid du Colombier Xerror("try again");
653e12c5d1SDavid du Colombier return;
66dc5a79c1SDavid du Colombier }
67dc5a79c1SDavid du Colombier
683e12c5d1SDavid du Colombier /* interrupts don't get us out */
69dc5a79c1SDavid du Colombier poplist();
703e12c5d1SDavid du Colombier while(Waitfor(pid, 1) < 0)
713e12c5d1SDavid du Colombier ;
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier }
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier struct word nullpath = { "", 0};
76dc5a79c1SDavid du Colombier
77dc5a79c1SDavid du Colombier void
doredir(redir * rp)78dc5a79c1SDavid du Colombier doredir(redir *rp)
793e12c5d1SDavid du Colombier {
803e12c5d1SDavid du Colombier if(rp){
813e12c5d1SDavid du Colombier doredir(rp->next);
823e12c5d1SDavid du Colombier switch(rp->type){
833e12c5d1SDavid du Colombier case ROPEN:
843e12c5d1SDavid du Colombier if(rp->from!=rp->to){
853e12c5d1SDavid du Colombier Dup(rp->from, rp->to);
863e12c5d1SDavid du Colombier close(rp->from);
873e12c5d1SDavid du Colombier }
883e12c5d1SDavid du Colombier break;
89dc5a79c1SDavid du Colombier case RDUP:
90dc5a79c1SDavid du Colombier Dup(rp->from, rp->to);
91dc5a79c1SDavid du Colombier break;
92dc5a79c1SDavid du Colombier case RCLOSE:
93dc5a79c1SDavid du Colombier close(rp->from);
94dc5a79c1SDavid du Colombier break;
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier }
973e12c5d1SDavid du Colombier }
98dc5a79c1SDavid du Colombier
99dc5a79c1SDavid du Colombier word*
searchpath(char * w)100dc5a79c1SDavid du Colombier searchpath(char *w)
101dc5a79c1SDavid du Colombier {
1023e12c5d1SDavid du Colombier word *path;
1033e12c5d1SDavid du Colombier if(strncmp(w, "/", 1)==0
1043e12c5d1SDavid du Colombier || strncmp(w, "#", 1)==0
1053e12c5d1SDavid du Colombier || strncmp(w, "./", 2)==0
1063e12c5d1SDavid du Colombier || strncmp(w, "../", 3)==0
1073e12c5d1SDavid du Colombier || (path = vlook("path")->val)==0)
1083e12c5d1SDavid du Colombier path=&nullpath;
1093e12c5d1SDavid du Colombier return path;
1103e12c5d1SDavid du Colombier }
111dc5a79c1SDavid du Colombier
112dc5a79c1SDavid du Colombier void
execexec(void)113dc5a79c1SDavid du Colombier execexec(void)
114dc5a79c1SDavid du Colombier {
1153e12c5d1SDavid du Colombier popword(); /* "exec" */
1163e12c5d1SDavid du Colombier if(runq->argv->words==0){
1179a747e4fSDavid du Colombier Xerror1("empty argument list");
1183e12c5d1SDavid du Colombier return;
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier doredir(runq->redir);
1213e12c5d1SDavid du Colombier Execute(runq->argv->words, searchpath(runq->argv->words->word));
1223e12c5d1SDavid du Colombier poplist();
1233e12c5d1SDavid du Colombier }
124dc5a79c1SDavid du Colombier
125dc5a79c1SDavid du Colombier void
execfunc(var * func)126dc5a79c1SDavid du Colombier execfunc(var *func)
1273e12c5d1SDavid du Colombier {
1283e12c5d1SDavid du Colombier word *starval;
1293e12c5d1SDavid du Colombier popword();
1303e12c5d1SDavid du Colombier starval = runq->argv->words;
1313e12c5d1SDavid du Colombier runq->argv->words = 0;
1323e12c5d1SDavid du Colombier poplist();
1337c6618bfSDavid du Colombier start(func->fn, func->pc, runq->local);
1343e12c5d1SDavid du Colombier runq->local = newvar(strdup("*"), runq->local);
1353e12c5d1SDavid du Colombier runq->local->val = starval;
1363e12c5d1SDavid du Colombier runq->local->changed = 1;
1373e12c5d1SDavid du Colombier }
138dc5a79c1SDavid du Colombier
139dc5a79c1SDavid du Colombier int
dochdir(char * word)140dc5a79c1SDavid du Colombier dochdir(char *word)
141dc5a79c1SDavid du Colombier {
1427dd7cddfSDavid du Colombier /* report to /dev/wdir if it exists and we're interactive */
1437dd7cddfSDavid du Colombier static int wdirfd = -2;
1447dd7cddfSDavid du Colombier if(chdir(word)<0) return -1;
1457dd7cddfSDavid du Colombier if(flag['i']!=0){
1467dd7cddfSDavid du Colombier if(wdirfd==-2) /* try only once */
1477dd7cddfSDavid du Colombier wdirfd = open("/dev/wdir", OWRITE|OCEXEC);
148bad30d5dSDavid du Colombier if(wdirfd>=0) {
149bad30d5dSDavid du Colombier fcntl(wdirfd, F_SETFD, FD_CLOEXEC);
1507dd7cddfSDavid du Colombier write(wdirfd, word, strlen(word));
1517dd7cddfSDavid du Colombier }
152bad30d5dSDavid du Colombier }
1537dd7cddfSDavid du Colombier return 1;
1547dd7cddfSDavid du Colombier }
155dc5a79c1SDavid du Colombier
156bad30d5dSDavid du Colombier static char *
appfile(char * dir,char * comp)157bad30d5dSDavid du Colombier appfile(char *dir, char *comp)
158bad30d5dSDavid du Colombier {
159bad30d5dSDavid du Colombier int dirlen, complen;
160bad30d5dSDavid du Colombier char *s, *p;
161bad30d5dSDavid du Colombier
162bad30d5dSDavid du Colombier dirlen = strlen(dir);
163bad30d5dSDavid du Colombier complen = strlen(comp);
164bad30d5dSDavid du Colombier s = emalloc(dirlen + 1 + complen + 1);
165bad30d5dSDavid du Colombier memmove(s, dir, dirlen);
166bad30d5dSDavid du Colombier p = s + dirlen;
167bad30d5dSDavid du Colombier *p++ = '/';
168bad30d5dSDavid du Colombier memmove(p, comp, complen);
169bad30d5dSDavid du Colombier p[complen] = '\0';
170bad30d5dSDavid du Colombier return s;
171bad30d5dSDavid du Colombier }
172bad30d5dSDavid du Colombier
173dc5a79c1SDavid du Colombier void
execcd(void)174dc5a79c1SDavid du Colombier execcd(void)
175dc5a79c1SDavid du Colombier {
1763e12c5d1SDavid du Colombier word *a = runq->argv->words;
1773e12c5d1SDavid du Colombier word *cdpath;
178276e7d6dSDavid du Colombier char *dir;
179276e7d6dSDavid du Colombier
1803e12c5d1SDavid du Colombier setstatus("can't cd");
1813e12c5d1SDavid du Colombier cdpath = vlook("cdpath")->val;
1823e12c5d1SDavid du Colombier switch(count(a)){
1833e12c5d1SDavid du Colombier default:
1843e12c5d1SDavid du Colombier pfmt(err, "Usage: cd [directory]\n");
1853e12c5d1SDavid du Colombier break;
1863e12c5d1SDavid du Colombier case 2:
187dc5a79c1SDavid du Colombier if(a->next->word[0]=='/' || cdpath==0)
188dc5a79c1SDavid du Colombier cdpath = &nullpath;
1893e12c5d1SDavid du Colombier for(; cdpath; cdpath = cdpath->next){
190276e7d6dSDavid du Colombier if(cdpath->word[0] != '\0')
191bad30d5dSDavid du Colombier dir = appfile(cdpath->word, a->next->word);
192276e7d6dSDavid du Colombier else
193276e7d6dSDavid du Colombier dir = strdup(a->next->word);
194276e7d6dSDavid du Colombier
1957dd7cddfSDavid du Colombier if(dochdir(dir) >= 0){
196276e7d6dSDavid du Colombier if(cdpath->word[0] != '\0' &&
197276e7d6dSDavid du Colombier strcmp(cdpath->word, ".") != 0)
1983e12c5d1SDavid du Colombier pfmt(err, "%s\n", dir);
199276e7d6dSDavid du Colombier free(dir);
2003e12c5d1SDavid du Colombier setstatus("");
2013e12c5d1SDavid du Colombier break;
2023e12c5d1SDavid du Colombier }
203276e7d6dSDavid du Colombier free(dir);
2043e12c5d1SDavid du Colombier }
205dc5a79c1SDavid du Colombier if(cdpath==0)
206dc5a79c1SDavid du Colombier pfmt(err, "Can't cd %s: %r\n", a->next->word);
2073e12c5d1SDavid du Colombier break;
2083e12c5d1SDavid du Colombier case 1:
2093e12c5d1SDavid du Colombier a = vlook("home")->val;
2103e12c5d1SDavid du Colombier if(count(a)>=1){
2117dd7cddfSDavid du Colombier if(dochdir(a->word)>=0)
2123e12c5d1SDavid du Colombier setstatus("");
2133e12c5d1SDavid du Colombier else
2149a747e4fSDavid du Colombier pfmt(err, "Can't cd %s: %r\n", a->word);
2153e12c5d1SDavid du Colombier }
2163e12c5d1SDavid du Colombier else
2173e12c5d1SDavid du Colombier pfmt(err, "Can't cd -- $home empty\n");
2183e12c5d1SDavid du Colombier break;
2193e12c5d1SDavid du Colombier }
2203e12c5d1SDavid du Colombier poplist();
2213e12c5d1SDavid du Colombier }
222dc5a79c1SDavid du Colombier
223dc5a79c1SDavid du Colombier void
execexit(void)224dc5a79c1SDavid du Colombier execexit(void)
225dc5a79c1SDavid du Colombier {
2263e12c5d1SDavid du Colombier switch(count(runq->argv->words)){
227dc5a79c1SDavid du Colombier default:
228dc5a79c1SDavid du Colombier pfmt(err, "Usage: exit [status]\nExiting anyway\n");
229dc5a79c1SDavid du Colombier case 2:
230dc5a79c1SDavid du Colombier setstatus(runq->argv->words->next->word);
2313e12c5d1SDavid du Colombier case 1: Xexit();
2323e12c5d1SDavid du Colombier }
2333e12c5d1SDavid du Colombier }
234dc5a79c1SDavid du Colombier
235dc5a79c1SDavid du Colombier void
execshift(void)236dc5a79c1SDavid du Colombier execshift(void)
237dc5a79c1SDavid du Colombier {
2383e12c5d1SDavid du Colombier int n;
2393e12c5d1SDavid du Colombier word *a;
2403e12c5d1SDavid du Colombier var *star;
2413e12c5d1SDavid du Colombier switch(count(runq->argv->words)){
2423e12c5d1SDavid du Colombier default:
2433e12c5d1SDavid du Colombier pfmt(err, "Usage: shift [n]\n");
2443e12c5d1SDavid du Colombier setstatus("shift usage");
2453e12c5d1SDavid du Colombier poplist();
2463e12c5d1SDavid du Colombier return;
247dc5a79c1SDavid du Colombier case 2:
248dc5a79c1SDavid du Colombier n = atoi(runq->argv->words->next->word);
249dc5a79c1SDavid du Colombier break;
250dc5a79c1SDavid du Colombier case 1:
251dc5a79c1SDavid du Colombier n = 1;
252dc5a79c1SDavid du Colombier break;
2533e12c5d1SDavid du Colombier }
2543e12c5d1SDavid du Colombier star = vlook("*");
2553e12c5d1SDavid du Colombier for(;n && star->val;--n){
2563e12c5d1SDavid du Colombier a = star->val->next;
2573e12c5d1SDavid du Colombier efree(star->val->word);
2583e12c5d1SDavid du Colombier efree((char *)star->val);
2593e12c5d1SDavid du Colombier star->val = a;
2603e12c5d1SDavid du Colombier star->changed = 1;
2613e12c5d1SDavid du Colombier }
2623e12c5d1SDavid du Colombier setstatus("");
2633e12c5d1SDavid du Colombier poplist();
2643e12c5d1SDavid du Colombier }
265dc5a79c1SDavid du Colombier
266dc5a79c1SDavid du Colombier int
octal(char * s)267dc5a79c1SDavid du Colombier octal(char *s)
2683e12c5d1SDavid du Colombier {
2693e12c5d1SDavid du Colombier int n = 0;
2703e12c5d1SDavid du Colombier while(*s==' ' || *s=='\t' || *s=='\n') s++;
2713e12c5d1SDavid du Colombier while('0'<=*s && *s<='7') n = n*8+*s++-'0';
2723e12c5d1SDavid du Colombier return n;
2733e12c5d1SDavid du Colombier }
274dc5a79c1SDavid du Colombier
275dc5a79c1SDavid du Colombier int
mapfd(int fd)276dc5a79c1SDavid du Colombier mapfd(int fd)
2773e12c5d1SDavid du Colombier {
2783e12c5d1SDavid du Colombier redir *rp;
2793e12c5d1SDavid du Colombier for(rp = runq->redir;rp;rp = rp->next){
2803e12c5d1SDavid du Colombier switch(rp->type){
2813e12c5d1SDavid du Colombier case RCLOSE:
282dc5a79c1SDavid du Colombier if(rp->from==fd)
283dc5a79c1SDavid du Colombier fd=-1;
2843e12c5d1SDavid du Colombier break;
2853e12c5d1SDavid du Colombier case RDUP:
2863e12c5d1SDavid du Colombier case ROPEN:
287dc5a79c1SDavid du Colombier if(rp->to==fd)
288dc5a79c1SDavid du Colombier fd = rp->from;
2893e12c5d1SDavid du Colombier break;
2903e12c5d1SDavid du Colombier }
2913e12c5d1SDavid du Colombier }
2923e12c5d1SDavid du Colombier return fd;
2933e12c5d1SDavid du Colombier }
2943e12c5d1SDavid du Colombier union code rdcmds[4];
295dc5a79c1SDavid du Colombier
296dc5a79c1SDavid du Colombier void
execcmds(io * f)297dc5a79c1SDavid du Colombier execcmds(io *f)
2983e12c5d1SDavid du Colombier {
2993e12c5d1SDavid du Colombier static int first = 1;
3003e12c5d1SDavid du Colombier if(first){
3013e12c5d1SDavid du Colombier rdcmds[0].i = 1;
3023e12c5d1SDavid du Colombier rdcmds[1].f = Xrdcmds;
3033e12c5d1SDavid du Colombier rdcmds[2].f = Xreturn;
3043e12c5d1SDavid du Colombier first = 0;
3053e12c5d1SDavid du Colombier }
3063e12c5d1SDavid du Colombier start(rdcmds, 1, runq->local);
3073e12c5d1SDavid du Colombier runq->cmdfd = f;
3083e12c5d1SDavid du Colombier runq->iflast = 0;
3093e12c5d1SDavid du Colombier }
310dc5a79c1SDavid du Colombier
311dc5a79c1SDavid du Colombier void
execeval(void)312dc5a79c1SDavid du Colombier execeval(void)
313dc5a79c1SDavid du Colombier {
3143e12c5d1SDavid du Colombier char *cmdline, *s, *t;
3153e12c5d1SDavid du Colombier int len = 0;
3163e12c5d1SDavid du Colombier word *ap;
3173e12c5d1SDavid du Colombier if(count(runq->argv->words)<=1){
3189a747e4fSDavid du Colombier Xerror1("Usage: eval cmd ...");
3193e12c5d1SDavid du Colombier return;
3203e12c5d1SDavid du Colombier }
321219b2ee8SDavid du Colombier eflagok = 1;
3223e12c5d1SDavid du Colombier for(ap = runq->argv->words->next;ap;ap = ap->next)
3233e12c5d1SDavid du Colombier len+=1+strlen(ap->word);
3243e12c5d1SDavid du Colombier cmdline = emalloc(len);
3253e12c5d1SDavid du Colombier s = cmdline;
3263e12c5d1SDavid du Colombier for(ap = runq->argv->words->next;ap;ap = ap->next){
3273e12c5d1SDavid du Colombier for(t = ap->word;*t;) *s++=*t++;
3283e12c5d1SDavid du Colombier *s++=' ';
3293e12c5d1SDavid du Colombier }
3303e12c5d1SDavid du Colombier s[-1]='\n';
3313e12c5d1SDavid du Colombier poplist();
3323e12c5d1SDavid du Colombier execcmds(opencore(cmdline, len));
3333e12c5d1SDavid du Colombier efree(cmdline);
3343e12c5d1SDavid du Colombier }
3353e12c5d1SDavid du Colombier union code dotcmds[14];
336dc5a79c1SDavid du Colombier
337dc5a79c1SDavid du Colombier void
execdot(void)338dc5a79c1SDavid du Colombier execdot(void)
339dc5a79c1SDavid du Colombier {
3403e12c5d1SDavid du Colombier int iflag = 0;
3413e12c5d1SDavid du Colombier int fd;
3423e12c5d1SDavid du Colombier list *av;
3433e12c5d1SDavid du Colombier thread *p = runq;
344276e7d6dSDavid du Colombier char *zero, *file;
3453e12c5d1SDavid du Colombier word *path;
346276e7d6dSDavid du Colombier static int first = 1;
347276e7d6dSDavid du Colombier
3483e12c5d1SDavid du Colombier if(first){
3493e12c5d1SDavid du Colombier dotcmds[0].i = 1;
3503e12c5d1SDavid du Colombier dotcmds[1].f = Xmark;
3513e12c5d1SDavid du Colombier dotcmds[2].f = Xword;
3523e12c5d1SDavid du Colombier dotcmds[3].s="0";
3533e12c5d1SDavid du Colombier dotcmds[4].f = Xlocal;
3543e12c5d1SDavid du Colombier dotcmds[5].f = Xmark;
3553e12c5d1SDavid du Colombier dotcmds[6].f = Xword;
3563e12c5d1SDavid du Colombier dotcmds[7].s="*";
3573e12c5d1SDavid du Colombier dotcmds[8].f = Xlocal;
3583e12c5d1SDavid du Colombier dotcmds[9].f = Xrdcmds;
3593e12c5d1SDavid du Colombier dotcmds[10].f = Xunlocal;
3603e12c5d1SDavid du Colombier dotcmds[11].f = Xunlocal;
3613e12c5d1SDavid du Colombier dotcmds[12].f = Xreturn;
3623e12c5d1SDavid du Colombier first = 0;
3633e12c5d1SDavid du Colombier }
364219b2ee8SDavid du Colombier else
365219b2ee8SDavid du Colombier eflagok = 1;
3663e12c5d1SDavid du Colombier popword();
3673e12c5d1SDavid du Colombier if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){
3683e12c5d1SDavid du Colombier iflag = 1;
3693e12c5d1SDavid du Colombier popword();
3703e12c5d1SDavid du Colombier }
3713e12c5d1SDavid du Colombier /* get input file */
3723e12c5d1SDavid du Colombier if(p->argv->words==0){
3739a747e4fSDavid du Colombier Xerror1("Usage: . [-i] file [arg ...]");
3743e12c5d1SDavid du Colombier return;
3753e12c5d1SDavid du Colombier }
3763e12c5d1SDavid du Colombier zero = strdup(p->argv->words->word);
3773e12c5d1SDavid du Colombier popword();
3787dd7cddfSDavid du Colombier fd = -1;
3793e12c5d1SDavid du Colombier for(path = searchpath(zero); path; path = path->next){
380276e7d6dSDavid du Colombier if(path->word[0] != '\0')
381bad30d5dSDavid du Colombier file = appfile(path->word, zero);
382276e7d6dSDavid du Colombier else
383276e7d6dSDavid du Colombier file = strdup(zero);
384276e7d6dSDavid du Colombier
385276e7d6dSDavid du Colombier fd = open(file, 0);
386276e7d6dSDavid du Colombier free(file);
387276e7d6dSDavid du Colombier if(fd >= 0)
388276e7d6dSDavid du Colombier break;
3893e12c5d1SDavid du Colombier if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */
3903e12c5d1SDavid du Colombier fd = Dup1(0);
391dc5a79c1SDavid du Colombier if(fd>=0)
392dc5a79c1SDavid du Colombier break;
3933e12c5d1SDavid du Colombier }
3943e12c5d1SDavid du Colombier }
3953e12c5d1SDavid du Colombier if(fd<0){
3967dd7cddfSDavid du Colombier pfmt(err, "%s: ", zero);
3977dd7cddfSDavid du Colombier setstatus("can't open");
3987dd7cddfSDavid du Colombier Xerror(".: can't open");
3993e12c5d1SDavid du Colombier return;
4003e12c5d1SDavid du Colombier }
4013e12c5d1SDavid du Colombier /* set up for a new command loop */
4023e12c5d1SDavid du Colombier start(dotcmds, 1, (struct var *)0);
4033e12c5d1SDavid du Colombier pushredir(RCLOSE, fd, 0);
4043e12c5d1SDavid du Colombier runq->cmdfile = zero;
4053e12c5d1SDavid du Colombier runq->cmdfd = openfd(fd);
4063e12c5d1SDavid du Colombier runq->iflag = iflag;
4073e12c5d1SDavid du Colombier runq->iflast = 0;
4083e12c5d1SDavid du Colombier /* push $* value */
4093e12c5d1SDavid du Colombier pushlist();
4103e12c5d1SDavid du Colombier runq->argv->words = p->argv->words;
4113e12c5d1SDavid du Colombier /* free caller's copy of $* */
4123e12c5d1SDavid du Colombier av = p->argv;
4133e12c5d1SDavid du Colombier p->argv = av->next;
4143e12c5d1SDavid du Colombier efree((char *)av);
4153e12c5d1SDavid du Colombier /* push $0 value */
4163e12c5d1SDavid du Colombier pushlist();
4173e12c5d1SDavid du Colombier pushword(zero);
4183e12c5d1SDavid du Colombier ndot++;
4193e12c5d1SDavid du Colombier }
420dc5a79c1SDavid du Colombier
421dc5a79c1SDavid du Colombier void
execflag(void)422dc5a79c1SDavid du Colombier execflag(void)
423dc5a79c1SDavid du Colombier {
4243e12c5d1SDavid du Colombier char *letter, *val;
4253e12c5d1SDavid du Colombier switch(count(runq->argv->words)){
4263e12c5d1SDavid du Colombier case 2:
427d3907fe5SDavid du Colombier setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set");
4283e12c5d1SDavid du Colombier break;
4293e12c5d1SDavid du Colombier case 3:
4303e12c5d1SDavid du Colombier letter = runq->argv->words->next->word;
4313e12c5d1SDavid du Colombier val = runq->argv->words->next->next->word;
4323e12c5d1SDavid du Colombier if(strlen(letter)==1){
4333e12c5d1SDavid du Colombier if(strcmp(val, "+")==0){
434d3907fe5SDavid du Colombier flag[(uchar)letter[0]] = flagset;
4353e12c5d1SDavid du Colombier break;
4363e12c5d1SDavid du Colombier }
4373e12c5d1SDavid du Colombier if(strcmp(val, "-")==0){
438d3907fe5SDavid du Colombier flag[(uchar)letter[0]] = 0;
4393e12c5d1SDavid du Colombier break;
4403e12c5d1SDavid du Colombier }
4413e12c5d1SDavid du Colombier }
4423e12c5d1SDavid du Colombier default:
4439a747e4fSDavid du Colombier Xerror1("Usage: flag [letter] [+-]");
4443e12c5d1SDavid du Colombier return;
4453e12c5d1SDavid du Colombier }
4463e12c5d1SDavid du Colombier poplist();
4473e12c5d1SDavid du Colombier }
448dc5a79c1SDavid du Colombier
449dc5a79c1SDavid du Colombier void
execwhatis(void)45099eb86a7SDavid du Colombier execwhatis(void){ /* mildly wrong -- should fork before writing */
4513e12c5d1SDavid du Colombier word *a, *b, *path;
4523e12c5d1SDavid du Colombier var *v;
4533e12c5d1SDavid du Colombier struct builtin *bp;
454276e7d6dSDavid du Colombier char *file;
4553e12c5d1SDavid du Colombier struct io out[1];
4563e12c5d1SDavid du Colombier int found, sep;
4573e12c5d1SDavid du Colombier a = runq->argv->words->next;
4583e12c5d1SDavid du Colombier if(a==0){
4599a747e4fSDavid du Colombier Xerror1("Usage: whatis name ...");
4603e12c5d1SDavid du Colombier return;
4613e12c5d1SDavid du Colombier }
4623e12c5d1SDavid du Colombier setstatus("");
463*4e3613abSDavid du Colombier memset(out, 0, sizeof out);
4643e12c5d1SDavid du Colombier out->fd = mapfd(1);
4653e12c5d1SDavid du Colombier out->bufp = out->buf;
4663e12c5d1SDavid du Colombier out->ebuf = &out->buf[NBUF];
4673e12c5d1SDavid du Colombier out->strp = 0;
4683e12c5d1SDavid du Colombier for(;a;a = a->next){
4693e12c5d1SDavid du Colombier v = vlook(a->word);
4703e12c5d1SDavid du Colombier if(v->val){
4713e12c5d1SDavid du Colombier pfmt(out, "%s=", a->word);
4723e12c5d1SDavid du Colombier if(v->val->next==0)
4733e12c5d1SDavid du Colombier pfmt(out, "%q\n", v->val->word);
4743e12c5d1SDavid du Colombier else{
4753e12c5d1SDavid du Colombier sep='(';
4763e12c5d1SDavid du Colombier for(b = v->val;b && b->word;b = b->next){
4773e12c5d1SDavid du Colombier pfmt(out, "%c%q", sep, b->word);
4783e12c5d1SDavid du Colombier sep=' ';
4793e12c5d1SDavid du Colombier }
4803e12c5d1SDavid du Colombier pfmt(out, ")\n");
4813e12c5d1SDavid du Colombier }
4823e12c5d1SDavid du Colombier found = 1;
4833e12c5d1SDavid du Colombier }
4843e12c5d1SDavid du Colombier else
4853e12c5d1SDavid du Colombier found = 0;
4863e12c5d1SDavid du Colombier v = gvlook(a->word);
487dc5a79c1SDavid du Colombier if(v->fn)
488fed0fa9eSDavid du Colombier pfmt(out, "fn %q %s\n", v->name, v->fn[v->pc-1].s);
4893e12c5d1SDavid du Colombier else{
4903e12c5d1SDavid du Colombier for(bp = Builtin;bp->name;bp++)
4913e12c5d1SDavid du Colombier if(strcmp(a->word, bp->name)==0){
4923e12c5d1SDavid du Colombier pfmt(out, "builtin %s\n", a->word);
4933e12c5d1SDavid du Colombier break;
4943e12c5d1SDavid du Colombier }
4953e12c5d1SDavid du Colombier if(!bp->name){
496276e7d6dSDavid du Colombier for(path = searchpath(a->word); path;
497276e7d6dSDavid du Colombier path = path->next){
498276e7d6dSDavid du Colombier if(path->word[0] != '\0')
499bad30d5dSDavid du Colombier file = appfile(path->word,
500bad30d5dSDavid du Colombier a->word);
501276e7d6dSDavid du Colombier else
502276e7d6dSDavid du Colombier file = strdup(a->word);
5033e12c5d1SDavid du Colombier if(Executable(file)){
5043e12c5d1SDavid du Colombier pfmt(out, "%s\n", file);
505276e7d6dSDavid du Colombier free(file);
5063e12c5d1SDavid du Colombier break;
5073e12c5d1SDavid du Colombier }
508276e7d6dSDavid du Colombier free(file);
5093e12c5d1SDavid du Colombier }
5103e12c5d1SDavid du Colombier if(!path && !found){
5113e12c5d1SDavid du Colombier pfmt(err, "%s: not found\n", a->word);
5123e12c5d1SDavid du Colombier setstatus("not found");
5133e12c5d1SDavid du Colombier }
5143e12c5d1SDavid du Colombier }
5153e12c5d1SDavid du Colombier }
5163e12c5d1SDavid du Colombier }
5173e12c5d1SDavid du Colombier poplist();
5183e12c5d1SDavid du Colombier flush(err);
5193e12c5d1SDavid du Colombier }
520dc5a79c1SDavid du Colombier
521dc5a79c1SDavid du Colombier void
execwait(void)522dc5a79c1SDavid du Colombier execwait(void)
523dc5a79c1SDavid du Colombier {
5243e12c5d1SDavid du Colombier switch(count(runq->argv->words)){
525dc5a79c1SDavid du Colombier default:
526dc5a79c1SDavid du Colombier Xerror1("Usage: wait [pid]");
527dc5a79c1SDavid du Colombier return;
528dc5a79c1SDavid du Colombier case 2:
529dc5a79c1SDavid du Colombier Waitfor(atoi(runq->argv->words->next->word), 0);
530dc5a79c1SDavid du Colombier break;
531dc5a79c1SDavid du Colombier case 1:
532dc5a79c1SDavid du Colombier Waitfor(-1, 0);
533dc5a79c1SDavid du Colombier break;
5343e12c5d1SDavid du Colombier }
535219b2ee8SDavid du Colombier poplist();
5363e12c5d1SDavid du Colombier }
537