15
15
while(c->f==Xpopredir) c++;
16
16
return c->f==Xexit;
22
25
struct builtin *bp;
28
a = runq->argv->words;
28
30
Xerror1("empty argument list");
32
34
pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */
60
62
Updenv(); /* necessary so changes don't go out again */
63
if((pid = execforkexec()) < 0){
63
64
Xerror("try again");
68
strcpy(buf, "can't exec: ");
70
errstr(buf+n, ERRMAX-n);
75
/* interrupts don't get us out */
76
while(Waitfor(pid, 1) < 0)
68
/* interrupts don't get us out */
70
while(Waitfor(pid, 1) < 0)
83
struct word nullpath={ "", 0};
84
void doredir(redir *rp)
75
struct word nullpath = { "", 0};
95
case RDUP: Dup(rp->from, rp->to); break;
96
case RCLOSE: close(rp->from); break;
90
Dup(rp->from, rp->to);
100
word *searchpath(char *w){
102
103
if(strncmp(w, "/", 1)==0
103
104
/* || strncmp(w, "#", 1)==0 */
104
105
|| strncmp(w, "./", 2)==0
105
106
|| strncmp(w, "../", 3)==0
106
|| (path=vlook("path")->val)==0)
107
|| (path = vlook("path")->val)==0)
111
115
popword(); /* "exec" */
112
116
if(runq->argv->words==0){
113
117
Xerror1("empty argument list");
117
121
Execute(runq->argv->words, searchpath(runq->argv->words->word));
120
void execfunc(var *func)
124
starval=runq->argv->words;
130
starval = runq->argv->words;
131
runq->argv->words = 0;
127
start(func->fn, func->pc, (struct var *)0);
128
runq->local=newvar(strdup("*"), runq->local);
129
runq->local->val=starval;
130
runq->local->changed=1;
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;
132
int dochdir(char *word){
133
142
/* report to /dev/wdir if it exists and we're interactive */
134
143
static int wdirfd = -2;
135
144
if(chdir(word)<0) return -1;
145
word *a=runq->argv->words;
157
word *a = runq->argv->words;
148
160
setstatus("can't cd");
149
cdpath=vlook("cdpath")->val;
161
cdpath = vlook("cdpath")->val;
150
162
switch(count(a)){
152
164
pfmt(err, "Usage: cd [directory]\n");
155
if(a->next->word[0]=='/' || cdpath==0) cdpath=&nullpath;
156
for(;cdpath;cdpath=cdpath->next){
167
if(a->next->word[0]=='/' || cdpath==0)
169
for(;cdpath;cdpath = cdpath->next){
157
170
strcpy(dir, cdpath->word);
158
if(dir[0]) strcat(dir, "/");
159
173
strcat(dir, a->next->word);
160
174
if(dochdir(dir)>=0){
161
175
if(strlen(cdpath->word)
185
203
switch(count(runq->argv->words)){
186
default: pfmt(err, "Usage: exit [status]\nExiting anyway\n");
187
case 2: setstatus(runq->argv->words->next->word);
205
pfmt(err, "Usage: exit [status]\nExiting anyway\n");
207
setstatus(runq->argv->words->next->word);
191
void execshift(void){
198
221
setstatus("shift usage");
201
case 2: n=atoi(runq->argv->words->next->word); break;
225
n = atoi(runq->argv->words->next->word);
205
232
for(;n && star->val;--n){
207
234
efree(star->val->word);
208
235
efree((char *)star->val);
218
247
while(*s==' ' || *s=='\t' || *s=='\n') s++;
219
while('0'<=*s && *s<='7') n=n*8+*s++-'0';
248
while('0'<=*s && *s<='7') n = n*8+*s++-'0';
225
for(rp=runq->redir;rp;rp=rp->next){
256
for(rp = runq->redir;rp;rp = rp->next){
226
257
switch(rp->type){
228
if(rp->from==fd) fd=-1;
232
if(rp->to==fd) fd=rp->from;
238
271
union code rdcmds[4];
276
static int first = 1;
279
rdcmds[1].f = Xrdcmds;
280
rdcmds[2].f = Xreturn;
248
283
start(rdcmds, 1, runq->local);
253
291
char *cmdline, *s, *t;
256
294
if(count(runq->argv->words)<=1){
257
295
Xerror1("Usage: eval cmd ...");
261
for(ap=runq->argv->words->next;ap;ap=ap->next)
299
for(ap = runq->argv->words->next;ap;ap = ap->next)
262
300
len+=1+strlen(ap->word);
263
cmdline=emalloc(len);
265
for(ap=runq->argv->words->next;ap;ap=ap->next){
266
for(t=ap->word;*t;) *s++=*t++;
301
cmdline = emalloc(len);
303
for(ap = runq->argv->words->next;ap;ap = ap->next){
304
for(t = ap->word;*t;) *s++=*t++;
309
350
Xerror1("Usage: . [-i] file [arg ...]");
312
zero=strdup(p->argv->words->word);
353
zero = strdup(p->argv->words->word);
315
for(path=searchpath(zero);path;path=path->next){
356
for(path = searchpath(zero);path;path = path->next){
316
357
strcpy(file, path->word);
317
if(file[0]) strcat(file, "/");
318
360
strcat(file, zero);
361
if((fd = open(file, 0))>=0) break;
319
362
if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */
323
if((fd=open(file, 0))>=0) break;
326
369
pfmt(err, "%s: ", zero);
331
374
/* set up for a new command loop */
332
375
start(dotcmds, 1, (struct var *)0);
333
376
pushredir(RCLOSE, fd, 0);
335
runq->cmdfd=openfd(fd);
377
runq->cmdfile = zero;
378
runq->cmdfd = openfd(fd);
338
381
/* push $* value */
340
runq->argv->words=p->argv->words;
383
runq->argv->words = p->argv->words;
341
384
/* free caller's copy of $* */
344
387
efree((char *)av);
345
388
/* push $0 value */
351
397
char *letter, *val;
352
398
switch(count(runq->argv->words)){
354
400
setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set");
357
letter=runq->argv->words->next->word;
358
val=runq->argv->words->next->next->word;
403
letter = runq->argv->words->next->word;
404
val = runq->argv->words->next->next->word;
359
405
if(strlen(letter)==1){
360
406
if(strcmp(val, "+")==0){
361
flag[(uchar)letter[0]]=flagset;
407
flag[(uchar)letter[0]] = flagset;
364
410
if(strcmp(val, "-")==0){
365
flag[(uchar)letter[0]]=0;
411
flag[(uchar)letter[0]] = 0;
375
void execwhatis(void){ /* mildly wrong -- should fork before writing */
423
execwhatis(void){ /* mildly wrong -- should fork before writing */
376
424
word *a, *b, *path;
378
426
struct builtin *bp;
380
428
struct io out[1];
382
a=runq->argv->words->next;
430
a = runq->argv->words->next;
384
432
Xerror1("Usage: whatis name ...");
390
out->ebuf=&out->buf[NBUF];
437
out->bufp = out->buf;
438
out->ebuf = &out->buf[NBUF];
395
443
pfmt(out, "%s=", a->word);
396
444
if(v->val->next==0)
397
445
pfmt(out, "%q\n", v->val->word);
400
for(b=v->val;b && b->word;b=b->next){
448
for(b = v->val;b && b->word;b = b->next){
401
449
pfmt(out, "%c%q", sep, b->word);
404
452
pfmt(out, ")\n");
411
if(v->fn) pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
460
pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
413
for(bp=Builtin;bp->name;bp++)
462
for(bp = Builtin;bp->name;bp++)
414
463
if(strcmp(a->word, bp->name)==0){
415
464
pfmt(out, "builtin %s\n", a->word);
419
for(path=searchpath(a->word);path;path=path->next){
468
for(path = searchpath(a->word);path;path = path->next){
420
469
strcpy(file, path->word);
421
if(file[0]) strcat(file, "/");
422
472
strcat(file, a->word);
423
473
if(Executable(file)){
424
474
pfmt(out, "%s\n", file);
439
492
switch(count(runq->argv->words)){
440
default: Xerror1("Usage: wait [pid]"); return;
441
case 2: Waitfor(atoi(runq->argv->words->next->word), 0); break;
442
case 1: Waitfor(-1, 0); break;
494
Xerror1("Usage: wait [pid]");
497
Waitfor(atoi(runq->argv->words->next->word), 0);