~ubuntu-branches/ubuntu/natty/9base/natty

« back to all changes in this revision

Viewing changes to rc/simple.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-08-20 17:34:06 UTC
  • mfrom: (6.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090820173406-xpwqa9ruyevvc0ut
Tags: 1:3-3
* Updating maintainer field.
* Updating vcs fields.
* Updating package to standards version 3.8.3.
* Updatin variables writing in rules to consistent style.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
        while(c->f==Xpopredir) c++;
16
16
        return c->f==Xexit;
17
17
}
18
 
void Xsimple(void){
 
18
 
 
19
void
 
20
Xsimple(void)
 
21
{
19
22
        word *a;
20
 
        thread *p=runq;
 
23
        thread *p = runq;
21
24
        var *v;
22
25
        struct builtin *bp;
23
 
        int pid, n;
24
 
        char buf[ERRMAX];
 
26
        int pid;
25
27
        globlist();
26
 
        a=runq->argv->words;
 
28
        a = runq->argv->words;
27
29
        if(a==0){
28
30
                Xerror1("empty argument list");
29
31
                return;
30
32
        }
31
33
        if(flag['x'])
32
34
                pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */
33
 
        v=gvlook(a->word);
 
35
        v = gvlook(a->word);
34
36
        if(v->fn)
35
37
                execfunc(v);
36
38
        else{
41
43
                                poplist();
42
44
                                return;
43
45
                        }
44
 
                        a=a->next;
 
46
                        a = a->next;
45
47
                        popword();
46
48
                }
47
 
                for(bp=Builtin;bp->name;bp++)
 
49
                for(bp = Builtin;bp->name;bp++)
48
50
                        if(strcmp(a->word, bp->name)==0){
49
51
                                (*bp->fnc)();
50
52
                                return;
58
60
                else{
59
61
                        flush(err);
60
62
                        Updenv();       /* necessary so changes don't go out again */
61
 
                        switch(pid=fork()){
62
 
                        case -1:
 
63
                        if((pid = execforkexec()) < 0){
63
64
                                Xerror("try again");
64
65
                                return;
65
 
                        case 0:
66
 
                                pushword("exec");
67
 
                                execexec();
68
 
                                strcpy(buf, "can't exec: ");
69
 
                                n = strlen(buf);
70
 
                                errstr(buf+n, ERRMAX-n);
71
 
                                Exit(buf);
72
 
                        default:
73
 
                                kidpid = pid;
74
 
                                poplist();
75
 
                                /* interrupts don't get us out */
76
 
                                while(Waitfor(pid, 1) < 0)
77
 
                                        ;
78
 
                                kidpid = 0;
79
66
                        }
 
67
 
 
68
                        /* interrupts don't get us out */
 
69
                        poplist();
 
70
                        while(Waitfor(pid, 1) < 0)
 
71
                                ;
80
72
                }
81
73
        }
82
74
}
83
 
struct word nullpath={ "", 0};
84
 
void doredir(redir *rp)
 
75
struct word nullpath = { "", 0};
 
76
 
 
77
void
 
78
doredir(redir *rp)
85
79
{
86
80
        if(rp){
87
81
                doredir(rp->next);
92
86
                                close(rp->from);
93
87
                        }
94
88
                        break;
95
 
                case RDUP: Dup(rp->from, rp->to); break;
96
 
                case RCLOSE: close(rp->from); break;
 
89
                case RDUP:
 
90
                        Dup(rp->from, rp->to);
 
91
                        break;
 
92
                case RCLOSE:
 
93
                        close(rp->from);
 
94
                        break;
97
95
                }
98
96
        }
99
97
}
100
 
word *searchpath(char *w){
 
98
 
 
99
word*
 
100
searchpath(char *w)
 
101
{
101
102
        word *path;
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)
107
108
                path=&nullpath;
108
109
        return path;
109
110
}
110
 
void execexec(void){
 
111
 
 
112
void
 
113
execexec(void)
 
114
{
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));
118
122
        poplist();
119
123
}
120
 
void execfunc(var *func)
 
124
 
 
125
void
 
126
execfunc(var *func)
121
127
{
122
128
        word *starval;
123
129
        popword();
124
 
        starval=runq->argv->words;
125
 
        runq->argv->words=0;
 
130
        starval = runq->argv->words;
 
131
        runq->argv->words = 0;
126
132
        poplist();
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;
131
137
}
132
 
