2 * Maybe `simple' is a misnomer.
10 * Search through the following code to see if we're just going to exit.
14 union code *c=&runq->code[runq->pc];
15 while(c->f==Xpopredir) c++;
28 a = runq->argv->words;
30 Xerror1("empty argument list");
34 pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */
39 if(strcmp(a->word, "builtin")==0){
41 pfmt(err, "builtin: empty argument list\n");
42 setstatus("empty arg list");
49 for(bp = Builtin;bp->name;bp++)
50 if(strcmp(a->word, bp->name)==0){
55 /* fork and wait is redundant */
62 Updenv(); /* necessary so changes don't go out again */
63 if((pid = execforkexec()) < 0){
68 /* interrupts don't get us out */
70 while(Waitfor(pid, 1) < 0)
75 struct word nullpath = { "", 0};
85 Dup(rp->from, rp->to);
90 Dup(rp->from, rp->to);
103 if(strncmp(w, "/", 1)==0
104 /* || strncmp(w, "#", 1)==0 */
105 || strncmp(w, "./", 2)==0
106 || strncmp(w, "../", 3)==0
107 || (path = vlook("path")->val)==0)
115 popword(); /* "exec" */
116 if(runq->argv->words==0){
117 Xerror1("empty argument list");
120 doredir(runq->redir);
121 Execute(runq->argv->words, searchpath(runq->argv->words->word));
130 starval = runq->argv->words;
131 runq->argv->words = 0;
133 start(func->fn, func->pc, runq->local);
134 runq->local = newvar(strdup("*"), runq->local);
135 runq->local->val = starval;
136 runq->local->changed = 1;
142 /* report to /dev/wdir if it exists and we're interactive */
143 static int wdirfd = -2;
144 if(chdir(word)<0) return -1;
146 if(wdirfd==-2) /* try only once */
147 wdirfd = open("/dev/wdir", OWRITE|OCEXEC);
149 write(wdirfd, word, strlen(word));
157 word *a = runq->argv->words;
160 setstatus("can't cd");
161 cdpath = vlook("cdpath")->val;
164 pfmt(err, "Usage: cd [directory]\n");
167 if(a->next->word[0]=='/' || cdpath==0)
169 for(;cdpath;cdpath = cdpath->next){
170 strcpy(dir, cdpath->word);
173 strcat(dir, a->next->word);
175 if(strlen(cdpath->word)
176 && strcmp(cdpath->word, ".")!=0)
177 pfmt(err, "%s\n", dir);
183 pfmt(err, "Can't cd %s: %r\n", a->next->word);
186 a = vlook("home")->val;
188 if(dochdir(a->word)>=0)
191 pfmt(err, "Can't cd %s: %r\n", a->word);
194 pfmt(err, "Can't cd -- $home empty\n");
203 switch(count(runq->argv->words)){
205 pfmt(err, "Usage: exit [status]\nExiting anyway\n");
207 setstatus(runq->argv->words->next->word);
218 switch(count(runq->argv->words)){
220 pfmt(err, "Usage: shift [n]\n");
221 setstatus("shift usage");
225 n = atoi(runq->argv->words->next->word);
232 for(;n && star->val;--n){
234 efree(star->val->word);
235 efree((char *)star->val);
247 while(*s==' ' || *s=='\t' || *s=='\n') s++;
248 while('0'<=*s && *s<='7') n = n*8+*s++-'0';
256 for(rp = runq->redir;rp;rp = rp->next){
271 union code rdcmds[4];
276 static int first = 1;
279 rdcmds[1].f = Xrdcmds;
280 rdcmds[2].f = Xreturn;
283 start(rdcmds, 1, runq->local);
291 char *cmdline, *s, *t;
294 if(count(runq->argv->words)<=1){
295 Xerror1("Usage: eval cmd ...");
299 for(ap = runq->argv->words->next;ap;ap = ap->next)
300 len+=1+strlen(ap->word);
301 cmdline = emalloc(len);
303 for(ap = runq->argv->words->next;ap;ap = ap->next){
304 for(t = ap->word;*t;) *s++=*t++;
309 execcmds(opencore(cmdline, len));
312 union code dotcmds[14];
322 static int first = 1;
327 dotcmds[1].f = Xmark;
328 dotcmds[2].f = Xword;
330 dotcmds[4].f = Xlocal;
331 dotcmds[5].f = Xmark;
332 dotcmds[6].f = Xword;
334 dotcmds[8].f = Xlocal;
335 dotcmds[9].f = Xrdcmds;
336 dotcmds[10].f = Xunlocal;
337 dotcmds[11].f = Xunlocal;
338 dotcmds[12].f = Xreturn;
344 if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){
349 if(p->argv->words==0){
350 Xerror1("Usage: . [-i] file [arg ...]");
353 zero = strdup(p->argv->words->word);
356 for(path = searchpath(zero);path;path = path->next){
357 strcpy(file, path->word);
361 if((fd = open(file, 0))>=0) break;
362 if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */
369 pfmt(err, "%s: ", zero);
370 setstatus("can't open");
371 Xerror(".: can't open");
374 /* set up for a new command loop */
375 start(dotcmds, 1, (struct var *)0);
376 pushredir(RCLOSE, fd, 0);
377 runq->cmdfile = zero;
378 runq->cmdfd = openfd(fd);
383 runq->argv->words = p->argv->words;
384 /* free caller's copy of $* */
398 switch(count(runq->argv->words)){
400 setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set");
403 letter = runq->argv->words->next->word;
404 val = runq->argv->words->next->next->word;
405 if(strlen(letter)==1){
406 if(strcmp(val, "+")==0){
407 flag[(uchar)letter[0]] = flagset;
410 if(strcmp(val, "-")==0){
411 flag[(uchar)letter[0]] = 0;
416 Xerror1("Usage: flag [letter] [+-]");
423 execwhatis(void){ /* mildly wrong -- should fork before writing */
430 a = runq->argv->words->next;
432 Xerror1("Usage: whatis name ...");
437 out->bufp = out->buf;
438 out->ebuf = &out->buf[NBUF];
443 pfmt(out, "%s=", a->word);
445 pfmt(out, "%q\n", v->val->word);
448 for(b = v->val;b && b->word;b = b->next){
449 pfmt(out, "%c%q", sep, b->word);
460 pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
462 for(bp = Builtin;bp->name;bp++)
463 if(strcmp(a->word, bp->name)==0){
464 pfmt(out, "builtin %s\n", a->word);
468 for(path = searchpath(a->word);path;path = path->next){
469 strcpy(file, path->word);
472 strcat(file, a->word);
473 if(Executable(file)){
474 pfmt(out, "%s\n", file);
479 pfmt(err, "%s: not found\n", a->word);
480 setstatus("not found");
492 switch(count(runq->argv->words)){
494 Xerror1("Usage: wait [pid]");
497 Waitfor(atoi(runq->argv->words->next->word), 0);