OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [initial/] [uclinux/] [userland/] [sh/] [sh3.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#include <sys/types.h>
2
#include <signal.h>
3
 
4
#include <stdio.h>
5
#include <errno.h>
6
#include <setjmp.h>
7
#include <stddef.h>
8
#include <time.h>
9
#include <sys/times.h>
10
#include <sys/stat.h>
11
#include <sys/wait.h>
12
#undef NULL
13
#include "sh.h"
14
 
15
/* -------- exec.c -------- */
16
/* #include "sh.h" */
17
 
18
/*
19
 * execute tree
20
 */
21
 
22
static  char    *signame[] = {
23
        "Signal 0",
24
        "Hangup",
25
        (char *)NULL,   /* interrupt */
26
        "Quit",
27
        "Illegal instruction",
28
        "Trace/BPT trap",
29
        "Abort",
30
        "Bus error",
31
        "Floating Point Exception",
32
        "Killed",
33
        "SIGUSR1",
34
        "SIGSEGV",
35
        "SIGUSR2",
36
        (char *)NULL,   /* broken pipe */
37
        "Alarm clock",
38
        "Terminated",
39
};
40
#define NSIGNAL (sizeof(signame)/sizeof(signame[0]))
41
 
42
 
43
static int forkexec (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked );
44
int iosetup (struct ioword *iop, int pipein, int pipeout );
45
static void echo(char **wp );
46
static struct op **find1case (struct op *t, char *w );
47
static struct op *findcase (struct op *t, char *w );
48
static void brkset(struct brkcon *bc );
49
int dolabel(void);
50
int dochdir(struct op *t );
51
int doshift(struct op *t );
52
int dologin(struct op *t );
53
int doumask(struct op *t );
54
int doexec(struct op *t );
55
int dodot(struct op *t );
56
int dowait(struct op *t );
57
int doread(struct op *t );
58
int doeval(struct op *t );
59
int dotrap(struct op *t );
60
int getsig(char *s );
61
void setsig (int n, void (*f)());
62
int getn(char *as );
63
int dobreak(struct op *t );
64
int docontinue(struct op *t );
65
static int brkcontin (char *cp, int val );
66
int doexit(struct op *t );
67
int doexport(struct op *t );
68
int doreadonly(struct op *t );
69
static void rdexp (char **wp, void (*f)(), int key);
70
static void badid(char *s );
71
int doset(struct op *t );
72
void varput (char *s, int out );
73
int dotimes(void);
74
 
75
int
76
execute(t, pin, pout, act)
77
register struct op *t;
78
int *pin, *pout;
79
int act;
80
{
81
        register struct op *t1;
82
        volatile int i, rv, a;
83
        char *cp, **wp, **wp2;
84
        struct var *vp;
85
        struct brkcon bc;
86
 
87
        if (t == NULL)
88
                return(0);
89
        rv = 0;
90
        a = areanum++;
91
        wp = (wp2 = t->words) != NULL
92
             ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY)
93
             : NULL;
94
 
95
        switch(t->type) {
96
        case TPAREN:
97
        case TCOM:
98
            {
99
                int child;
100
                rv = forkexec(t, pin, pout, act, wp, &child);
101
                if (child) {
102
                        exstat = rv;
103
                        leave();
104
                }
105
            }
106
                break;
107
 
108
        case TPIPE:
109
                {
110
                    int pv[2];
111
                    if ((rv = openpipe(pv)) < 0)
112
                        break;
113
                    pv[0] = remap(pv[0]);
114
                    pv[1] = remap(pv[1]);
115
                    (void) execute(t->left, pin, pv, 0);
116
                    rv = execute(t->right, pv, pout, 0);
117
                }
118
                break;
119
 
120
        case TLIST:
121
                (void) execute(t->left, pin, pout, 0);
122
                rv = execute(t->right, pin, pout, 0);
123
                break;
124
 
125
        case TASYNC:
126
        {
127
                int htalking = talking;
128
 
129
                i = vfork();
130
                if (i != 0) {
131
                        talking = htalking;
132
                        if (i != -1) {
133
                                setval(lookup("!"), putn(i));
134
                                if (pin != NULL)
135
                                        closepipe(pin);
136
                                if (talking) {
137
                                        prs(putn(i));
138
                                        prs("\n");
139
                                }
140
                        } else
141
                                rv = -1;
142
                        setstatus(rv);
143
                } else {
144
                        signal(SIGINT, SIG_IGN);
145
                        signal(SIGQUIT, SIG_IGN);
146
                        if (talking)
147
                                signal(SIGTERM, SIG_DFL);
148
                        talking = 0;
149
                        if (pin == NULL) {
150
                                close(0);
151
                                open("/dev/null", 0);
152
                        }
153
                        exit(execute(t->left, pin, pout, FEXEC));
154
                }
155
        }
156
                break;
157
 
158
        case TOR:
159
        case TAND:
160
                rv = execute(t->left, pin, pout, 0);
161
                if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND))
