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 */ 123e12c5d1SDavid du Colombier exitnext(void){ 133e12c5d1SDavid du Colombier union code *c=&runq->code[runq->pc]; 143e12c5d1SDavid du Colombier while(c->f==Xpopredir) c++; 153e12c5d1SDavid du Colombier return c->f==Xexit; 163e12c5d1SDavid du Colombier } 173e12c5d1SDavid du Colombier void Xsimple(void){ 183e12c5d1SDavid du Colombier word *a; 193e12c5d1SDavid du Colombier thread *p=runq; 203e12c5d1SDavid du Colombier var *v; 213e12c5d1SDavid du Colombier struct builtin *bp; 223e12c5d1SDavid du Colombier int pid; 233e12c5d1SDavid du Colombier globlist(); 243e12c5d1SDavid du Colombier a=runq->argv->words; 253e12c5d1SDavid du Colombier if(a==0){ 263e12c5d1SDavid du Colombier Xerror("empty argument list"); 273e12c5d1SDavid du Colombier return; 283e12c5d1SDavid du Colombier } 293e12c5d1SDavid du Colombier if(flag['x']) 303e12c5d1SDavid du Colombier pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */ 313e12c5d1SDavid du Colombier v=gvlook(a->word); 323e12c5d1SDavid du Colombier if(v->fn) 333e12c5d1SDavid du Colombier execfunc(v); 343e12c5d1SDavid du Colombier else{ 353e12c5d1SDavid du Colombier if(strcmp(a->word, "builtin")==0){ 363e12c5d1SDavid du Colombier if(count(a)==1){ 373e12c5d1SDavid du Colombier pfmt(err, "builtin: empty argument list\n"); 383e12c5d1SDavid du Colombier setstatus("empty arg list"); 393e12c5d1SDavid du Colombier poplist(); 403e12c5d1SDavid du Colombier return; 413e12c5d1SDavid du Colombier } 423e12c5d1SDavid du Colombier a=a->next; 433e12c5d1SDavid du Colombier popword(); 443e12c5d1SDavid du Colombier } 453e12c5d1SDavid du Colombier for(bp=Builtin;bp->name;bp++) 463e12c5d1SDavid du Colombier if(strcmp(a->word, bp->name)==0){ 473e12c5d1SDavid du Colombier (*bp->fnc)(); 483e12c5d1SDavid du Colombier return; 493e12c5d1SDavid du Colombier } 503e12c5d1SDavid du Colombier if(exitnext()){ 513e12c5d1SDavid du Colombier /* fork and wait is redundant */ 523e12c5d1SDavid du Colombier pushword("exec"); 533e12c5d1SDavid du Colombier execexec(); 543e12c5d1SDavid du Colombier Xexit(); 553e12c5d1SDavid du Colombier } 563e12c5d1SDavid du Colombier else{ 573e12c5d1SDavid du Colombier flush(err); 583e12c5d1SDavid du Colombier Updenv(); 593e12c5d1SDavid du Colombier switch(pid=fork()){ 603e12c5d1SDavid du Colombier case -1: 61*219b2ee8SDavid du Colombier Xperror("try again"); 623e12c5d1SDavid du Colombier return; 633e12c5d1SDavid du Colombier case 0: 643e12c5d1SDavid du Colombier pushword("exec"); 653e12c5d1SDavid du Colombier execexec(); 663e12c5d1SDavid du Colombier Exit("can't exec"); 673e12c5d1SDavid du Colombier default: 683e12c5d1SDavid du Colombier poplist(); 693e12c5d1SDavid du Colombier /* interrupts don't get us out */ 703e12c5d1SDavid du Colombier while(Waitfor(pid, 1) < 0) 713e12c5d1SDavid du Colombier ; 723e12c5d1SDavid du Colombier } 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier } 753e12c5d1SDavid du Colombier } 763e12c5d1SDavid du Colombier struct word nullpath={ "", 0}; 773e12c5d1SDavid du Colombier void doredir(redir *rp) 783e12c5d1SDavid du Colombier { 793e12c5d1SDavid du Colombier if(rp){ 803e12c5d1SDavid du Colombier doredir(rp->next); 813e12c5d1SDavid du Colombier switch(rp->type){ 823e12c5d1SDavid du Colombier case ROPEN: 833e12c5d1SDavid du Colombier if(rp->from!=rp->to){ 843e12c5d1SDavid du Colombier Dup(rp->from, rp->to); 853e12c5d1SDavid du Colombier close(rp->from); 863e12c5d1SDavid du Colombier } 873e12c5d1SDavid du Colombier break; 883e12c5d1SDavid du Colombier case RDUP: Dup(rp->from, rp->to); break; 893e12c5d1SDavid du Colombier case RCLOSE: close(rp->from); break; 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier } 933e12c5d1SDavid du Colombier word *searchpath(char *w){ 943e12c5d1SDavid du Colombier word *path; 953e12c5d1SDavid du Colombier if(strncmp(w, "/", 1)==0 963e12c5d1SDavid du Colombier || strncmp(w, "#", 1)==0 973e12c5d1SDavid du Colombier || strncmp(w, "./", 2)==0 983e12c5d1SDavid du Colombier || strncmp(w, "../", 3)==0 993e12c5d1SDavid du Colombier || (path=vlook("path")->val)==0) 1003e12c5d1SDavid du Colombier path=&nullpath; 1013e12c5d1SDavid du Colombier return path; 1023e12c5d1SDavid du Colombier } 1033e12c5d1SDavid du Colombier void execexec(void){ 1043e12c5d1SDavid du Colombier word *path; 1053e12c5d1SDavid du Colombier popword(); /* "exec" */ 1063e12c5d1SDavid du Colombier if(runq->argv->words==0){ 1073e12c5d1SDavid du Colombier Xerror("empty argument list"); 1083e12c5d1SDavid du Colombier return; 1093e12c5d1SDavid du Colombier } 1103e12c5d1SDavid du Colombier doredir(runq->redir); 1113e12c5d1SDavid du Colombier Execute(runq->argv->words, searchpath(runq->argv->words->word)); 1123e12c5d1SDavid du Colombier poplist(); 1133e12c5d1SDavid du Colombier } 1143e12c5d1SDavid du Colombier void execfunc(var *func) 1153e12c5d1SDavid du Colombier { 1163e12c5d1SDavid du Colombier word *starval; 1173e12c5d1SDavid du Colombier popword(); 1183e12c5d1SDavid du Colombier starval=runq->argv->words; 1193e12c5d1SDavid du Colombier runq->argv->words=0; 1203e12c5d1SDavid du Colombier poplist(); 1213e12c5d1SDavid du Colombier start(func->fn, func->pc, (struct var *)0); 1223e12c5d1SDavid du Colombier runq->local=newvar(strdup("*"), runq->local); 1233e12c5d1SDavid du Colombier runq->local->val=starval; 1243e12c5d1SDavid du Colombier runq->local->changed=1; 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier void execcd(void){ 1273e12c5d1SDavid du Colombier word *a=runq->argv->words; 1283e12c5d1SDavid du Colombier word *cdpath; 1293e12c5d1SDavid du Colombier char dir[512]; 1303e12c5d1SDavid du Colombier setstatus("can't cd"); 1313e12c5d1SDavid du Colombier cdpath=vlook("cdpath")->val; 1323e12c5d1SDavid du Colombier switch(count(a)){ 1333e12c5d1SDavid du Colombier default: 1343e12c5d1SDavid du Colombier pfmt(err, "Usage: cd [directory]\n"); 1353e12c5d1SDavid du Colombier break; 1363e12c5d1SDavid du Colombier case 2: 1373e12c5d1SDavid du Colombier if(a->next->word[0]=='/' || cdpath==0) cdpath=&nullpath; 1383e12c5d1SDavid du Colombier for(;cdpath;cdpath=cdpath->next){ 1393e12c5d1SDavid du Colombier strcpy(dir, cdpath->word); 1403e12c5d1SDavid du Colombier if(dir[0]) strcat(dir, "/"); 1413e12c5d1SDavid du Colombier strcat(dir, a->next->word); 1423e12c5d1SDavid du Colombier if(chdir(dir)>=0){ 1433e12c5d1SDavid du Colombier if(strlen(cdpath->word) 1443e12c5d1SDavid du Colombier && strcmp(cdpath->word, ".")!=0) 1453e12c5d1SDavid du Colombier pfmt(err, "%s\n", dir); 1463e12c5d1SDavid du Colombier setstatus(""); 1473e12c5d1SDavid du Colombier break; 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier } 1503e12c5d1SDavid du Colombier if(cdpath==0) pfmt(err, "Can't cd %s\n", a->next->word); 1513e12c5d1SDavid du Colombier break; 1523e12c5d1SDavid du Colombier case 1: 1533e12c5d1SDavid du Colombier a=vlook("home")->val; 1543e12c5d1SDavid du Colombier if(count(a)>=1){ 1553e12c5d1SDavid du Colombier if(chdir(a->word)>=0) 1563e12c5d1SDavid du Colombier setstatus(""); 1573e12c5d1SDavid du Colombier else 1583e12c5d1SDavid du Colombier pfmt(err, "Can't cd %s\n", a->word); 1593e12c5d1SDavid du Colombier } 1603e12c5d1SDavid du Colombier else 1613e12c5d1SDavid du Colombier pfmt(err, "Can't cd -- $home empty\n"); 1623e12c5d1SDavid du Colombier break; 1633e12c5d1SDavid du Colombier } 1643e12c5d1SDavid du Colombier poplist(); 1653e12c5d1SDavid du Colombier } 1663e12c5d1SDavid du Colombier void execexit(void){ 1673e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 1683e12c5d1SDavid du Colombier default: pfmt(err, "Usage: exit [status]\nExiting anyway\n"); 1693e12c5d1SDavid du Colombier case 2: setstatus(runq->argv->words->next->word); 1703e12c5d1SDavid du Colombier case 1: Xexit(); 1713e12c5d1SDavid du Colombier } 1723e12c5d1SDavid du Colombier } 1733e12c5d1SDavid du Colombier void execshift(void){ 1743e12c5d1SDavid du Colombier int n; 1753e12c5d1SDavid du Colombier word *a; 1763e12c5d1SDavid du Colombier var *star; 1773e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 1783e12c5d1SDavid du Colombier default: 1793e12c5d1SDavid du Colombier pfmt(err, "Usage: shift [n]\n"); 1803e12c5d1SDavid du Colombier setstatus("shift usage"); 1813e12c5d1SDavid du Colombier poplist(); 1823e12c5d1SDavid du Colombier return; 1833e12c5d1SDavid du Colombier case 2: n=atoi(runq->argv->words->next->word); break; 1843e12c5d1SDavid du Colombier case 1: n=1; break; 1853e12c5d1SDavid du Colombier } 1863e12c5d1SDavid du Colombier star=vlook("*"); 1873e12c5d1SDavid du Colombier for(;n && star->val;--n){ 1883e12c5d1SDavid du Colombier a=star->val->next; 1893e12c5d1SDavid du Colombier efree(star->val->word); 1903e12c5d1SDavid du Colombier efree((char *)star->val); 1913e12c5d1SDavid du Colombier star->val=a; 1923e12c5d1SDavid du Colombier star->changed=1; 1933e12c5d1SDavid du Colombier } 1943e12c5d1SDavid du Colombier setstatus(""); 1953e12c5d1SDavid du Colombier poplist(); 1963e12c5d1SDavid du Colombier } 1973e12c5d1SDavid du Colombier int octal(char *s) 1983e12c5d1SDavid du Colombier { 1993e12c5d1SDavid du Colombier int n=0; 2003e12c5d1SDavid du Colombier while(*s==' ' || *s=='\t' || *s=='\n') s++; 2013e12c5d1SDavid du Colombier while('0'<=*s && *s<='7') n=n*8+*s++-'0'; 2023e12c5d1SDavid du Colombier return n; 2033e12c5d1SDavid du Colombier } 2043e12c5d1SDavid du Colombier int mapfd(int fd) 2053e12c5d1SDavid du Colombier { 2063e12c5d1SDavid du Colombier redir *rp; 2073e12c5d1SDavid du Colombier for(rp=runq->redir;rp;rp=rp->next){ 2083e12c5d1SDavid du Colombier switch(rp->type){ 2093e12c5d1SDavid du Colombier case RCLOSE: 2103e12c5d1SDavid du Colombier if(rp->from==fd) fd=-1; 2113e12c5d1SDavid du Colombier break; 2123e12c5d1SDavid du Colombier case RDUP: 2133e12c5d1SDavid du Colombier case ROPEN: 2143e12c5d1SDavid du Colombier if(rp->to==fd) fd=rp->from; 2153e12c5d1SDavid du Colombier break; 2163e12c5d1SDavid du Colombier } 2173e12c5d1SDavid du Colombier } 2183e12c5d1SDavid du Colombier return fd; 2193e12c5d1SDavid du Colombier } 2203e12c5d1SDavid du Colombier union code rdcmds[4]; 2213e12c5d1SDavid du Colombier void execcmds(io *f) 2223e12c5d1SDavid du Colombier { 2233e12c5d1SDavid du Colombier static int first=1; 2243e12c5d1SDavid du Colombier if(first){ 2253e12c5d1SDavid du Colombier rdcmds[0].i=1; 2263e12c5d1SDavid du Colombier rdcmds[1].f=Xrdcmds; 2273e12c5d1SDavid du Colombier rdcmds[2].f=Xreturn; 2283e12c5d1SDavid du Colombier first=0; 2293e12c5d1SDavid du Colombier } 2303e12c5d1SDavid du Colombier start(rdcmds, 1, runq->local); 2313e12c5d1SDavid du Colombier runq->cmdfd=f; 2323e12c5d1SDavid du Colombier runq->iflast=0; 2333e12c5d1SDavid du Colombier } 2343e12c5d1SDavid du Colombier void execeval(void){ 2353e12c5d1SDavid du Colombier char *cmdline, *s, *t; 2363e12c5d1SDavid du Colombier int len=0; 2373e12c5d1SDavid du Colombier word *ap; 2383e12c5d1SDavid du Colombier if(count(runq->argv->words)<=1){ 2393e12c5d1SDavid du Colombier Xerror("Usage: eval cmd ..."); 2403e12c5d1SDavid du Colombier return; 2413e12c5d1SDavid du Colombier } 242*219b2ee8SDavid du Colombier eflagok=1; 2433e12c5d1SDavid du Colombier for(ap=runq->argv->words->next;ap;ap=ap->next) 2443e12c5d1SDavid du Colombier len+=1+strlen(ap->word); 2453e12c5d1SDavid du Colombier cmdline=emalloc(len); 2463e12c5d1SDavid du Colombier s=cmdline; 2473e12c5d1SDavid du Colombier for(ap=runq->argv->words->next;ap;ap=ap->next){ 2483e12c5d1SDavid du Colombier for(t=ap->word;*t;) *s++=*t++; 2493e12c5d1SDavid du Colombier *s++=' '; 2503e12c5d1SDavid du Colombier } 2513e12c5d1SDavid du Colombier s[-1]='\n'; 2523e12c5d1SDavid du Colombier poplist(); 2533e12c5d1SDavid du Colombier execcmds(opencore(cmdline, len)); 2543e12c5d1SDavid du Colombier efree(cmdline); 2553e12c5d1SDavid du Colombier } 2563e12c5d1SDavid du Colombier union code dotcmds[14]; 2573e12c5d1SDavid du Colombier void execdot(void){ 2583e12c5d1SDavid du Colombier int iflag=0; 2593e12c5d1SDavid du Colombier int fd; 2603e12c5d1SDavid du Colombier list *av; 2613e12c5d1SDavid du Colombier thread *p=runq; 2623e12c5d1SDavid du Colombier char *zero; 2633e12c5d1SDavid du Colombier static int first=1; 2643e12c5d1SDavid du Colombier char file[512]; 2653e12c5d1SDavid du Colombier word *path; 2663e12c5d1SDavid du Colombier if(first){ 2673e12c5d1SDavid du Colombier dotcmds[0].i=1; 2683e12c5d1SDavid du Colombier dotcmds[1].f=Xmark; 2693e12c5d1SDavid du Colombier dotcmds[2].f=Xword; 2703e12c5d1SDavid du Colombier dotcmds[3].s="0"; 2713e12c5d1SDavid du Colombier dotcmds[4].f=Xlocal; 2723e12c5d1SDavid du Colombier dotcmds[5].f=Xmark; 2733e12c5d1SDavid du Colombier dotcmds[6].f=Xword; 2743e12c5d1SDavid du Colombier dotcmds[7].s="*"; 2753e12c5d1SDavid du Colombier dotcmds[8].f=Xlocal; 2763e12c5d1SDavid du Colombier dotcmds[9].f=Xrdcmds; 2773e12c5d1SDavid du Colombier dotcmds[10].f=Xunlocal; 2783e12c5d1SDavid du Colombier dotcmds[11].f=Xunlocal; 2793e12c5d1SDavid du Colombier dotcmds[12].f=Xreturn; 2803e12c5d1SDavid du Colombier first=0; 2813e12c5d1SDavid du Colombier } 282*219b2ee8SDavid du Colombier else 283*219b2ee8SDavid du Colombier eflagok=1; 2843e12c5d1SDavid du Colombier popword(); 2853e12c5d1SDavid du Colombier if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ 2863e12c5d1SDavid du Colombier iflag=1; 2873e12c5d1SDavid du Colombier popword(); 2883e12c5d1SDavid du Colombier } 2893e12c5d1SDavid du Colombier /* get input file */ 2903e12c5d1SDavid du Colombier if(p->argv->words==0){ 2913e12c5d1SDavid du Colombier Xerror("Usage: . [-i] file [arg ...]"); 2923e12c5d1SDavid du Colombier return; 2933e12c5d1SDavid du Colombier } 2943e12c5d1SDavid du Colombier zero=strdup(p->argv->words->word); 2953e12c5d1SDavid du Colombier popword(); 296*219b2ee8SDavid du Colombier strcpy(file, "**No file name**"); 2973e12c5d1SDavid du Colombier for(path=searchpath(zero);path;path=path->next){ 2983e12c5d1SDavid du Colombier strcpy(file, path->word); 2993e12c5d1SDavid du Colombier if(file[0]) strcat(file, "/"); 3003e12c5d1SDavid du Colombier strcat(file, zero); 3013e12c5d1SDavid du Colombier if((fd=open(file, 0))>=0) break; 3023e12c5d1SDavid du Colombier if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */ 3033e12c5d1SDavid du Colombier fd=Dup1(0); 3043e12c5d1SDavid du Colombier if(fd>=0) break; 3053e12c5d1SDavid du Colombier } 3063e12c5d1SDavid du Colombier } 3073e12c5d1SDavid du Colombier if(fd<0){ 308*219b2ee8SDavid du Colombier Xperror(file); 3093e12c5d1SDavid du Colombier return; 3103e12c5d1SDavid du Colombier } 3113e12c5d1SDavid du Colombier /* set up for a new command loop */ 3123e12c5d1SDavid du Colombier start(dotcmds, 1, (struct var *)0); 3133e12c5d1SDavid du Colombier pushredir(RCLOSE, fd, 0); 3143e12c5d1SDavid du Colombier runq->cmdfile=zero; 3153e12c5d1SDavid du Colombier runq->cmdfd=openfd(fd); 3163e12c5d1SDavid du Colombier runq->iflag=iflag; 3173e12c5d1SDavid du Colombier runq->iflast=0; 3183e12c5d1SDavid du Colombier /* push $* value */ 3193e12c5d1SDavid du Colombier pushlist(); 3203e12c5d1SDavid du Colombier runq->argv->words=p->argv->words; 3213e12c5d1SDavid du Colombier /* free caller's copy of $* */ 3223e12c5d1SDavid du Colombier av=p->argv; 3233e12c5d1SDavid du Colombier p->argv=av->next; 3243e12c5d1SDavid du Colombier efree((char *)av); 3253e12c5d1SDavid du Colombier /* push $0 value */ 3263e12c5d1SDavid du Colombier pushlist(); 3273e12c5d1SDavid du Colombier pushword(zero); 3283e12c5d1SDavid du Colombier ndot++; 3293e12c5d1SDavid du Colombier } 3303e12c5d1SDavid du Colombier void execflag(void){ 3313e12c5d1SDavid du Colombier char *letter, *val; 3323e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 3333e12c5d1SDavid du Colombier case 2: 3343e12c5d1SDavid du Colombier setstatus(flag[runq->argv->words->next->word[0]]?"":"flag not set"); 3353e12c5d1SDavid du Colombier break; 3363e12c5d1SDavid du Colombier case 3: 3373e12c5d1SDavid du Colombier letter=runq->argv->words->next->word; 3383e12c5d1SDavid du Colombier val=runq->argv->words->next->next->word; 3393e12c5d1SDavid du Colombier if(strlen(letter)==1){ 3403e12c5d1SDavid du Colombier if(strcmp(val, "+")==0){ 3413e12c5d1SDavid du Colombier flag[letter[0]]=flagset; 3423e12c5d1SDavid du Colombier break; 3433e12c5d1SDavid du Colombier } 3443e12c5d1SDavid du Colombier if(strcmp(val, "-")==0){ 3453e12c5d1SDavid du Colombier flag[letter[0]]=0; 3463e12c5d1SDavid du Colombier break; 3473e12c5d1SDavid du Colombier } 3483e12c5d1SDavid du Colombier } 3493e12c5d1SDavid du Colombier default: 3503e12c5d1SDavid du Colombier Xerror("Usage: flag [letter] [+-]"); 3513e12c5d1SDavid du Colombier return; 3523e12c5d1SDavid du Colombier } 3533e12c5d1SDavid du Colombier poplist(); 3543e12c5d1SDavid du Colombier } 3553e12c5d1SDavid du Colombier void execwhatis(void){ /* mildly wrong -- should fork before writing */ 3563e12c5d1SDavid du Colombier word *a, *b, *path; 3573e12c5d1SDavid du Colombier var *v; 3583e12c5d1SDavid du Colombier struct builtin *bp; 3593e12c5d1SDavid du Colombier char file[512]; 3603e12c5d1SDavid du Colombier struct io out[1]; 3613e12c5d1SDavid du Colombier int found, sep; 3623e12c5d1SDavid du Colombier a=runq->argv->words->next; 3633e12c5d1SDavid du Colombier if(a==0){ 3643e12c5d1SDavid du Colombier Xerror("Usage: whatis name ..."); 3653e12c5d1SDavid du Colombier return; 3663e12c5d1SDavid du Colombier } 3673e12c5d1SDavid du Colombier setstatus(""); 3683e12c5d1SDavid du Colombier out->fd=mapfd(1); 3693e12c5d1SDavid du Colombier out->bufp=out->buf; 3703e12c5d1SDavid du Colombier out->ebuf=&out->buf[NBUF]; 3713e12c5d1SDavid du Colombier out->strp=0; 3723e12c5d1SDavid du Colombier for(;a;a=a->next){ 3733e12c5d1SDavid du Colombier v=vlook(a->word); 3743e12c5d1SDavid du Colombier if(v->val){ 3753e12c5d1SDavid du Colombier pfmt(out, "%s=", a->word); 3763e12c5d1SDavid du Colombier if(v->val->next==0) 3773e12c5d1SDavid du Colombier pfmt(out, "%q\n", v->val->word); 3783e12c5d1SDavid du Colombier else{ 3793e12c5d1SDavid du Colombier sep='('; 3803e12c5d1SDavid du Colombier for(b=v->val;b && b->word;b=b->next){ 3813e12c5d1SDavid du Colombier pfmt(out, "%c%q", sep, b->word); 3823e12c5d1SDavid du Colombier sep=' '; 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier pfmt(out, ")\n"); 3853e12c5d1SDavid du Colombier } 3863e12c5d1SDavid du Colombier found=1; 3873e12c5d1SDavid du Colombier } 3883e12c5d1SDavid du Colombier else 3893e12c5d1SDavid du Colombier found=0; 3903e12c5d1SDavid du Colombier v=gvlook(a->word); 3913e12c5d1SDavid du Colombier if(v->fn) pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s); 3923e12c5d1SDavid du Colombier else{ 3933e12c5d1SDavid du Colombier for(bp=Builtin;bp->name;bp++) 3943e12c5d1SDavid du Colombier if(strcmp(a->word, bp->name)==0){ 3953e12c5d1SDavid du Colombier pfmt(out, "builtin %s\n", a->word); 3963e12c5d1SDavid du Colombier break; 3973e12c5d1SDavid du Colombier } 3983e12c5d1SDavid du Colombier if(!bp->name){ 3993e12c5d1SDavid du Colombier for(path=searchpath(a->word);path;path=path->next){ 4003e12c5d1SDavid du Colombier strcpy(file, path->word); 4013e12c5d1SDavid du Colombier if(file[0]) strcat(file, "/"); 4023e12c5d1SDavid du Colombier strcat(file, a->word); 4033e12c5d1SDavid du Colombier if(Executable(file)){ 4043e12c5d1SDavid du Colombier pfmt(out, "%s\n", file); 4053e12c5d1SDavid du Colombier break; 4063e12c5d1SDavid du Colombier } 4073e12c5d1SDavid du Colombier } 4083e12c5d1SDavid du Colombier if(!path && !found){ 4093e12c5d1SDavid du Colombier pfmt(err, "%s: not found\n", a->word); 4103e12c5d1SDavid du Colombier setstatus("not found"); 4113e12c5d1SDavid du Colombier } 4123e12c5d1SDavid du Colombier } 4133e12c5d1SDavid du Colombier } 4143e12c5d1SDavid du Colombier } 4153e12c5d1SDavid du Colombier poplist(); 4163e12c5d1SDavid du Colombier flush(err); 4173e12c5d1SDavid du Colombier } 4183e12c5d1SDavid du Colombier void execwait(void){ 4193e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 4203e12c5d1SDavid du Colombier default: Xerror("Usage: wait [pid]"); return; 4213e12c5d1SDavid du Colombier case 2: Waitfor(atoi(runq->argv->words->next->word), 0); break; 4223e12c5d1SDavid du Colombier case 1: Waitfor(-1, 0); break; 4233e12c5d1SDavid du Colombier } 424*219b2ee8SDavid du Colombier poplist(); 4253e12c5d1SDavid du Colombier } 426