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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [sh/] [sh5.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#define Extern extern
2
#include <sys/types.h>
3
#include <signal.h>
4
 
5
#include <errno.h>
6
#include <setjmp.h>
7
#include "sh.h"
8
 
9
/* -------- io.c -------- */
10
/* #include "sh.h" */
11
 
12
/*
13
 * shell IO
14
 */
15
 
16
static struct iobuf sharedbuf = {AFID_NOBUF};
17
static struct iobuf mainbuf = {AFID_NOBUF};
18
static unsigned bufid = AFID_ID;        /* buffer id counter */
19
 
20
struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};
21
 
22
static void readhere (char **name, char *s, int ec );
23
void pushio(struct ioarg *argp, int (*fn)());
24
static int xxchar(struct ioarg *ap );
25
void tempname(char *tname );
26
 
27
int my_getc( int ec)
28
{
29
        register int c;
30
 
31
        if(e.linep > elinep) {
32
                while((c=readc()) != '\n' && c)
33
                        ;
34
                err("input line too long");
35
                gflg++;
36
                return(c);
37
        }
38
        c = readc();
39
        if (ec != '\'' && e.iop->task != XGRAVE) {
40
                if(c == '\\') {
41
                        c = readc();
42
                        if (c == '\n' && ec != '\"')
43
                                return(my_getc(ec));
44
                        c |= QUOTE;
45
                }
46
        }
47
        return(c);
48
}
49
 
50
void
51
unget(c)
52
int c;
53
{
54
        if (e.iop >= e.iobase)
55
                e.iop->peekc = c;
56
}
57
 
58
int
59
eofc()
60
 
61
{
62
  return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);
63
}
64
 
65
int
66
readc()
67
{
68
        register int c;
69
 
70
        for (; e.iop >= e.iobase; e.iop--)
71
                if ((c = e.iop->peekc) != '\0') {
72
                        e.iop->peekc = 0;
73
                        return(c);
74
                }
75
                else {
76
                    if (e.iop->prev != 0) {
77
                        if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') {
78
                                if (c == -1) {
79
                                        e.iop++;
80
                                        continue;
81
                                }
82
                                if (e.iop == iostack)
83
                                        ioecho(c);
84
                                return(e.iop->prev = c);
85
                        }
86
                        else if (e.iop->task == XIO && e.iop->prev != '\n') {
87
                                e.iop->prev = 0;
88
                                if (e.iop == iostack)
89
                                        ioecho('\n');
90
                                return '\n';
91
                        }
92
                    }
93
                    if (e.iop->task == XIO) {
94
                        if (multiline)
95
                            return e.iop->prev = 0;
96
                        if (talking && e.iop == iostack+1)
97
                            prs(prompt->value);
98
                    }
99
                }
100
        if (e.iop >= iostack)
101
                return(0);
102
        leave();
103
        /* NOTREACHED */
104
        return(0);
105
}
106
 
107
void
108
ioecho(c)
109
char c;
110
{
111
        if (flag['v'])
112
                write(2, &c, sizeof c);
113
}
114
 
115
void
116
pushio(argp, fn)
117
struct ioarg *argp;
118
int (*fn)();
119
{
120
        if (++e.iop >= &iostack[NPUSH]) {
121
                e.iop--;
122
                err("Shell input nested too deeply");
123
                gflg++;
124
                return;
125
        }
126
        e.iop->iofn = fn;
127
 
128
        if (argp->afid != AFID_NOBUF)
129
          e.iop->argp = argp;
130
        else {
131
          e.iop->argp  = ioargstack + (e.iop - iostack);
132
          *e.iop->argp = *argp;
133
          e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;
134
          if (isatty(e.iop->argp->afile) == 0 &&
135
              (e.iop == &iostack[0] ||
136
               lseek(e.iop->argp->afile, 0L, 1) != -1)) {
137
            if (++bufid == AFID_NOBUF)
138
              bufid = AFID_ID;
139
            e.iop->argp->afid  = bufid;
140
          }
141
        }
142
 
143
        e.iop->prev  = ~'\n';
144
        e.iop->peekc = 0;
145
        e.iop->xchar = 0;
146
        e.iop->nlcount = 0;
147
        if (fn == filechar || fn == linechar)
148
                e.iop->task = XIO;
149
        else if (fn == gravechar || fn == qgravechar)
150
                e.iop->task = XGRAVE;
151
        else
152
                e.iop->task = XOTHER;
153
}
154
 