162
                        rv = execute(t1, pin, pout, 0);
163
                break;
164
 
165
        case TFOR:
166
                if (wp == NULL) {
167
                        wp = dolv+1;
168
                        if ((i = dolc) < 0)
169
                                i = 0;
170
                } else {
171
                        i = -1;
172
                        while (*wp++ != NULL)
173
                                ;
174
                }
175
                vp = lookup(t->str);
176
                while (setjmp(bc.brkpt))
177
                        if (isbreak)
178
                                goto broken;
179
                brkset(&bc);
180
                for (t1 = t->left; i-- && *wp != NULL;) {
181
                        setval(vp, *wp++);
182
                        rv = execute(t1, pin, pout, 0);
183
                }
184
                brklist = brklist->nextlev;
185
                break;
186
 
187
        case TWHILE:
188
        case TUNTIL:
189
                while (setjmp(bc.brkpt))
190
                        if (isbreak)
191
                                goto broken;
192
                brkset(&bc);
193
                t1 = t->left;
194
                while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE))
195
                        rv = execute(t->right, pin, pout, 0);
196
                brklist = brklist->nextlev;
197
                break;
198
 
199
        case TIF:
200
        case TELIF:
201
                if (t->right != NULL) {
202
                rv = !execute(t->left, pin, pout, 0) ?
203
                        execute(t->right->left, pin, pout, 0):
204
                        execute(t->right->right, pin, pout, 0);
205
                }
206
                break;
207
 
208
        case TCASE:
209
                if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0)
210
                        cp = "";
211
                if ((t1 = findcase(t->left, cp)) != NULL)
212
                        rv = execute(t1, pin, pout, 0);
213
                break;
214
 
215
        case TBRACE:
216
/*
217
                if (iopp = t->ioact)
218
                        while (*iopp)
219
                                if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) {
220
                                        rv = -1;
221
                                        break;
222
                                }
223
*/
224
                if (rv >= 0 && (t1 = t->left))
225
                        rv = execute(t1, pin, pout, 0);
226
                break;
227
        }
228
 
229
broken:
230
        t->words = wp2;
231
        isbreak = 0;
232
        freehere(areanum);
233
        freearea(areanum);
234
        areanum = a;
235
        if (talking && intr) {
236
                closeall();
237
                fail();
238
        }
239
        if ((i = trapset) != 0) {
240
                trapset = 0;
241
                runtrap(i);
242
        }
243
        return(rv);
244
}
245
 
