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

Subversion Repositories or1k

[/] [or1k/] [tags/] [initial/] [uclinux/] [userland/] [sh/] [sh1.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 <stdio.h>
6
#include <errno.h>
7
#include <setjmp.h>
8
#include <stdlib.h>
9
#include "sh.h"
10
 
11
/* Globals */
12
char    **dolv;
13
int     dolc;
14
int     exstat;
15
char    gflg;
16
int     talking;        /* interactive (talking-type wireless) */
17
int     execflg;
18
int     multiline;      /* \n changed to ; */
19
struct  op      *outtree;       /* result from parser */
20
xint    *failpt;
21
xint    *errpt;
22
struct  brkcon  *brklist;
23
int     isbreak;
24
struct  wdblock *wdlist;
25
struct  wdblock *iolist;
26
char    *trap[_NSIG+1];
27
char    ourtrap[_NSIG+1];
28
int     trapset;        /* trap pending */
29
int     yynerrs;        /* yacc */
30
char    line[LINELIM];
31
struct  var     *vlist;         /* dictionary */
32
struct  var     *homedir;       /* home directory */
33
struct  var     *prompt;        /* main prompt */
34
struct  var     *cprompt;       /* continuation prompt */
35
struct  var     *path;          /* search path for commands */
36
struct  var     *shell;         /* shell to interpret command files */
37
struct  var     *ifs;           /* field separators */
38
struct  ioarg ioargstack[NPUSH];
39
struct  io      iostack[NPUSH];
40
int     areanum;        /* current allocation area */
41
 
42
 
43
/* -------- sh.c -------- */
44
/*
45
 * shell
46
 */
47
 
48
/* #include "sh.h" */
49
 
50
int     intr;
51
int     inparse;
52
char    flags['z'-'a'+1];
53
char    *flag = flags-'a';
54
char    *elinep = line+sizeof(line)-5;
55
char    *null   = "";
56
int     heedint =1;
57
struct  env     e ={line, iostack, iostack-1,
58
                    (xint *)NULL, FDBASE, (struct env *)NULL};
59
 
60
extern  char    **environ;      /* environment pointer */
61
 
62
/*
63
 * default shell, search rules
64
 */
65
char    shellname[] = "/bin/sh";
66
char    search[] = ":/bin:/usr/bin";
67
 
68
void (*qflag)(int) = SIG_IGN;
69
//_PROTOTYPE(void (*qflag), (int)) = SIG_IGN;
70
 
71
int main(int argc, char **argv);
72
int newfile(char *s);
73
static char *findeq(char *cp);
74
static char *cclass(char *p, int sub);
75
static void initarea(void);
76
 
77
 
78
#undef abort
79
#define abort() exit(1)
80
int main(argc, argv)
81
int argc;
82
register char **argv;
83
{
84
        register int f;
85
        register char *s;
86
        int cflag;
87
        char *name, **ap;
88
        int (*iof)();
89
        initarea();
90
 
91
        if ((ap = environ) != NULL) {
92
                while (*ap)
93
                        assign(*ap++, !COPYV);
94
                for (ap = environ; *ap;)
95
                        export(lookup(*ap++));
96
        }
97
        closeall();
98
        areanum = 1;
99
 
100
        shell = lookup("SHELL");
101
        if (shell->value == null)
102
                setval(shell, shellname);
103
        export(shell);
104
 
105
        homedir = lookup("HOME");
106
        if (homedir->value == null)
107
                setval(homedir, "/");
108
        export(homedir);
109
 
110
        setval(lookup("$"), itoa(getpid(), 5));
111
 
112
        path = lookup("PATH");
113
        if (path->value == null)
114
                setval(path, search);
115
        export(path);
116
 
117
        ifs = lookup("IFS");
118
        if (ifs->value == null)
119
                setval(ifs, " \t\n");
120
 
121
        prompt = lookup("PS1");
122
        if (prompt->value == null)
123
#ifndef UNIXSHELL
124
                setval(prompt, "$ ");
125
#else
126
                setval(prompt, "% ");
127
#endif
128
 
129
        if (geteuid() == 0) {
130
                setval(prompt, "# ");
131
                prompt->status &= ~EXPORT;
132
        }
133
        cprompt = lookup("PS2");
134
        if (cprompt->value == null)
135
                setval(cprompt, "> ");
136
 
137
        iof = filechar;
138
        cflag = 0;
139
        name = *argv++;
140
        if (--argc >= 1) {
141
                if(argv[0][0] == '-' && argv[0][1] != '\0') {
142
                        for (s = argv[0]+1; *s; s++)
143
                                switch (*s) {
144
                                case 'c':
145
                                        prompt->status &= ~EXPORT;
146
                                        cprompt->status &= ~EXPORT;
147
                                        setval(prompt, "");
148
                                        setval(cprompt, "");
149
                                        cflag = 1;
150
                                        if (--argc > 0)
151
                                                PUSHIO(aword, *++argv, iof = nlchar);
152
                                        break;
153
 
154
                                case 'q':
155
                                        qflag = SIG_DFL;
156
                                        break;
157
 
158
                                case 's':
159
                                        /* standard input */
160
                                        break;
161
 
162
                                case 't':
163
                                        prompt->status &= ~EXPORT;
164
                                        setval(prompt, "");
165
                                        iof = linechar;
166
                                        break;
167
 
168
                                case 'i':
169
                                        talking++;
170
                                default:
171
                                        if (*s>='a' && *s<='z')
172
                                                flag[(int)*s]++;
173
                                }
174
                } else {
175
                        argv--;
176
                        argc++;
177
                }
178
                if (iof == filechar && --argc > 0) {
179
                        setval(prompt, "");
180
                        setval(cprompt, "");
181
                        prompt->status &= ~EXPORT;
182
                        cprompt->status &= ~EXPORT;
183
                        if (newfile(name = *++argv))
184
                                exit(1);
185
                }
186
        }
187
        setdash();
188
        if (e.iop < iostack) {
189
                PUSHIO(afile, 0, iof);
190
                if (isatty(0) && isatty(1) && !cflag)
191
                        talking++;
192
        }
193
        signal(SIGQUIT, qflag);
194
        if (name && name[0] == '-') {
195
                talking++;
196
                if ((f = open(".profile", 0)) >= 0)
197
                        next(remap(f));
198
                if ((f = open("/etc/profile", 0)) >= 0)
199
                        next(remap(f));
200
        }
201
        if (talking)
202
                signal(SIGTERM, sig);
203
        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
204
                signal(SIGINT, onintr);
205
        dolv = argv;
206
        dolc = argc;
207
        dolv[0] = name;
208
        if (dolc > 1) {
209
                for (ap = ++argv; --argc > 0;) {
210
                        if (assign(*ap = *argv++, !COPYV)) {
211
                                dolc--; /* keyword */
212
                        } else {
213
                                ap++;
214
                        }
215
                }
216
        }
217
        setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc));