int dochdir(char *word){
 
138
 
 
139
int
 
140
dochdir(char *word)
 
141
{
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;
141
150
        }
142
151
        return 1;
143
152
}
144
 
void execcd(void){
145
 
        word *a=runq->argv->words;
 
153
 
 
154
void
 
155
execcd(void)
 
156
{
 
157
        word *a = runq->argv->words;
146
158
        word *cdpath;
147
159
        char dir[512];
148
160
        setstatus("can't cd");
149
 
        cdpath=vlook("cdpath")->val;
 
161
        cdpath = vlook("cdpath")->val;
150
162
        switch(count(a)){
151
163
        default:
152
164
                pfmt(err, "Usage: cd [directory]\n");
153
165
                break;
154
166
        case 2:
155
 
                if(a->next->word[0]=='/' || cdpath==0) cdpath=&nullpath;
156
 
                for(;cdpath;cdpath=cdpath->next){
 
167
                if(a->next->word[0]=='/' || cdpath==0)
 
168
                        cdpath=&nullpath;
 
169
                for(;cdpath;cdpath = cdpath->next){
157
170
                        strcpy(dir, cdpath->word);
158
 
                        if(dir[0]) strcat(dir, "/");
 
171
                        if(dir[0])
 
172
                                strcat(dir, "/");
159
173
                        strcat(dir, a->next->word);
160
174
                        if(dochdir(dir)>=0){
161
175
                                if(strlen(cdpath->word)
165
179
                                break;
166
180
                        }
167
181
                }
168
 
                if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word);
 
182
                if(cdpath==0)
 
183
                        pfmt(err, "Can't cd %s: %r\n", a->next->word);
169
184
                break;
170
185
        case 1:
171
 
                a=vlook("HOME")->val;
 
186
                a = vlook("home")->val;
172
187
                if(count(a)>=1){
173
188
                        if(dochdir(a->word)>=0)
174
189
                                setstatus("");
181
196
        }
182
197
        poplist();
183
198
}
184
 
void execexit(void){
 
199
 
 
200
void
 
201
execexit(void)
 
202
{
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);
 
204
        default:
 
205
                pfmt(err, "Usage: exit [status]\nExiting anyway\n");
 
206
        case 2:
 
207
                setstatus(runq->argv->words->next->word);
188
208
        case 1: Xexit();
189
209
        }
190
210
}
191
 
void execshift(void){
 
211
 
 
212
void
 
213
execshift(void)
 
214
{
192
215
        int n;
193
216
        word *a;
194
217
        var *star;
198
221
                setstatus("shift usage");
199
222
                poplist();
200
223
                return;
201
 
        case 2: n=atoi(runq->argv->words->next->word); break;
202
 
        case 1: n=1; break;
 
224
        case 2:
 
225
                n = atoi(runq->argv->words->next->word);
 
226
                break;
 
227
        case 1:
 
228
                n = 1;
 
229
                break;
203
230
        }
204
 
        star=vlook("*");
 
231
        star = vlook("*");
205
232
        for(;n && star->val;--n){
206
 
                a=star->val->next;
 
233
                a = star->val->next;
207
234
                efree(star->val->word);
208
235
                efree((char *)star->val);
209
 
                star->val=a;
210
 
                star->changed=1;
 
236
                star->val = a;
 
237
                star->changed = 1;
211
238
        }
212
239
        setstatus("");
213
240
        poplist();
214
241
}
215
 
int octal(char *s)
 
242
 
 
243
int
 
244
octal(char *s)
216
245
{
217
 
        int n=0;
 
246
        int n = 0;
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';
220
249
        return n;
221
250
}
222
 
int mapfd(int fd)
 
251
 
 
252
int
 
253
mapfd(int fd)
223
254
{
224
255
        redir *rp;
225
 
        for(rp=runq->redir;rp;rp=rp->next){
 
256
        for(rp = runq->redir;rp;rp = rp->next){
226
257
                switch(rp->type){
227
258
                case RCLOSE:
228
 
                        if(rp->from==fd) fd=-1;
 
259
                        if(rp->from==fd)
 
260
                                fd=-1;
229
261
                        break;
230
262
                case RDUP:
231
263
                case ROPEN:
232
 
                        if(rp->to==fd) fd=rp->from;
 
264
                        if(rp->to==fd)
 
265
                                fd = rp->from;
233
266
                        break;
234
267
                }
235
268
        }
236
269
        return fd;
237
270
}
238
271
union code rdcmds[4];
239
 
void execcmds(io *f)
 
272
 
 
273
void
 
274
execcmds(io *f)
240
275
{
241
 
        static int first=1;
 
276
        static int first = 1;
242
277
        if(first){
243
 
                rdcmds[0].i=1;
244
 
                rdcmds[1].f=Xrdcmds;
245
 
                rdcmds[2].f=Xreturn;
246
 
                first=0;
 
278
                rdcmds[0].i = 1;
 
279
                rdcmds[1].f = Xrdcmds;
 
280
                rdcmds[2].f = Xreturn;
 
281
                first = 0;
247
282
        }
248
283
        start(rdcmds, 1, runq->local);
249
 
        runq->cmdfd=f;
250
 
        runq->iflast=0;
 
284
        runq->cmdfd = f;
 
285
        runq->iflast = 0;
251
286
}
252
 
void execeval(void){
 
287
 
 
288
void
 
289
execeval(void)
 
290
{
253
291
        char *cmdline, *s, *t;
254
 
        int len=0;
 
292
        int len = 0;
255
293
        word *ap;
256
294
        if(count(runq->argv->words)<=1){
257
295
                Xerror1("Usage: eval cmd ...");
258
296
                return;
259
297
        }
260
 
        eflagok=1;
261
 
        for(ap=runq->argv->words->next;ap;ap=ap->next)
 
298
        eflagok = 1;
 
299
        for(ap = runq->argv->words->next;ap;ap = ap->next)
262
300
                len+=1+strlen(ap->word);
263
 
        cmdline=emalloc(len);
264
 
        s=cmdline;
265
 
        for(ap=runq->argv->words->next;ap;ap=ap->next){
266
 
                for(t=ap->word;*t;) *s++=*t++;
 
301
        cmdline = emalloc(len);
 
302
        s = cmdline;
 
303
        for(ap = runq->argv->words->next;ap;ap = ap->next){
 
304
                for(t = ap->word;*t;) *s++=*t++;
267
305
                *s++=' ';
268
306
        }
269
307
        s[-1]='\n';
272
310
        efree(cmdline);
273
311
}
274
312
union code dotcmds[14];
275
 
void execdot(void){
276
 
        int iflag=0;
 
313
 
 
314
void
 
315
execdot(void)
 
316
{
 
317
        int iflag = 0;
277
318
        int fd;
278
319
        list *av;
279
 
        thread *p=runq;
 
320
        thread *p = runq;
280
321
        char *zero;
281
 
        static int first=1;
 
322
        static int first = 1;
282
323
        char file[512];
283
324
        word *path;
284
325
        if(first){
285
 
                dotcmds[0].i=1;
286
 
                dotcmds[1].f=Xmark;
287
 
                dotcmds[2].f=Xword;
 
326
                dotcmds[0].i = 1;
 
327
                dotcmds[1].f = Xmark;
 
328
                dotcmds[2].f = Xword;
288
329
                dotcmds[3].s="0";
289
 
                dotcmds[4].f=Xlocal;
290
 
                dotcmds[5].f=Xmark;
291
 
                dotcmds[6].f=Xword;
 
330
                dotcmds[4].f = Xlocal;
 
331
                dotcmds[5].f = Xmark;
 
332
                dotcmds[6].f = Xword;
292
333
                dotcmds[7].s="*";
293
 
                dotcmds[8].f=Xlocal;
294
 
                dotcmds[9].f=Xrdcmds;
295
 
                dotcmds[10].f=Xunlocal;
296
 
                dotcmds[11].f=Xunlocal;
297
 
                dotcmds[12].f=Xreturn;
298
 
                first=0;
 
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;
 
339
                first = 0;
299
340
        }
300
341
        else
301
 
                eflagok=1;
 
342
                eflagok = 1;
302
343
        popword();
303
344
        if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){
304
 
                iflag=1;
 
345
                iflag = 1;
305
346
                popword();
306
347
        }
307
348
        /* get input file */
309
350
                Xerror1("Usage: . [-i] file [arg ...]");
310
351
                return;
311
352
        }
312
 
        zero=strdup(p->argv->words->word);
 
353
        zero = strdup(p->argv->words->word);
313
354
        popword();
314
355
        fd=-1;
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, "/");
 
358
                if(file[0])
 
359
                        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 */
320
 
                        fd=Dup1(0);
321
 
                        if(fd>=0) break;
 
363
                        fd = Dup1(0);
 
364
                        if(fd>=0)
 
365
                                break;
322
366
                }
323
 
                if((fd=open(file, 0))>=0) break;
324
367
        }
325
368
        if(fd<0){
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);
334
 
        runq->cmdfile=zero;
335
 
        runq->cmdfd=openfd(fd);
336
 
        runq->iflag=iflag;
337
 
        runq->iflast=0;
 
377
        runq->cmdfile = zero;
 
378
        runq->cmdfd = openfd(fd);
 
379
        runq->iflag = iflag;
 
380
        runq->iflast = 0;
338
381
        /* push $* value */
339
382
        pushlist();
340
 
        runq->argv->words=p->argv->words;
 
383
        runq->argv->words = p->argv->words;
341
384
        /* free caller's copy of $* */
342
 
        av=p->argv;
343
 
        p->argv=av->next;
 
385
        av = p->argv;
 
386
        p->argv = av->next;
344
387
        efree((char *)av);
345
388
        /* push $0 value */
346
389
        pushlist();
347
390
        pushword(zero);
348
391
        ndot++;
349
392
}
350
 
void execflag(void){
 
393
 
 
394
void
 
395
execflag(void)
 
396
{
351
397
        char *letter, *val;
352
398
        switch(count(runq->argv->words)){
353
399
        case 2:
354
400
                setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set");
355
401
                break;
356
402
        case 3:
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;
362
408
                                break;
363
409
                        }
364
410
                        if(strcmp(val, "-")==0){
365
 
                                flag[(uchar)letter[0]]=0;
 
411
                                flag[(uchar)letter[0]] = 0;
366
412
                                break;
367
413
                        }
368
414
                }
372
418
        }
373
419
        poplist();
374
420
}
375
 