246
static int
247
forkexec( register struct op *t, int *pin, int *pout, int act, char **wp, int *pforked)
248
{
249
        int i, rv;
250
        int (*shcom)() = NULL;
251
        register int f;
252
        char *cp = NULL;
253
        struct ioword **iopp;
254
        int resetsig;
255
        char **owp;
256
 
257
        int *hpin = pin;
258
        int *hpout = pout;
259
        int hforked;
260
        char *hwp;
261
        int htalking;
262
        int hintr;
263
        struct brkcon * hbrklist;
264
        int hexecflg;
265
 
266
        owp = wp;
267
        resetsig = 0;
268
        *pforked = 0;
269
        rv = -1;        /* system-detected error */
270
        if (t->type == TCOM) {
271
                while ((cp = *wp++) != NULL)
272
                        ;
273
                cp = *wp;
274
 
275
                /* strip all initial assignments */
276
                /* not correct wrt PATH=yyy command  etc */
277
                if (flag['x'])
278
                        echo (cp ? wp: owp);
279
                if (cp == NULL && t->ioact == NULL) {
280
                        while ((cp = *owp++) != NULL && assign(cp, COPYV))
281
                                ;
282
                        return(setstatus(0));
283
                }
284
                else if (cp != NULL)
285
                        shcom = inbuilt(cp);
286
        }
287
        t->words = wp;
288
        f = act;
289
        if (shcom == NULL && (f & FEXEC) == 0) {
290
 
291
                hpin = pin;
292
                hpout = pout;
293
                hforked = *pforked;
294
                hwp = *wp;
295
                htalking = talking;
296
                hintr = intr;
297
                hbrklist = brklist;
298
                hexecflg = execflg;
299
 
300
                i = vfork();
301
                if (i != 0) {
302
                        /* who wrote this crappy non vfork safe shit? */
303
                        pin = hpin;
304
                        pout = hpout;
305
                        *pforked = hforked;
306
                        *wp = hwp;
307
                        talking = htalking;
308
                        intr = hintr;
309
                        brklist = hbrklist;
310
                        execflg = hexecflg;
311
 
312
                        *pforked = 0;
313
                        if (i == -1)
314
                                return(rv);
315
                        if (pin != NULL)
316
                                closepipe(pin);
317
                        return(pout==NULL? setstatus(waitfor(i,0)): 0);
318
                }
319
 
320
                if (talking) {
321
                        signal(SIGINT, SIG_IGN);
322
                        signal(SIGQUIT, SIG_IGN);
323
                        resetsig = 1;
324
                }
325
                talking = 0;
326
                intr = 0;
327
                (*pforked)++;
328
                brklist = 0;
329
                execflg = 0;
330
        }
331
        if (owp != NULL)
332
                while ((cp = *owp++) != NULL && assign(cp, COPYV))
333
                        if (shcom == NULL)
334
                                export(lookup(cp));
335
#ifdef COMPIPE
336
        if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) {
337
                err("piping to/from shell builtins not yet done");
338
                return(-1);
339
        }
340
#endif
341
        if (pin != NULL) {
342
                dup2(pin[0], 0);
343
                closepipe(pin);
344
        }
345
        if (pout != NULL) {
346
                dup2(pout[1], 1);
347
                closepipe(pout);
348
        }
349
        if ((iopp = t->ioact) != NULL) {
350
                if (shcom != NULL && shcom != doexec) {
351
                        prs(cp);
352
                        err(": cannot redirect shell command");
353
                        return(-1);
354
                }
355
                while (*iopp)
356
                        if (iosetup(*iopp++, pin!=NULL, pout!=NULL))
357
                                return(rv);
358
        }
359
        if (shcom)
360
                return(setstatus((*shcom)(t)));
361
        /* should use FIOCEXCL */
362
        for (i=FDBASE; i<NOFILE; i++)
363
                close(i);
364
        if (resetsig) {
365
                signal(SIGINT, SIG_DFL);
366
                signal(SIGQUIT, SIG_DFL);
367
        }
368
        if (t->type == TPAREN)
369
                exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));
370
        if (wp[0] == NULL)
371
                exit(0);
372
 
373
        cp = rexecve(wp[0], wp, makenv());
374
        prs(wp[0]); prs(": "); warn(cp);
375
        if (!execflg)
376
                trap[0] = NULL;
377
        leave();
378
        /* NOTREACHED */
379
        exit(1);
380
}
381
 
382
/*
383
 * 0< 1> are ignored as required
384
 * within pipelines.
385
 */
386
int
387
iosetup(iop, pipein, pipeout)
388
register struct ioword *iop;
389
int pipein, pipeout;
390
{
391
        register int u = -1;
392
        char *cp=NULL, *msg;
393
 
394
        if (iop->io_unit == IODEFAULT)  /* take default */
395
                iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1;
396
        if (pipein && iop->io_unit == 0)
397
                return(0);
398
        if (pipeout && iop->io_unit == 1)
399
                return(0);
400
        msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create";
401
        if ((iop->io_flag & IOHERE) == 0) {
402
                cp = iop->io_name;
403
                if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL)
404
                        return(1);
405
        }