218
 
219
        for (;;) {
220
                if (talking && e.iop <= iostack)
221
                        prs(prompt->value);
222
                onecommand();
223
        }
224
}
225
 
226
void
227
setdash()
228
{
229
        register char *cp;
230
        register int c;
231
        char m['z'-'a'+1];
232
 
233
        cp = m;
234
        for (c='a'; c<='z'; c++)
235
                if (flag[c])
236
                        *cp++ = c;
237
        *cp = 0;
238
        setval(lookup("-"), m);
239
}
240
 
241
int
242
newfile(s)
243
register char *s;
244
{
245
        register int f;
246
 
247
        if (strcmp(s, "-") != 0) {
248
                f = open(s, 0);
249
                if (f < 0) {
250
                        prs(s);
251
                        err(": cannot open");
252
                        return(1);
253
                }
254
        } else
255
                f = 0;
256
        next(remap(f));
257
        return(0);
258
}
259
 
260
void
261
onecommand()
262
{
263
        register int i;
264
        jmp_buf m1;
265
 
266
        while (e.oenv)
267
                quitenv();
268
        areanum = 1;
269
        freehere(areanum);
270
        freearea(areanum);
271
        garbage();
272
        wdlist = 0;
273
        iolist = 0;
274
        e.errpt = 0;
275
        e.linep = line;
276
        yynerrs = 0;
277
        multiline = 0;
278
        inparse = 1;
279
        intr = 0;
280
        execflg = 0;
281
        setjmp(failpt = m1);    /* Bruce Evans' fix */
282
        if (setjmp(failpt = m1) || yyparse() || intr) {
283
                while (e.oenv)
284
                        quitenv();
285
                scraphere();
286
                if (!talking && intr)
287
                        leave();
288
                inparse = 0;
289
                intr = 0;
290
                return;
291
        }
292
        inparse = 0;
293
        brklist = 0;
294
        intr = 0;
295
        execflg = 0;
296
        if (!flag['n'])
297
                execute(outtree, NOPIPE, NOPIPE, 0);
298
        if (!talking && intr) {
299
                execflg = 0;
300
                leave();
301
        }
302
        if ((i = trapset) != 0) {
303
                trapset = 0;
304
                runtrap(i);
305
        }
306
}
307
 
