void Xdol(void) { word *a, *star; char *s, *t; int n; if(runq->argv == 0) { Xerror1("need to set up argv"); return; } if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); n = 0; for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; a = runq->argv->next->words; if(n==0 || *t) a = copywords(vlook(s)->val, a); else{ star = vlook("*")->val; if(star && 1<=n && n<=count(star)){ while(--n) star = star->next; a = newword(star->word, a); } } poplist(); runq->argv->words = a; }
void Xwrite(void) { char *file; int f; switch(count(runq->argv->words)){ default: Xerror1("> requires singleton\n"); return; case 0: Xerror1("> requires file\n"); return; case 1: break; } file = runq->argv->words->word; if((f = Creat(file))<0){ pfmt(err, "%s: ", file); Xerror("can't open"); return; } pushredir(ROPEN, f, runq->code[runq->pc].i); runq->pc++; poplist(); }
void Xcount(void) { word *a; char *s, *t; int n; char num[12]; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); n = 0; for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; if(n==0 || *t){ a = vlook(s)->val; inttoascii(num, count(a)); } else{ a = vlook("*")->val; inttoascii(num, a && 1<=n && n<=count(a)?1:0); } poplist(); pushword(num); }
void Xqdol(void) { word *a, *p; char *s; int n; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); a = vlook(s)->val; poplist(); n = count(a); if(n==0){ pushword(""); return; } for(p = a;p;p = p->next) n+=strlen(p->word); s = emalloc(n); if(a){ strcpy(s, a->word); for(p = a->next;p;p = p->next){ strcat(s, " "); strcat(s, p->word); } } else s[0]='\0'; pushword(s); efree(s); }
void execflag(void) { char *letter, *val; switch(count(runq->argv->words)){ case 2: setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set"); break; case 3: letter = runq->argv->words->next->word; val = runq->argv->words->next->next->word; if(strlen(letter)==1){ if(strcmp(val, "+")==0){ flag[(uchar)letter[0]] = flagset; break; } if(strcmp(val, "-")==0){ flag[(uchar)letter[0]] = 0; break; } } default: Xerror1("Usage: flag [letter] [+-]"); return; } poplist(); }
void Xsimple(void) { word *a; thread *p = runq; var *v; struct builtin *bp; int pid; globlist(); a = runq->argv->words; if(a==0){ Xerror1("empty argument list"); return; } if(flag['x']) pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */ v = gvlook(a->word); if(v->fn) execfunc(v); else{ if(strcmp(a->word, "builtin")==0){ if(count(a)==1){ pfmt(err, "builtin: empty argument list\n"); setstatus("empty arg list"); poplist(); return; } a = a->next; popword(); } for(bp = Builtin;bp->name;bp++) if(strcmp(a->word, bp->name)==0){ (*bp->fnc)(); return; } if(exitnext()){ /* fork and wait is redundant */ pushword("exec"); execexec(); Xexit(); } else{ flush(err); Updenv(); /* necessary so changes don't go out again */ if((pid = execforkexec()) < 0){ Xerror("try again"); return; } /* interrupts don't get us out */ poplist(); while(Waitfor(pid, 1) < 0) ; } } }
void Xconc(void) { word *lp = runq->argv->words; word *rp = runq->argv->next->words; word *vp = runq->argv->next->next->words; int lc = count(lp), rc = count(rp); if(lc!=0 || rc!=0){ if(lc==0 || rc==0){ Xerror1("null list in concatenation"); return; } if(lc!=1 && rc!=1 && lc!=rc){ Xerror1("mismatched list lengths in concatenation"); return; } vp = conclist(lp, rp, vp); } poplist(); poplist(); runq->argv->words = vp; }
void Xlocal(void) { if(count(runq->argv->words)!=1){ Xerror1("variable name must be singleton\n"); return; } deglob(runq->argv->words->word); runq->local = newvar(strdup(runq->argv->words->word), runq->local); runq->local->val = copywords(runq->argv->next->words, (word *)0); runq->local->changed = 1; poplist(); poplist(); }
void execwait(void) { switch(count(runq->argv->words)){ default: Xerror1("Usage: wait [pid]"); return; case 2: Waitfor(atoi(runq->argv->words->next->word), 0); break; case 1: Waitfor(-1, 0); break; } poplist(); }
void Xsub(void) { word *a, *v; char *s; if(count(runq->argv->next->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->next->words->word; deglob(s); a = runq->argv->next->next->words; v = vlook(s)->val; a = subwords(v, count(v), runq->argv->words, a); poplist(); poplist(); runq->argv->words = a; }
void Xassign(void) { var *v; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } deglob(runq->argv->words->word); v = vlook(runq->argv->words->word); poplist(); globlist(); freewords(v->val); v->val = runq->argv->words; v->changed = 1; if(v->changefn) v->changefn(v); runq->argv->words = 0; poplist(); }
void execexec(void) { word *a, *p; char *s; int n; popword(); /* "exec" */ if(runq->argv->words==0){ Xerror1("empty argument list"); return; } doredir(runq->redir); if(flag['j']){ a = runq->argv->words; n = 0; for(p = a;p;p = p->next) n+=strlen(p->word); s = emalloc(n+2); if(a){ strcat(s, a->word); for(p = a->next;p;p = p->next){ popword(); strcat(s, " "); strcat(s, p->word); } } print("%s\n", s); pushword(s); pushword("1"); pushword("-n"); pushword("/Users/npe/src/hare/usr/inferno/appl/cmd/scripts/anl/linux/deploy/py9p/"); pushword("-9"); pushword("runJob.py"); } Execute(runq->argv->words, searchpath(runq->argv->words->word)); poplist(); }
void execeval(void) { char *cmdline, *s, *t; int len = 0; word *ap; if(count(runq->argv->words)<=1){ Xerror1("Usage: eval cmd ..."); return; } eflagok = 1; for(ap = runq->argv->words->next;ap;ap = ap->next) len+=1+strlen(ap->word); cmdline = emalloc(len); s = cmdline; for(ap = runq->argv->words->next;ap;ap = ap->next){ for(t = ap->word;*t;) *s++=*t++; *s++=' '; } s[-1]='\n'; poplist(); execcmds(opencore(cmdline, len)); efree(cmdline); }
void execwhatis(void){ /* mildly wrong -- should fork before writing */ word *a, *b, *path; var *v; struct builtin *bp; char file[512]; struct io out[1]; int found, sep; a = runq->argv->words->next; if(a==0){ Xerror1("Usage: whatis name ..."); return; } setstatus(""); out->fd = mapfd(1); out->bufp = out->buf; out->ebuf = &out->buf[NBUF]; out->strp = 0; for(;a;a = a->next){ v = vlook(a->word); if(v->val){ pfmt(out, "%s=", a->word); if(v->val->next==0) pfmt(out, "%q\n", v->val->word); else{ sep='('; for(b = v->val;b && b->word;b = b->next){ pfmt(out, "%c%q", sep, b->word); sep=' '; } pfmt(out, ")\n"); } found = 1; } else found = 0; v = gvlook(a->word); if(v->fn) pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s); else{ for(bp = Builtin;bp->name;bp++) if(strcmp(a->word, bp->name)==0){ pfmt(out, "builtin %s\n", a->word); break; } if(!bp->name){ for(path = searchpath(a->word);path;path = path->next){ strcpy(file, path->word); if(file[0]) strcat(file, "/"); strcat(file, a->word); if(Executable(file)){ pfmt(out, "%s\n", file); break; } } if(!path && !found){ pfmt(err, "%s: not found\n", a->word); setstatus("not found"); } } } } poplist(); flush(err); }
void execdot(void) { int iflag = 0; int fd; list *av; thread *p = runq; char *zero; static int first = 1; char file[512]; word *path; if(first){ dotcmds[0].i = 1; dotcmds[1].f = Xmark; dotcmds[2].f = Xword; dotcmds[3].s="0"; dotcmds[4].f = Xlocal; dotcmds[5].f = Xmark; dotcmds[6].f = Xword; dotcmds[7].s="*"; dotcmds[8].f = Xlocal; dotcmds[9].f = Xrdcmds; dotcmds[10].f = Xunlocal; dotcmds[11].f = Xunlocal; dotcmds[12].f = Xreturn; first = 0; } else eflagok = 1; popword(); if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ iflag = 1; popword(); } /* get input file */ if(p->argv->words==0){ Xerror1("Usage: . [-i] file [arg ...]"); return; } zero = strdup(p->argv->words->word); popword(); fd=-1; for(path = searchpath(zero);path;path = path->next){ strcpy(file, path->word); if(file[0]) strcat(file, "/"); strcat(file, zero); if((fd = open(file, 0))>=0) break; if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */ fd = Dup1(0); if(fd>=0) break; } } if(fd<0){ pfmt(err, "%s: ", zero); setstatus("can't open"); Xerror(".: can't open"); return; } /* set up for a new command loop */ start(dotcmds, 1, (struct var *)0); pushredir(RCLOSE, fd, 0); runq->cmdfile = zero; runq->cmdfd = openfd(fd); runq->iflag = iflag; runq->iflast = 0; /* push $* value */ pushlist(); runq->argv->words = p->argv->words; /* free caller's copy of $* */ av = p->argv; p->argv = av->next; efree((char *)av); /* push $0 value */ pushlist(); pushword(zero); ndot++; }