void execwhatis(void){  /* mildly wrong -- should fork before writing */
 
421
 
 
422
void
 
423
execwhatis(void){       /* mildly wrong -- should fork before writing */
376
424
        word *a, *b, *path;
377
425
        var *v;
378
426
        struct builtin *bp;
379
427
        char file[512];
380
428
        struct io out[1];
381
429
        int found, sep;
382
 
        a=runq->argv->words->next;
 
430
        a = runq->argv->words->next;
383
431
        if(a==0){
384
432
                Xerror1("Usage: whatis name ...");
385
433
                return;
386
434
        }
387
435
        setstatus("");
388
 
        out->fd=mapfd(1);
389
 
        out->bufp=out->buf;
390
 
        out->ebuf=&out->buf[NBUF];
391
 
        out->strp=0;
392
 
        for(;a;a=a->next){
393
 
                v=vlook(a->word);
 
436
        out->fd = mapfd(1);
 
437
        out->bufp = out->buf;
 
438
        out->ebuf = &out->buf[NBUF];
 
439
        out->strp = 0;
 
440
        for(;a;a = a->next){
 
441
                v = vlook(a->word);
394
442
                if(v->val){
395
443
                        pfmt(out, "%s=", a->word);
396
444
                        if(v->val->next==0)
397
445
                                pfmt(out, "%q\n", v->val->word);
398
446
                        else{
399
447
                                sep='(';
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);
402
450
                                        sep=' ';
403
451
                                }
404
452
                                pfmt(out, ")\n");
405
453
                        }
406
 
                        found=1;
 
454
                        found = 1;
407
455
                }
408
456
                else
409
 
                        found=0;
410
 
                v=gvlook(a->word);
411
 
                if(v->fn) pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
 
457
                        found = 0;
 
458
                v = gvlook(a->word);
 
459
                if(v->fn)
 
460
                        pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
412
461
                else{
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);
416
465
                                        break;
417
466
                                }
418
467
                        if(!bp->name){
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, "/");
 
470
                                        if(file[0])
 
471
                                                strcat(file, "/");
422
472
                                        strcat(file, a->word);
423
473
                                        if(Executable(file)){
424
474
                                                pfmt(out, "%s\n", file);
435
485
        poplist();
436
486
        flush(err);
437
487
}
438
 
void execwait(void){
 
488
 
 
489
void
 
490
execwait(void)
 
491
{
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;
 
493
        default:
 
494
                Xerror1("Usage: wait [pid]");
 
495
                return;
 
496
        case 2:
 
497
                Waitfor(atoi(runq->argv->words->next->word), 0);
 
498
                break;
 
499
        case 1:
 
500
                Waitfor(-1, 0);
 
501
                break;
443
502
        }
444
503
        poplist();
445
504
}