406
        if (iop->io_flag & IODUP) {
407
                if (cp[1] || (!digit(*cp) && *cp != '-')) {
408
                        prs(cp);
409
                        err(": illegal >& argument");
410
                        return(1);
411
                }
412
                if (*cp == '-')
413
                        iop->io_flag = IOCLOSE;
414
                iop->io_flag &= ~(IOREAD|IOWRITE);
415
        }
416
        switch (iop->io_flag) {
417
        case IOREAD:
418
                u = open(cp, 0);
419
                break;
420
 
421
        case IOHERE:
422
        case IOHERE|IOXHERE:
423
                u = herein(iop->io_name, iop->io_flag&IOXHERE);
424
                cp = "here file";
425
                break;
426
 
427
        case IOWRITE|IOCAT:
428
                if ((u = open(cp, 1)) >= 0) {
429
                        lseek(u, (long)0, 2);
430
                        break;
431
                }
432
        case IOWRITE:
433
                u = creat(cp, 0666);
434
                break;
435
 
436
        case IODUP:
437
                u = dup2(*cp-'0', iop->io_unit);
438
                break;
439
 
440
        case IOCLOSE:
441
                close(iop->io_unit);
442
                return(0);
443
        }
444
        if (u < 0) {
445
                prs(cp);
446
                prs(": cannot ");
447
                warn(msg);
448
                return(1);
449
        } else {
450
                if (u != iop->io_unit) {
451
                        dup2(u, iop->io_unit);
452
                        close(u);
453
                }
454
        }
455
        return(0);
456
}
457
 
458
static void
459
echo(wp)
460
register char **wp;
461
{
462
        register int i;
463
 
464
        prs("+");
465
        for (i=0; wp[i]; i++) {
466
                if (i)
467
                        prs(" ");
468
                prs(wp[i]);
469
        }
470
        prs("\n");
471
}
472
 
473
static struct op **
474
find1case(t, w)
475
struct op *t;
476
char *w;
477
{
478
        register struct op *t1;
479
        struct op **tp;
480
        register char **wp, *cp;
481
 
482
        if (t == NULL)
483
                return((struct op **)NULL);
484
        if (t->type == TLIST) {
485
                if ((tp = find1case(t->left, w)) != NULL)
486
                        return(tp);
487
                t1 = t->right;  /* TPAT */
488
        } else
489
                t1 = t;
490
        for (wp = t1->words; *wp;)
491
                if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp))
492
                        return(&t1->left);
493
        return((struct op **)NULL);
494
}
495
 
496
static struct op *
497
findcase(t, w)
498
struct op *t;
499
char *w;
500
{
501
        register struct op **tp;
502
 
503
        return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL);
504
}
505
 
506
/*
507
 * Enter a new loop level (marked for break/continue).
508
 */
509
static void
510
brkset(bc)
511
struct brkcon *bc;
512
{
513
        bc->nextlev = brklist;
514
        brklist = bc;
515
}
516
 
517
/*
518
 * Wait for the last process created.
519
 * Print a message for each process found
520
 * that was killed by a signal.
521
 * Ignore interrupt signals while waiting
522
 * unless `canintr' is true.
523
 */
524
int
525
waitfor(lastpid, canintr)
526
register int lastpid;
527
int canintr;
528
{
529
        register int pid, rv;
530
        int s;
531
        int oheedint = heedint;
532
 
533
        heedint = 0;
534
        rv = 0;
535
        do {
536
                pid = wait(&s);
537
                if (pid == -1) {
538
                        if (errno != EINTR || canintr)
539
                                break;
540
                } else {
541
                        if ((rv = WAITSIG(s)) != 0) {
542
                                if (rv < NSIGNAL) {
543
                                        if (signame[rv] != NULL) {
544
                                                if (pid != lastpid) {
545
                                                        prn(pid);
546
                                                        prs(": ");
547
                                                }
548
                                                prs(signame[rv]);
549
                                        }
550
                                } else {
551
                                        if (pid != lastpid) {
552
                                                prn(pid);
553
                                                prs(": ");
554
                                        }
555
                                        prs("Signal "); prn(rv); prs(" ");
556
                                }
557
                                if (WAITCORE(s))
558
                                        prs(" - core dumped");
559
                                if (rv >= NSIGNAL || signame[rv])
560
                                        prs("\n");
561
                                rv = -1;
562
                        } else
563
                                rv = WAITVAL(s);
564
                }
565
        } while (pid != lastpid);
566
        heedint = oheedint;
567
        if (intr) {
568
                if (talking) {
569
                        if (canintr)
570
                                intr = 0;
571
                } else {
572
                        if (exstat == 0) exstat = rv;
573
                        onintr(0);
574
                }
575
        }
576
        return(rv);
577
}
578
 