155
struct io *
156
setbase(ip)
157
struct io *ip;
158
{
159
        register struct io *xp;
160
 
161
        xp = e.iobase;
162
        e.iobase = ip;
163
        return(xp);
164
}
165
 
166
/*
167
 * Input generating functions
168
 */
169
 
170
/*
171
 * Produce the characters of a string, then a newline, then EOF.
172
 */
173
int
174
nlchar(ap)
175
register struct ioarg *ap;
176
{
177
        register int c;
178
 
179
        if (ap->aword == NULL)
180
                return(0);
181
        if ((c = *ap->aword++) == 0) {
182
                ap->aword = NULL;
183
                return('\n');
184
        }
185
        return(c);
186
}
187
 
188
/*
189
 * Given a list of words, produce the characters
190
 * in them, with a space after each word.
191
 */
192
int
193
wdchar(ap)
194
register struct ioarg *ap;
195
{
196
        register char c;
197
        register char **wl;
198
 
199
        if ((wl = ap->awordlist) == NULL)
200
                return(0);
201
        if (*wl != NULL) {
202
                if ((c = *(*wl)++) != 0)
203
                        return(c & 0177);
204
                ap->awordlist++;
205
                return(' ');
206
        }
207
        ap->awordlist = NULL;
208
        return('\n');
209
}
210
 
211
/*
212
 * Return the characters of a list of words,
213
 * producing a space between them.
214
 */
215
int
216
dolchar(ap)
217
register struct ioarg *ap;
218
{
219
        register char *wp;
220
 
221
        if ((wp = *ap->awordlist++) != NULL) {
222
                PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);
223
                return(-1);
224
        }
225
        return(0);
226
}
227
 
228
static int
229
xxchar(ap)
230
register struct ioarg *ap;
231
{
232
        register int c;
233
 
234
        if (ap->aword == NULL)
235
                return(0);
236
        if ((c = *ap->aword++) == '\0') {
237
                ap->aword = NULL;
238
                return(' ');
239
        }
240
        return(c);
241
}
242
 
243
/*
244
 * Produce the characters from a single word (string).
245
 */
246
int
247
strchar(ap)
248
register struct ioarg *ap;
249
{
250
        register int c;
251
 
252
        if (ap->aword == NULL || (c = *ap->aword++) == 0)
253
                return(0);
254
        return(c);
255
}
256
 
257
/*
258
 * Produce quoted characters from a single word (string).
259
 */
260
int
261
qstrchar(ap)
262
register struct ioarg *ap;
263
{
264
        register int c;
265
 
266
        if (ap->aword == NULL || (c = *ap->aword++) == 0)
267
                return(0);
268
        return(c|QUOTE);
269
}
270
 
271
/*
272
 * Return the characters from a file.
273
 */
274
int
275
filechar(ap)
276
register struct ioarg *ap;
277
{
278
        register int i;
279
        char c;
280
        struct iobuf *bp = ap->afbuf;
281
 
282
        if (ap->afid != AFID_NOBUF) {
283
          if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
284
            if (i)
285
              lseek(ap->afile, ap->afpos, 0);
286
            do {
287
              i = read(ap->afile, bp->buf, sizeof(bp->buf));
288
            } while (i < 0 && errno == EINTR);
289
            if (i <= 0) {
290
              closef(ap->afile);
291
              return 0;
292
            }
293
            bp->id = ap->afid;
294
            bp->ebufp = (bp->bufp  = bp->buf) + i;
295
          }
296
          ap->afpos++;
297
          return *bp->bufp++ & 0177;
298
        }
299
 
300
        do {
301
                i = read(ap->afile, &c, sizeof(c));
302
        } while (i < 0 && errno == EINTR);
303
        return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
304
}
305
 
306
/*
307
 * Return the characters from a here temp file.
308
 */
309
int
310
herechar(ap)
311
register struct ioarg *ap;
312
{
313
        char c;
314
 
315
 
316
        if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) {
317
                close(ap->afile);
318
                c = 0;
319
        }
320
        return (c);
321
 
322
}
323
 
324
/*
325
 * Return the characters produced by a process (`...`).
326
 * Quote them if required, and remove any trailing newline characters.
327
 */
328
int
329
gravechar(ap, iop)
330
struct ioarg *ap;
331
struct io *iop;
332
{
333
        register int c;
334
 
335
        if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')
336
                c = ' ';
337
        return(c);
338
}
339
 