308
void
309
fail()
310
{
311
        longjmp(failpt, 1);
312
        /* NOTREACHED */
313
}
314
 
315
void
316
leave()
317
{
318
        if (execflg)
319
                fail();
320
        scraphere();
321
        freehere(1);
322
        runtrap(0);
323
        exit(exstat);
324
        /* NOTREACHED */
325
}
326
 
327
void
328
warn(s)
329
register char *s;
330
{
331
        if(*s) {
332
                prs(s);
333
                exstat = -1;
334
        }
335
        prs("\n");
336
        if (flag['e'])
337
                leave();
338
}
339
 
340
void
341
err(s)
342
char *s;
343
{
344
        warn(s);
345
        if (flag['n'])
346
                return;
347
        if (!talking)
348
                leave();
349
        if (e.errpt)
350
                longjmp(e.errpt, 1);
351
        closeall();
352
        e.iop = e.iobase = iostack;
353
}
354
 
355
int
356
newenv(f)
357
int f;
358
{
359
        register struct env *ep;
360
 
361
        if (f) {
362
                quitenv();
363
                return(1);
364
        }
365
        ep = (struct env *) space(sizeof(*ep));
366
        if (ep == NULL) {
367
                while (e.oenv)
368
                        quitenv();
369
                fail();
370
        }
371
        *ep = e;
372
        e.oenv = ep;
373
        e.errpt = errpt;
374
        return(0);
375
}
376
 
377
void
378
quitenv()
379
{
380
        register struct env *ep;
381
        register int fd;
382
 
383
        if ((ep = e.oenv) != NULL) {
384
                fd = e.iofd;
385
                e = *ep;
386
                /* should close `'d files */
387
                DELETE(ep);
388
                while (--fd >= e.iofd)
389
                        close(fd);
390
        }
391
}
392
 
393
/*
394
 * Is any character from s1 in s2?
395
 */
396
int
397
anys(s1, s2)
398
register char *s1, *s2;
399
{
400
        while (*s1)
401
                if (any(*s1++, s2))
402
                        return(1);
403
        return(0);
404
}
405
 
406
/*
407
 * Is character c in s?
408
 */
409
int
410
any(c, s)
411
register int c;
412
register char *s;
413
{
414
        while (*s)
415
                if (*s++ == c)
416
                        return(1);
417
        return(0);
418
}
419
 
420
char *
421
putn(n)
422
register int n;
423
{
424
        return(itoa(n, -1));
425
}
426
 