579
int
580
setstatus(s)
581
register int s;
582
{
583
        exstat = s;
584
        setval(lookup("?"), putn(s));
585
        return(s);
586
}
587
 
588
/*
589
 * PATH-searching interface to execve.
590
 * If getenv("PATH") were kept up-to-date,
591
 * execvp might be used.
592
 */
593
char *
594
rexecve(c, v, envp)
595
char *c, **v, **envp;
596
{
597
        register int i;
598
        register char *sp, *tp;
599
        int eacces = 0, asis = 0;
600
 
601
        sp = any('/', c)? "": path->value;
602
        asis = *sp == '\0';
603
        while (asis || *sp != '\0') {
604
                asis = 0;
605
                tp = e.linep;
606
                for (; *sp != '\0'; tp++)
607
                        if ((*tp = *sp++) == ':') {
608
                                asis = *sp == '\0';
609
                                break;
610
                        }
611
                if (tp != e.linep)
612
                        *tp++ = '/';
613
                for (i = 0; (*tp++ = c[i++]) != '\0';)
614
                        ;
615
                execve(e.linep, v, envp);
616
                switch (errno) {
617
                case ENOEXEC:
618
                        *v = e.linep;
619
                        tp = *--v;
620
                        *v = e.linep;
621
                        execve("/bin/sh", v, envp);
622
                        *v = tp;
623
                        return("no Shell");
624
 
625
                case ENOMEM:
626
                        return("program too big");
627
 
628
                case E2BIG:
629
                        return("argument list too long");
630
 
631
                case EACCES:
632
                        eacces++;
633
                        break;
634
                }
635
        }
636
        return(errno==ENOENT ? "not found" : "cannot execute");
637
}
638
 
639
/*
640
 * Run the command produced by generator `f'
641
 * applied to stream `arg'.
642
 */
643
int
644
run(argp, f)
645
struct ioarg *argp;
646
int (*f)();
647
{
648
        struct op *otree;
649
        struct wdblock *swdlist;
650
        struct wdblock *siolist;
651
        jmp_buf ev, rt;
652
        xint *ofail;
653
        int rv;
654
 
655
        areanum++;
656
        swdlist = wdlist;
657
        siolist = iolist;
658
        otree = outtree;
659
        ofail = failpt;
660
        rv = -1;
661
        if (newenv(setjmp(errpt = ev)) == 0) {
662
                wdlist = 0;
663
                iolist = 0;
664
                pushio(argp, f);
665
                e.iobase = e.iop;
666
                yynerrs = 0;
667
                if (setjmp(failpt = rt) == 0 && yyparse() == 0)
668
                        rv = execute(outtree, NOPIPE, NOPIPE, 0);
669
                quitenv();
670
        }
671
        wdlist = swdlist;
672
        iolist = siolist;
673
        failpt = ofail;
674
        outtree = otree;
675
        freearea(areanum--);
676
        return(rv);
677
}
678
 
679
/* -------- do.c -------- */
680
/* #include "sh.h" */
681
 
682
/*
683
 * built-in commands: doX
684
 */
685
 
686
int
687
dolabel()
688
{
689
        return(0);
690
}
691
 
692
int
693
dochdir(t)
694
register struct op *t;
695
{
696
        register char *cp, *er;
697
 
698
        if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL)
699
                er = ": no home directory";
700
        else if(chdir(cp) < 0)
701
                er = ": bad directory";
702
        else
703
                return(0);
704
        prs(cp != NULL? cp: "cd");
705
        err(er);
706
        return(1);
707
}
708
 