340
int
341
qgravechar(ap, iop)
342
register struct ioarg *ap;
343
struct io *iop;
344
{
345
        register int c;
346
 
347
        if (iop->xchar) {
348
                if (iop->nlcount) {
349
                        iop->nlcount--;
350
                        return('\n'|QUOTE);
351
                }
352
                c = iop->xchar;
353
                iop->xchar = 0;
354
        } else if ((c = filechar(ap)) == '\n') {
355
                iop->nlcount = 1;
356
                while ((c = filechar(ap)) == '\n')
357
                        iop->nlcount++;
358
                iop->xchar = c;
359
                if (c == 0)
360
                        return(c);
361
                iop->nlcount--;
362
                c = '\n';
363
        }
364
        return(c!=0? c|QUOTE: 0);
365
}
366
 
367
/*
368
 * Return a single command (usually the first line) from a file.
369
 */
370
int
371
linechar(ap)
372
register struct ioarg *ap;
373
{
374
        register int c;
375
 
376
        if ((c = filechar(ap)) == '\n') {
377
                if (!multiline) {
378
                        closef(ap->afile);
379
                        ap->afile = -1; /* illegal value */
380
                }
381
        }
382
        return(c);
383
}
384
 
385
void
386
prs(s)
387
register char *s;
388
{
389
        if (*s)
390
                write(2, s, strlen(s));
391
}
392
 
393
void
394
prn(u)
395
unsigned u;
396
{
397
        prs(itoa(u, 0));
398
}
399
 
400
void
401
closef(i)
402
register int i;
403
{
404
        if (i > 2)
405
                close(i);
406
}
407
 
408
void
409
closeall()
410
{
411
        register int u;
412
 
413
        for (u=NUFILE; u<NOFILE;)
414
                close(u++);
415
}
416
 
417
/*
418
 * remap fd into Shell's fd space
419
 */
420
int
421
remap(fd)
422
register int fd;
423
{
424
        register int i;
425
        int map[NOFILE];
426
 
427
        if (fd < e.iofd) {
428
                for (i=0; i<NOFILE; i++)
429
                        map[i] = 0;
430
                do {
431
                        map[fd] = 1;
432
                        fd = dup(fd);
433
                } while (fd >= 0 && fd < e.iofd);
434
                for (i=0; i<NOFILE; i++)
435
                        if (map[i])
436
                                close(i);
437
                if (fd < 0)
438
                        err("too many files open in shell");
439
        }
440
        return(fd);
441
}
442
 
443
int
444
openpipe(pv)
445
register int *pv;
446
{
447
        register int i;
448
 
449
        if ((i = pipe(pv)) < 0)
450
                err("can't create pipe - try again");
451
        return(i);
452
}
453
 
454
void
455
closepipe(pv)
456
register int *pv;
457
{
458
        if (pv != NULL) {
459
                close(*pv++);
460
                close(*pv);
461
        }
462
}
463
 
464
/* -------- here.c -------- */
465
/* #include "sh.h" */
466
 
467
/*
468
 * here documents
469
 */
470
 
471
struct  here {
472
        char    *h_tag;
473
        int     h_dosub;
474
        struct  ioword *h_iop;
475
        struct  here    *h_next;
476
};
477
 
478
static  struct here *inhere;            /* list of hear docs while parsing */
479
static  struct here *acthere;           /* list of active here documents */
480
 
481
void
482
markhere(s, iop)
483
register char *s;
484
struct ioword *iop;
485
{
486
        register struct here *h, *lh;
487
 
488
        h = (struct here *) space(sizeof(struct here));
489
        if (h == 0)
490
                return;
491
        h->h_tag = evalstr(s, DOSUB);
492
        if (h->h_tag == 0)
493
                return;
494
        h->h_iop = iop;
495
        iop->io_name = 0;
496
        h->h_next = NULL;
497
        if (inhere == 0)
498
                inhere = h;
499
        else
500
                for (lh = inhere; lh!=NULL; lh = lh->h_next)
501
                        if (lh->h_next == 0) {
502
                                lh->h_next = h;
503
                                break;
504
                        }
505
        iop->io_flag |= IOHERE|IOXHERE;
506
        for (s = h->h_tag; *s; s++)
507
                if (*s & QUOTE) {
508
                        iop->io_flag &= ~ IOXHERE;
509
                        *s &= ~ QUOTE;
510
                }
511
        h->h_dosub = iop->io_flag & IOXHERE;
512
}
513
 