427
char *
428
itoa(u, n)
429
register unsigned u;
430
int n;
431
{
432
        register char *cp;
433
        static char s[20];
434
        int m;
435
 
436
        m = 0;
437
        if (n < 0 && (int) u < 0) {
438
                m++;
439
                u = -u;
440
        }
441
        cp = s+sizeof(s);
442
        *--cp = 0;
443
        do {
444
                *--cp = u%10 + '0';
445
                u /= 10;
446
        } while (--n > 0 || u);
447
        if (m)
448
                *--cp = '-';
449
        return(cp);
450
}
451
 
452
void
453
next(f)
454
int f;
455
{
456
        PUSHIO(afile, f, filechar);
457
}
458
 
459
void
460
onintr(s)
461
int s;                          /* ANSI C requires a parameter */
462
{
463
        signal(SIGINT, onintr);
464
        intr = 1;
465
        if (talking) {
466
                if (inparse) {
467
                        prs("\n");
468
                        fail();
469
                }
470
        }
471
        else if (heedint) {
472
                execflg = 0;
473
                leave();
474
        }
475
}
476
 
477
int
478
letter(c)
479
register int c;
480
{
481
        return((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
482
}
483
 
484
int
485
digit(c)
486
register int c;
487
{
488
        return(c >= '0' && c <= '9');
489
}
490
 
491
int
492
letnum(c)
493
register int c;
494
{
495
        return(letter(c) || digit(c));
496
}
497
 
498
char *
499
space(n)
500
int n;
501
{
502
        register char *cp;
503
 
504
        if ((cp = getcell(n)) == 0)
505
                err("out of string space");
506
        return(cp);
507
}
508
 
509
char *
510
strsave(s, a)
511
register char *s;
512
int a;
513
{
514
        register char *cp, *xp;
515
 
516
        if ((cp = space(strlen(s)+1)) != NULL) {
517
                setarea((char *)cp, a);
518
                for (xp = cp; (*xp++ = *s++) != '\0';)
519
                        ;
520
                return(cp);
521
        }
522
        return("");
523
}
524
 
525
void
526
xfree(s)
527
register char *s;
528
{
529
        DELETE(s);
530
}
531
 
532
/*
533
 * trap handling
534
 */
535
void
536
sig(i)
537
register int i;
538
{
539
        trapset = i;
540
        signal(i, sig);
541
}
542
 
543
void runtrap(i)
544
int i;
545
{
546
        char *trapstr;
547
 
548
        if ((trapstr = trap[i]) == NULL)
549
                return;
550
        if (i == 0)
551
                trap[i] = 0;
552
        RUN(aword, trapstr, nlchar);
553
}
554
 
555
/* -------- var.c -------- */
556
/* #include "sh.h" */
557
 
558
/*
559
 * Find the given name in the dictionary
560
 * and return its value.  If the name was
561
 * not previously there, enter it now and
562
 * return a null value.
563
 */
564
struct var *
565
lookup(n)
566
register char *n;
567
{
568
        register struct var *vp;
569
        register char *cp;
570
        register int c;
571
        static struct var dummy;
572
 
573
        if (digit(*n)) {
574
                dummy.name = n;
575
                for (c = 0; digit(*n) && c < 1000; n++)
576
                        c = c*10 + *n-'0';
577
                dummy.status = RONLY;
578
                dummy.value = c <= dolc? dolv[c]: null;
579
                return(&dummy);
580
        }
581
        for (vp = vlist; vp; vp = vp->next)
582
                if (eqname(vp->name, n))
583
                        return(vp);
584
        cp = findeq(n);
585
        vp = (struct var *)space(sizeof(*vp));
586
        if (vp == 0 || (vp->name = space((int)(cp-n)+2)) == 0) {
587
                dummy.name = dummy.value = "";
588
                return(&dummy);
589
        }
590
        for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++)
591
                ;
592
        if (*cp == 0)
593
                *cp = '=';
594
        *++cp = 0;
595
        setarea((char *)vp, 0);
596
        setarea((char *)vp->name, 0);
597
        vp->value = null;
598
        vp->next = vlist;
599
        vp->status = GETCELL;
600
        vlist = vp;
601
        return(vp);
602
}
603
 
604
/*
605
 * give variable at `vp' the value `val'.
606
 */
607
void
608
setval(vp, val)
609
struct var *vp;
610
char *val;
611
{
612
        nameval(vp, val, (char *)NULL);
613
}
614
 
615
/*
616
 * if name is not NULL, it must be
617
 * a prefix of the space `val',
618
 * and end with `='.
619
 * this is all so that exporting
620
 * values is reasonably painless.
621
 */
622
void
623
nameval(vp, val, name)
624
register struct var *vp;
625
char *val, *name;
626
{
627
        register char *cp, *xp;
628
        char *nv;
629
        int fl;
630
 
631
        if (vp->status & RONLY) {
632
                for (xp = vp->name; *xp && *xp != '=';)
633
                        putc(*xp++, stderr);
634
                err(" is read-only");
635
                return;
636
        }
637
        fl = 0;
638
        if (name == NULL) {
639
                xp = space(strlen(vp->name)+strlen(val)+2);
640
                if (xp == 0)
641
                        return;
642
                /* make string:  name=value */
643
                setarea((char *)xp, 0);
644
                name = xp;
645
                for (cp = vp->name; (*xp = *cp++) && *xp!='='; xp++)
646
                        ;
647
                if (*xp++ == 0)
648
                        xp[-1] = '=';
649
                nv = xp;
650
                for (cp = val; (*xp++ = *cp++) != '\0';)
651
                        ;
652
                val = nv;
653
                fl = GETCELL;
654
        }
655
        if (vp->status & GETCELL)
656
                xfree(vp->name);        /* form new string `name=value' */
657
        vp->name = name;
658
        vp->value = val;
659
        vp->status |= fl;
660
}
661
 
662
void
663
export(vp)
664
struct var *vp;
665
{
666
        vp->status |= EXPORT;
667
}
668
 
669
void
670
ronly(vp)
671
struct var *vp;
672
{
673
        if (letter(vp->name[0])) /* not an internal symbol ($# etc) */
674
                vp->status |= RONLY;
675
}
676
 
677
int
678
isassign(s)
679
register char *s;
680
{
681
        if (!letter((int)*s))
682
                return(0);
683
        for (; *s != '='; s++)
684
                if (*s == 0 || !letnum(*s))
685
                        return(0);
686
        return(1);
687
}
688
 
689
int
690
assign(s, cf)
691
register char *s;
692
int cf;
693
{
694
        register char *cp;
695
        struct var *vp;
696
 
697
        if (!letter(*s))
698
                return(0);
699
        for (cp = s; *cp != '='; cp++)
700
                if (*cp == 0 || !letnum(*cp))
701
                        return(0);
702
        vp = lookup(s);
703
        nameval(vp, ++cp, cf == COPYV? (char *)NULL: s);
704
        if (cf != COPYV)
705
                vp->status &= ~GETCELL;
706
        return(1);
707
}
708
 
709
int
710
checkname(cp)
711
register char *cp;
712
{
713
        if (!letter(*cp++))
714
                return(0);
715
        while (*cp)
716
                if (!letnum(*cp++))
717
                        return(0);
718
        return(1);
719
}
720
 
721
void
722
putvlist(f, out)
723
register int f, out;
724
{
725
        register struct var *vp;
726
 
727
        for (vp = vlist; vp; vp = vp->next)
728
                if (vp->status & f && letter(*vp->name)) {
729
                        if (vp->status & EXPORT)
730
                                write(out, "export ", 7);
731
                        if (vp->status & RONLY)
732
                                write(out, "readonly ", 9);
733
                        write(out, vp->name, (int)(findeq(vp->name) - vp->name));
734
                        write(out, "\n", 1);
735
                }
736
}
737
 
738
int
739
eqname(n1, n2)
740
register char *n1, *n2;
741
{
742
        for (; *n1 != '=' && *n1 != 0; n1++)
743
                if (*n2++ != *n1)
744
                        return(0);
745
        return(*n2 == 0 || *n2 == '=');
746
}
747
 
748
static char *
749
findeq(cp)
750
register char *cp;
751
{
752
        while (*cp != '\0' && *cp != '=')
753
                cp++;
754
        return(cp);
755
}
756
 
757
/* -------- gmatch.c -------- */
758
/*
759
 * int gmatch(string, pattern)
760
 * char *string, *pattern;
761
 *
762
 * Match a pattern as in sh(1).
763
 */
764
 
765
#define CMASK   0377
766
#define QUOTE   0200
767
#define QMASK   (CMASK&~QUOTE)
768
#define NOT     '!'     /* might use ^ */
769
 
770
int
771
gmatch(s, p)
772
register char *s, *p;
773
{
774
        register int sc, pc;
775
 
776
        if (s == NULL || p == NULL)
777
                return(0);
778
        while ((pc = *p++ & CMASK) != '\0') {
779
                sc = *s++ & QMASK;
780
                switch (pc) {
781
                case '[':
782
                        if ((p = cclass(p, sc)) == NULL)
783
                                return(0);
784
                        break;
785
 
786
                case '?':
787
                        if (sc == 0)
788
                                return(0);
789
                        break;
790
 
791
                case '*':
792
                        s--;
793
                        do {
794
                                if (*p == '\0' || gmatch(s, p))
795
                                        return(1);
796
                        } while (*s++ != '\0');
797
                        return(0);
798
 
799
                default:
800
                        if (sc != (pc&~QUOTE))
801
                                return(0);
802
                }
803
        }
804
        return(*s == 0);
805
}
806
 
807
static char *
808
cclass(p, sub)
809
register char *p;
810
register int sub;
811
{
812
        register int c, d, not, found;
813
 
814
        if ((not = *p == NOT) != 0)
815
                p++;
816
        found = not;
817
        do {
818
                if (*p == '\0')
819
                        return((char *)NULL);
820
                c = *p & CMASK;
821
                if (p[1] == '-' && p[2] != ']') {
822
                        d = p[2] & CMASK;
823
                        p++;
824
                } else
825
                        d = c;
826
                if (c == sub || (c <= sub && sub <= d))
827
                        found = !not;
828
        } while (*++p != ']');
829
        return(found? p+1: (char *)NULL);
830
}
831
 
832
 
833
//#if 0
834
 
835
 
836
/* -------- area.c -------- */
837
#define REGSIZE         sizeof(struct region)
838
#define GROWBY          256
839
#undef  SHRINKBY        64
840
#define FREE 32767
841
#define BUSY 0
842
#define ALIGN (sizeof(int)-1)
843
 
844
/* #include "area.h" */
845
 
846
struct region {
847
        struct  region *next;
848
        int     area;
849
};
850
 
851
/*
852
 * All memory between (char *)areabot and (char *)(areatop+1) is
853
 * exclusively administered by the area management routines.
854
 * It is assumed that sbrk() and brk() manipulate the high end.
855
 */
856
static  struct region *areabot;         /* bottom of area */
857
static  struct region *areatop;         /* top of area */
858
static  struct region *areanxt;         /* starting point of scan */
859
static void * brktop;
860
static void * brkaddr;
861
 
862
//#define sbrk(X) ({ void * __q = -1; if (brkaddr + (int)(X) < brktop) { __q = brkaddr; brkaddr+=(int)(X); } __q;})
863
 
864
static void
865
initarea()
866
{
867
        brkaddr = malloc(65000);
868
        brktop = brkaddr + 65000;
869
 
870
        while ((int)sbrk(0) & ALIGN)
871
                sbrk(1);
872
        areabot = (struct region *)sbrk(REGSIZE);
873
 
874
        areabot->next = areabot;
875
        areabot->area = BUSY;
876
        areatop = areabot;
877
        areanxt = areabot;
878
}
879
 
880
char *
881
getcell(nbytes)
882
unsigned nbytes;
883
{
884
        register int nregio;
885
        register struct region *p, *q;
886
        register int i;
887
 
888
        if (nbytes == 0) {
889
                puts("Boo");
890
                abort();
891
        }       /* silly and defeats the algorithm */
892
        /*
893
         * round upwards and add administration area
894
         */
895
        nregio = (nbytes+(REGSIZE-1))/REGSIZE + 1;
896
        for (p = areanxt;;) {
897
                if (p->area > areanum) {
898
                        /*
899
                         * merge free cells
900
                         */
901
                        while ((q = p->next)->area > areanum && q != areanxt)
902
                                p->next = q->next;
903
                        /*
904
                         * exit loop if cell big enough
905
                         */
906
                        if (q >= p + nregio)
907
                                goto found;
908
                }
909
                p = p->next;
910
                if (p == areanxt)
911
                        break;
912
        }
913
        i = nregio >= GROWBY ? nregio : GROWBY;
914
        p = (struct region *)sbrk(i * REGSIZE);
915
        if (p == (struct region *)-1)
916
                return((char *)NULL);
917
        p--;
918
        if (p != areatop) {
919
                puts("not contig");
920
                abort();        /* allocated areas are contiguous */
921
        }
922
        q = p + i;
923
        p->next = q;
924
        p->area = FREE;
925
        q->next = areabot;
926
        q->area = BUSY;
927
        areatop = q;
928
found:
929
        /*
930
         * we found a FREE area big enough, pointed to by 'p', and up to 'q'
931
         */
932
        areanxt = p + nregio;
933
        if (areanxt < q) {
934
                /*
935
                 * split into requested area and rest
936
                 */
937
                if (areanxt+1 > q) {
938
                        puts("OOM");
939
                        abort();        /* insufficient space left for admin */
940
                }
941
                areanxt->next = q;
942
                areanxt->area = FREE;
943
                p->next = areanxt;
944
        }
945
        p->area = areanum;
946
        return((char *)(p+1));
947
}
948
 
949
void
950
freecell(cp)
951
char *cp;
952
{
953
        register struct region *p;
954
 
955
        if ((p = (struct region *)cp) != NULL) {
956
                p--;
957
                if (p < areanxt)
958
                        areanxt = p;
959
                p->area = FREE;
960
        }
961
}
962
 
963
void
964
freearea(a)
965
register int a;
966
{
967
        register struct region *p, *top;
968
 
969
        top = areatop;
970
        for (p = areabot; p != top; p = p->next)
971
                if (p->area >= a)
972
                        p->area = FREE;
973
}
974
 
975
void
976
setarea(cp,a)
977
char *cp;
978
int a;
979
{
980
        register struct region *p;
981
 
982
        if ((p = (struct region *)cp) != NULL)
983
                (p-1)->area = a;
984
}
985
 
986
int
987
getarea(cp)
988
char *cp;
989
{
990
        return ((struct region*)cp-1)->area;
991
}
992
 
993
void
994
garbage()
995
{
996
        register struct region *p, *q, *top;
997
 
998
        top = areatop;
999
        for (p = areabot; p != top; p = p->next) {
1000
                if (p->area > areanum) {
1001
                        while ((q = p->next)->area > areanum)
1002
                                p->next = q->next;
1003
                        areanxt = p;
1004
                }
1005
        }
1006
#ifdef SHRINKBY
1007
        if (areatop >= q + SHRINKBY && q->area > areanum) {
1008
                brk((char *)(q+1));
1009
                q->next = areabot;
1010
                q->area = BUSY;
1011
                areatop = q;
1012
        }
1013
#endif
1014
}
1015
 
1016
//#endif

powered by: WebSVN 2.1.0

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