709
int
710
doshift(t)
711
register struct op *t;
712
{
713
        register int n;
714
 
715
        n = t->words[1]? getn(t->words[1]): 1;
716
        if(dolc < n) {
717
                err("nothing to shift");
718
                return(1);
719
        }
720
        dolv[n] = dolv[0];
721
        dolv += n;
722
        dolc -= n;
723
        setval(lookup("#"), putn(dolc));
724
        return(0);
725
}
726
 
727
/*
728
 * execute login and newgrp directly
729
 */
730
int
731
dologin(t)
732
struct op *t;
733
{
734
        register char *cp;
735
 
736
        if (talking) {
737
                signal(SIGINT, SIG_DFL);
738
                signal(SIGQUIT, SIG_DFL);
739
        }
740
        cp = rexecve(t->words[0], t->words, makenv());
741
        prs(t->words[0]); prs(": "); err(cp);
742
        return(1);
743
}
744
 
745
int
746
doumask(t)
747
register struct op *t;
748
{
749
        register int i, n;
750
        register char *cp;
751
 
752
        if ((cp = t->words[1]) == NULL) {
753
                i = umask(0);
754
                umask(i);
755
                for (n=3*4; (n-=3) >= 0;)
756
                        putc('0'+((i>>n)&07), stderr);
757
                putc('\n', stderr);
758
        } else {
759
                for (n=0; *cp>='0' && *cp<='9'; cp++)
760
                        n = n*8 + (*cp-'0');
761
                umask(n);
762
        }
763
        return(0);
764
}
765
 
766
int
767
doexec(t)
768
register struct op *t;
769
{
770
        register int i;
771
        jmp_buf ex;
772
        xint *ofail;
773
 
774
        t->ioact = NULL;
775
        for(i = 0; (t->words[i]=t->words[i+1]) != NULL; i++)
776
                ;
777
        if (i == 0)
778
                return(1);
779
        execflg = 1;
780
        ofail = failpt;
781
        if (setjmp(failpt = ex) == 0)
782
                execute(t, NOPIPE, NOPIPE, FEXEC);
783
        failpt = ofail;
784
        execflg = 0;
785
        return(1);
786
}
787
 
788
int
789
dodot(t)
790
struct op *t;
791
{
792
        register int i;
793
        register char *sp, *tp;
794
        char *cp;
795
 
796
        if ((cp = t->words[1]) == NULL)
797
                return(0);
798
        sp = any('/', cp)? ":": path->value;
799
        while (*sp) {
800
                tp = e.linep;
801
                while (*sp && (*tp = *sp++) != ':')
802
                        tp++;
803
                if (tp != e.linep)
804
                        *tp++ = '/';
805
                for (i = 0; (*tp++ = cp[i++]) != '\0';)
806
                        ;
807
                if ((i = open(e.linep, 0)) >= 0) {
808
                        exstat = 0;
809
                        next(remap(i));
810
                        return(exstat);
811
                }
812
        }
813
        prs(cp);
814
        err(": not found");
815
        return(-1);
816
}
817
 
818
int
819
dowait(t)
820
struct op *t;
821
{
822
        register int i;
823
        register char *cp;
824
 
825
        if ((cp = t->words[1]) != NULL) {
826
                i = getn(cp);
827
                if (i == 0)
828
                        return(0);
829
        } else
830
                i = -1;
831
        setstatus(waitfor(i, 1));
832
        return(0);
833
}
834
 
835
int
836
doread(t)
837
struct op *t;
838
{
839
        register char *cp, **wp;
840
        register int nb = 0;
841
        register int  nl = 0;
842
 
843
        if (t->words[1] == NULL) {
844
                err("Usage: read name ...");
845
                return(1);
846
        }
847
        for (wp = t->words+1; *wp; wp++) {
848
                for (cp = e.linep; !nl && cp < elinep-1; cp++)
849
                        if ((nb = read(0, cp, sizeof(*cp))) != sizeof(*cp) ||
850
                            (nl = (*cp == '\n')) ||
851
                            (wp[1] && any(*cp, ifs->value)))
852
                                break;
853
                *cp = 0;
854
                if (nb <= 0)
855
                        break;
856
                setval(lookup(*wp), e.linep);
857
        }
858
        return(nb <= 0);
859
}
860
 
861
int
862
doeval(t)
863
register struct op *t;
864
{
865
        return(RUN(awordlist, t->words+1, wdchar));
866
}
867
 