514
void
515
gethere()
516
{
517
        register struct here *h, *hp;
518
 
519
        /* Scan here files first leaving inhere list in place */
520
        for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
521
          readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\'');
522
 
523
        /* Make inhere list active - keep list intact for scraphere */
524
        if (hp != NULL) {
525
          hp->h_next = acthere;
526
          acthere    = inhere;
527
          inhere     = NULL;
528
        }
529
}
530
 
531
static void
532
readhere(name, s, ec)
533
char **name;
534
register char *s;
535
int ec;
536
{
537
        int tf;
538
        char tname[30];
539
        register int c;
540
        jmp_buf ev;
541
        char line [LINELIM+1];
542
        char *next;
543
 
544
        tempname(tname);
545
        *name = strsave(tname, areanum);
546
        tf = creat(tname, 0600);
547
        if (tf < 0)
548
                return;
549
        if (newenv(setjmp(errpt = ev)) != 0)
550
                unlink(tname);
551
        else {
552
                pushio(e.iop->argp, e.iop->iofn);
553
                e.iobase = e.iop;
554
                for (;;) {
555
                        if (talking && e.iop <= iostack)
556
                                prs(cprompt->value);
557
                        next = line;
558
                        while ((c = my_getc(ec)) != '\n' && c) {
559
                                if (ec == '\'')
560
                                        c &= ~ QUOTE;
561
                                if (next >= &line[LINELIM]) {
562
                                        c = 0;
563
                                        break;
564
                                }
565
                                *next++ = c;
566
                        }
567
                        *next = 0;
568
                        if (strcmp(s, line) == 0 || c == 0)
569
                                break;
570
                        *next++ = '\n';
571
                        write (tf, line, (int)(next-line));
572
                }
573
                if (c == 0) {
574
                        prs("here document `"); prs(s); err("' unclosed");
575
                }
576
                quitenv();
577
        }
578
        close(tf);
579
}
580
 
581
/*
582
 * open here temp file.
583
 * if unquoted here, expand here temp file into second temp file.
584
 */
585
int
586
herein(hname, xdoll)
587
char *hname;
588
int xdoll;
589
{
590
        register int hf, tf;
591
 
592
        if (hname == 0)
593
                return(-1);
594
        hf = open(hname, 0);
595
        if (hf < 0)
596
                return (-1);
597
        if (xdoll) {
598
                char c;
599
                char tname[30];
600
                jmp_buf ev;
601
 
602
                tempname(tname);
603
                if ((tf = creat(tname, 0600)) < 0)
604
                        return (-1);
605
                if (newenv(setjmp(errpt = ev)) == 0) {
606
                        PUSHIO(afile, hf, herechar);
607
                        setbase(e.iop);
608
                        while ((c = subgetc(0, 0)) != 0) {
609
                                c &= ~ QUOTE;
610
                                write(tf, &c, sizeof c);
611
                        }
612
                        quitenv();
613
                } else
614
                        unlink(tname);
615
                close(tf);
616
                tf = open(tname, 0);
617
                unlink(tname);
618
                return (tf);
619
        } else
620
                return (hf);
621
}
622
 
623
void
624
scraphere()
625
{
626
        register struct here *h;
627
 
628
        for (h = inhere; h != NULL; h = h->h_next) {
629
                if (h->h_iop && h->h_iop->io_name)
630
                  unlink(h->h_iop->io_name);
631
        }
632
        inhere = NULL;
633
}
634
 
635
/* unlink here temp files before a freearea(area) */
636
void
637
freehere(area)
638
int area;
639
{
640
        register struct here *h, *hl;
641
 
642
        hl = NULL;
643
        for (h = acthere; h != NULL; h = h->h_next)
644
                if (getarea((char *) h) >= area) {
645
                        if (h->h_iop->io_name != NULL)
646
                                unlink(h->h_iop->io_name);
647
                        if (hl == NULL)
648
                                acthere = h->h_next;
649
                        else
650
                                hl->h_next = h->h_next;
651
                } else
652
                        hl = h;
653
}
654
 
655
void
656
tempname(tname)
657
char *tname;
658
{
659
        static int inc;
660
        register char *cp, *lp;
661
 
662
        for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++)
663
                ;
664
        lp = putn(getpid()*1000 + inc++);
665
        for (; (*cp = *lp++) != '\0'; cp++)
666
                ;
667
}

powered by: WebSVN 2.1.0

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