868
int
869
dotrap(t)
870
register struct op *t;
871
{
872
        register int  n, i;
873
        register int  resetsig;
874
 
875
        if (t->words[1] == NULL) {
876
                for (i=0; i<=_NSIG; i++)
877
                        if (trap[i]) {
878
                                prn(i);
879
                                prs(": ");
880
                                prs(trap[i]);
881
                                prs("\n");
882
                        }
883
                return(0);
884
        }
885
        resetsig = digit(*t->words[1]);
886
        for (i = resetsig ? 1 : 2; t->words[i] != NULL; ++i) {
887
                n = getsig(t->words[i]);
888
                xfree(trap[n]);
889
                trap[n] = 0;
890
                if (!resetsig) {
891
                        if (*t->words[1] != '\0') {
892
                                trap[n] = strsave(t->words[1], 0);
893
                                setsig(n, sig);
894
                        } else
895
                                setsig(n, SIG_IGN);
896
                } else {
897
                        if (talking)
898
                                if (n == SIGINT)
899
                                        setsig(n, onintr);
900
                                else
901
                                        setsig(n, n == SIGQUIT ? SIG_IGN
902
                                                               : SIG_DFL);
903
                        else
904
                                setsig(n, SIG_DFL);
905
                }
906
        }
907
        return(0);
908
}
909
 
910
int
911
getsig(s)
912
char *s;
913
{
914
        register int n;
915
 
916
        if ((n = getn(s)) < 0 || n > _NSIG) {
917
                err("trap: bad signal number");
918
                n = 0;
919
        }
920
        return(n);
921
}
922
 
923
void
924
setsig( register int n, void (*f)(int))
925
{
926
        if (n == 0)
927
                return;
928
        if (signal(n, SIG_IGN) != SIG_IGN || ourtrap[n]) {
929
                ourtrap[n] = 1;
930
                signal(n, f);
931
        }
932
}
933
 
934
int
935
getn(as)
936
char *as;
937
{
938
        register char *s;
939
        register int n, m;
940
 
941
        s = as;
942
        m = 1;
943
        if (*s == '-') {
944
                m = -1;
945
                s++;
946
        }
947
        for (n = 0; digit(*s); s++)
948
                n = (n*10) + (*s-'0');
949
        if (*s) {
950
                prs(as);
951
                err(": bad number");
952
        }
953
        return(n*m);
954
}
955
 
956
int
957
dobreak(t)
958
struct op *t;
959
{
960
        return(brkcontin(t->words[1], 1));
961
}
962
 
963
int
964
docontinue(t)
965
struct op *t;
966
{
967
        return(brkcontin(t->words[1], 0));
968
}
969
 
970
static int
971
brkcontin(cp, val)
972
register char *cp;
973
int val;
974
{
975
        register struct brkcon *bc;
976
        register int nl;
977
 
978
        nl = cp == NULL? 1: getn(cp);
979
        if (nl <= 0)
980
                nl = 999;
981
        do {
982
                if ((bc = brklist) == NULL)
983
                        break;
984
                brklist = bc->nextlev;
985
        } while (--nl);
986
        if (nl) {
987
                err("bad break/continue level");
988
                return(1);
989
        }
990
        isbreak = val;
991
        longjmp(bc->brkpt, 1);
992
        /* NOTREACHED */
993
}
994
 
995
int
996
doexit(t)
997
struct op *t;
998
{
999
        register char *cp;
1000
 
1001
        execflg = 0;
1002
        if ((cp = t->words[1]) != NULL)
1003
                setstatus(getn(cp));
1004
        leave();
1005
        /* NOTREACHED */
1006
        return(0);
1007
}
1008
 
1009
int
1010
doexport(t)
1011
struct op *t;
1012
{
1013
        rdexp(t->words+1, export, EXPORT);
1014
        return(0);
1015
}
1016
 
1017
int
1018
doreadonly(t)
1019
struct op *t;
1020
{
1021
        rdexp(t->words+1, ronly, RONLY);
1022
        return(0);
1023
}
1024
 
1025
static void
1026
rdexp(wp, f, key)
1027
register char **wp;
1028
void (*f)();
1029
int key;
1030
{
1031
        if (*wp != NULL) {
1032
                for (; *wp != NULL; wp++)
1033
                        if (checkname(*wp))
1034
                                (*f)(lookup(*wp));
1035
                        else
1036
                                badid(*wp);
1037
        } else
1038
                putvlist(key, 1);
1039
}
1040
 
1041
static void
1042
badid(s)
1043
register char *s;
1044
{
1045
        prs(s);
1046
        err(": bad identifier");
1047
}
1048
 
1049
int
1050
doset(t)
1051
register struct op *t;
1052
{
1053
        register struct var *vp;
1054
        register char *cp;
1055
        register int n;
1056
 
1057
        if ((cp = t->words[1]) == NULL) {
1058
                for (vp = vlist; vp; vp = vp->next)
1059
                        varput(vp->name, 1);
1060
                return(0);
1061
        }
1062
        if (*cp == '-') {
1063
                /* bad: t->words++; */
1064
                for(n = 0; (t->words[n]=t->words[n+1]) != NULL; n++)
1065
                        ;
1066
                if (*++cp == 0)
1067
                        flag['x'] = flag['v'] = 0;
1068
                else
1069
                        for (; *cp; cp++)
1070
                                switch (*cp) {
1071
                                case 'e':
1072
                                        if (!talking)
1073
                                                flag['e']++;
1074
                                        break;
1075
 
1076
                                default:
1077
                                        if (*cp>='a' && *cp<='z')
1078
                                                flag[(int)*cp]++;
1079
                                        break;
1080
                                }
1081
                setdash();
1082
        }
1083
        if (t->words[1]) {
1084
                t->words[0] = dolv[0];
1085
                for (n=1; t->words[n]; n++)
1086
                        setarea((char *)t->words[n], 0);
1087
                dolc = n-1;
1088
                dolv = t->words;
1089
                setval(lookup("#"), putn(dolc));
1090
                setarea((char *)(dolv-1), 0);
1091
        }
1092
        return(0);
1093
}
1094
 
1095
void
1096
varput(s, out)
1097
register char *s;
1098
int out;
1099
{
1100
        if (letnum(*s)) {
1101
                write(out, s, strlen(s));
1102
                write(out, "\n", 1);
1103
        }
1104
}
1105
 
1106
 
1107
#define SECS    60L
1108
#define MINS    3600L
1109
 
1110
int
1111
dotimes()
1112
{
1113
        struct tms tbuf;
1114
 
1115
        times(&tbuf);
1116
 
1117
        prn((int)(tbuf.tms_cutime / MINS));
1118
        prs("m");
1119
        prn((int)((tbuf.tms_cutime % MINS) / SECS));
1120
        prs("s ");
1121
        prn((int)(tbuf.tms_cstime / MINS));
1122
        prs("m");
1123
        prn((int)((tbuf.tms_cstime % MINS) / SECS));
1124
        prs("s\n");
1125
        return(0);
1126
}
1127
 
1128
struct  builtin {
1129
        char    *command;
1130
        int     (*fn)();
1131
};
1132
static struct   builtin builtin[] = {
1133
    {":",               dolabel},
1134
    {"cd",              dochdir},
1135
    {"shift",   doshift},
1136
    {"exec",            doexec},
1137
    {"wait",            dowait},
1138
    {"read",            doread},
1139
    {"eval",            doeval},
1140
    {"trap",            dotrap},
1141
    {"break",   dobreak},
1142
    {"continue",        docontinue},
1143
    {"exit",            doexit},
1144
    {"export",  doexport},
1145
    {"readonly",        doreadonly},
1146
    {"set",             doset},
1147
    {".",               dodot},
1148
    {"umask",   doumask},
1149
    {"login",   dologin},
1150
    {"newgrp",  dologin},
1151
    {"times",   dotimes},
1152
    {0,0}
1153
};
1154
 
1155
int (*inbuilt(s))()
1156
register char *s;
1157
{
1158
        register struct builtin *bp;
1159
 
1160
        for (bp = builtin; bp->command != NULL; bp++)
1161
                if (strcmp(bp->command, s) == 0)
1162
                        return(bp->fn);
1163
        return((int(*)())NULL);
1164
}
1165
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.