sh1.c

Go to the documentation of this file.
00001 #define Extern extern
00002 #include <sys/types.h>
00003 #include <signal.h>
00004 #include <errno.h>
00005 #include <setjmp.h>
00006 #include "sh.h"
00007 /* -------- sh.c -------- */
00008 /*
00009  * shell
00010  */
00011 
00012 /* #include "sh.h" */
00013 
00014 int     intr;
00015 int     inparse;
00016 char    flags['z'-'a'+1];
00017 char    *flag = flags-'a';
00018 char    *elinep = line+sizeof(line)-5;
00019 char    *null   = "";
00020 int     heedint =1;
00021 struct  env     e ={line, iostack, iostack-1,
00022                     (xint *)NULL, FDBASE, (struct env *)NULL};
00023 
00024 extern  char    **environ;      /* environment pointer */
00025 
00026 /*
00027  * default shell, search rules
00028  */
00029 char    shellname[] = "/bin/sh";
00030 char    search[] = ":/bin:/usr/bin";
00031 
00032 _PROTOTYPE(void (*qflag), (int)) = SIG_IGN;
00033 
00034 _PROTOTYPE(int main, (int argc, char **argv ));
00035 _PROTOTYPE(int newfile, (char *s ));
00036 _PROTOTYPE(static char *findeq, (char *cp ));
00037 _PROTOTYPE(static char *cclass, (char *p, int sub ));
00038 _PROTOTYPE(void initarea, (void));
00039 
00040 int main(argc, argv)
00041 int argc;
00042 register char **argv;
00043 {
00044         register int f;
00045         register char *s;
00046         int cflag;
00047         char *name, **ap;
00048         int (*iof)();
00049 
00050         initarea();
00051         if ((ap = environ) != NULL) {
00052                 while (*ap)
00053                         assign(*ap++, !COPYV);
00054                 for (ap = environ; *ap;)
00055                         export(lookup(*ap++));
00056         }
00057         closeall();
00058         areanum = 1;
00059 
00060         shell = lookup("SHELL");
00061         if (shell->value == null)
00062                 setval(shell, shellname);
00063         export(shell);
00064 
00065         homedir = lookup("HOME");
00066         if (homedir->value == null)
00067                 setval(homedir, "/");
00068         export(homedir);
00069 
00070         setval(lookup("$"), itoa(getpid(), 5));
00071 
00072         path = lookup("PATH");
00073         if (path->value == null)
00074                 setval(path, search);
00075         export(path);
00076 
00077         ifs = lookup("IFS");
00078         if (ifs->value == null)
00079                 setval(ifs, " \t\n");
00080 
00081         prompt = lookup("PS1");
00082         if (prompt->value == null)
00083 #ifndef UNIXSHELL
00084                 setval(prompt, "$ ");
00085 #else
00086                 setval(prompt, "% ");
00087 #endif
00088 
00089         if (geteuid() == 0) {
00090                 setval(prompt, "# ");
00091                 prompt->status &= ~EXPORT;
00092         }
00093         cprompt = lookup("PS2");
00094         if (cprompt->value == null)
00095                 setval(cprompt, "> ");
00096 
00097         iof = filechar;
00098         cflag = 0;
00099         name = *argv++;
00100         if (--argc >= 1) {
00101                 if(argv[0][0] == '-' && argv[0][1] != '\0') {
00102                         for (s = argv[0]+1; *s; s++)
00103                                 switch (*s) {
00104                                 case 'c':
00105                                         prompt->status &= ~EXPORT;
00106                                         cprompt->status &= ~EXPORT;
00107                                         setval(prompt, "");
00108                                         setval(cprompt, "");
00109                                         cflag = 1;
00110                                         if (--argc > 0)
00111                                                 PUSHIO(aword, *++argv, iof = nlchar);
00112                                         break;
00113         
00114                                 case 'q':
00115                                         qflag = SIG_DFL;
00116                                         break;
00117 
00118                                 case 's':
00119                                         /* standard input */
00120                                         break;
00121 
00122                                 case 't':
00123                                         prompt->status &= ~EXPORT;
00124                                         setval(prompt, "");
00125                                         iof = linechar;
00126                                         break;
00127         
00128                                 case 'i':
00129                                         talking++;
00130                                 default:
00131                                         if (*s>='a' && *s<='z')
00132                                                 flag[*s]++;
00133                                 }
00134                 } else {
00135                         argv--;
00136                         argc++;
00137                 }
00138                 if (iof == filechar && --argc > 0) {
00139                         setval(prompt, "");
00140                         setval(cprompt, "");
00141                         prompt->status &= ~EXPORT;
00142                         cprompt->status &= ~EXPORT;
00143                         if (newfile(name = *++argv))
00144                                 exit(1);
00145                 }
00146         }
00147         setdash();
00148         if (e.iop < iostack) {
00149                 PUSHIO(afile, 0, iof);
00150                 if (isatty(0) && isatty(1) && !cflag)
00151                         talking++;
00152         }
00153         signal(SIGQUIT, qflag);
00154         if (name && name[0] == '-') {
00155                 talking++;
00156                 if ((f = open(".profile", 0)) >= 0)
00157                         next(remap(f));
00158                 if ((f = open("/etc/profile", 0)) >= 0)
00159                         next(remap(f));
00160         }
00161         if (talking)
00162                 signal(SIGTERM, sig);
00163         if (signal(SIGINT, SIG_IGN) != SIG_IGN)
00164                 signal(SIGINT, onintr);
00165         dolv = argv;
00166         dolc = argc;
00167         dolv[0] = name;
00168         if (dolc > 1)
00169                 for (ap = ++argv; --argc > 0;)
00170                         if (assign(*ap = *argv++, !COPYV))
00171                                 dolc--; /* keyword */
00172                         else
00173                                 ap++;
00174         setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc));
00175 
00176         for (;;) {
00177                 if (talking && e.iop <= iostack)
00178                         prs(prompt->value);
00179                 onecommand();
00180         }
00181 }
00182 
00183 void
00184 setdash()
00185 {
00186         register char *cp, c;
00187         char m['z'-'a'+1];
00188 
00189         cp = m;
00190         for (c='a'; c<='z'; c++)
00191                 if (flag[c])
00192                         *cp++ = c;
00193         *cp = 0;
00194         setval(lookup("-"), m);
00195 }
00196 
00197 int
00198 newfile(s)
00199 register char *s;
00200 {
00201         register f;
00202 
00203         if (strcmp(s, "-") != 0) {
00204                 f = open(s, 0);
00205                 if (f < 0) {
00206                         prs(s);
00207                         err(": cannot open");
00208                         return(1);
00209                 }
00210         } else
00211                 f = 0;
00212         next(remap(f));
00213         return(0);
00214 }
00215 
00216 void
00217 onecommand()
00218 {
00219         register i;
00220         jmp_buf m1;
00221 
00222         while (e.oenv)
00223                 quitenv();
00224         areanum = 1;
00225         freehere(areanum);
00226         freearea(areanum);
00227         garbage();
00228         wdlist = 0;
00229         iolist = 0;
00230         e.errpt = 0;
00231         e.linep = line;
00232         yynerrs = 0;
00233         multiline = 0;
00234         inparse = 1;
00235         intr = 0;
00236         execflg = 0;
00237         setjmp(failpt = m1);    /* Bruce Evans' fix */
00238         if (setjmp(failpt = m1) || yyparse() || intr) {
00239                 while (e.oenv)
00240                         quitenv();
00241                 scraphere();
00242                 if (!talking && intr)
00243                         leave();
00244                 inparse = 0;
00245                 intr = 0;
00246                 return;
00247         }
00248         inparse = 0;
00249         brklist = 0;
00250         intr = 0;
00251         execflg = 0;
00252         if (!flag['n'])
00253                 execute(outtree, NOPIPE, NOPIPE, 0);
00254         if (!talking && intr) {
00255                 execflg = 0;
00256                 leave();
00257         }
00258         if ((i = trapset) != 0) {
00259                 trapset = 0;
00260                 runtrap(i);
00261         }
00262 }
00263 
00264 void
00265 fail()
00266 {
00267         longjmp(failpt, 1);
00268         /* NOTREACHED */
00269 }
00270 
00271 void
00272 leave()
00273 {
00274         if (execflg)
00275                 fail();
00276         scraphere();
00277         freehere(1);
00278         runtrap(0);
00279         exit(exstat);
00280         /* NOTREACHED */
00281 }
00282 
00283 void
00284 warn(s)
00285 register char *s;
00286 {
00287         if(*s) {
00288                 prs(s);
00289                 exstat = -1;
00290         }
00291         prs("\n");
00292         if (flag['e'])
00293                 leave();
00294 }
00295 
00296 void
00297 err(s)
00298 char *s;
00299 {
00300         warn(s);
00301         if (flag['n'])
00302                 return;
00303         if (!talking)
00304                 leave();
00305         if (e.errpt)
00306                 longjmp(e.errpt, 1);
00307         closeall();
00308         e.iop = e.iobase = iostack;
00309 }
00310 
00311 int
00312 newenv(f)
00313 int f;
00314 {
00315         register struct env *ep;
00316 
00317         if (f) {
00318                 quitenv();
00319                 return(1);
00320         }
00321         ep = (struct env *) space(sizeof(*ep));
00322         if (ep == NULL) {
00323                 while (e.oenv)
00324                         quitenv();
00325                 fail();
00326         }
00327         *ep = e;
00328         e.oenv = ep;
00329         e.errpt = errpt;
00330         return(0);
00331 }
00332 
00333 void
00334 quitenv()
00335 {
00336         register struct env *ep;
00337         register fd;
00338 
00339         if ((ep = e.oenv) != NULL) {
00340                 fd = e.iofd;
00341                 e = *ep;
00342                 /* should close `'d files */
00343                 DELETE(ep);
00344                 while (--fd >= e.iofd)
00345                         close(fd);
00346         }
00347 }
00348 
00349 /*
00350  * Is any character from s1 in s2?
00351  */
00352 int
00353 anys(s1, s2)
00354 register char *s1, *s2;
00355 {
00356         while (*s1)
00357                 if (any(*s1++, s2))
00358                         return(1);
00359         return(0);
00360 }
00361 
00362 /*
00363  * Is character c in s?
00364  */
00365 int
00366 any(c, s)
00367 register int c;
00368 register char *s;
00369 {
00370         while (*s)
00371                 if (*s++ == c)
00372                         return(1);
00373         return(0);
00374 }
00375 
00376 char *
00377 putn(n)
00378 register int n;
00379 {
00380         return(itoa(n, -1));
00381 }
00382 
00383 char *
00384 itoa(u, n)
00385 register unsigned u;
00386 int n;
00387 {
00388         register char *cp;
00389         static char s[20];
00390         int m;
00391 
00392         m = 0;
00393         if (n < 0 && (int) u < 0) {
00394                 m++;
00395                 u = -u;
00396         }
00397         cp = s+sizeof(s);
00398         *--cp = 0;
00399         do {
00400                 *--cp = u%10 + '0';
00401                 u /= 10;
00402         } while (--n > 0 || u);
00403         if (m)
00404                 *--cp = '-';
00405         return(cp);
00406 }
00407 
00408 void
00409 next(f)
00410 int f;
00411 {
00412         PUSHIO(afile, f, filechar);
00413 }
00414 
00415 void
00416 onintr(s)
00417 int s;                          /* ANSI C requires a parameter */
00418 {
00419         signal(SIGINT, onintr);
00420         intr = 1;
00421         if (talking) {
00422                 if (inparse) {
00423                         prs("\n");
00424                         fail();
00425                 }
00426         }
00427         else if (heedint) {
00428                 execflg = 0;
00429                 leave();
00430         }
00431 }
00432 
00433 int
00434 letter(c)
00435 register c;
00436 {
00437         return((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
00438 }
00439 
00440 int
00441 digit(c)
00442 register c;
00443 {
00444         return(c >= '0' && c <= '9');
00445 }
00446 
00447 int
00448 letnum(c)
00449 register c;
00450 {
00451         return(letter(c) || digit(c));
00452 }
00453 
00454 char *
00455 space(n)
00456 int n;
00457 {
00458         register char *cp;
00459 
00460         if ((cp = getcell(n)) == 0)
00461                 err("out of string space");
00462         return(cp);
00463 }
00464 
00465 char *
00466 strsave(s, a)
00467 register char *s;
00468 int a;
00469 {
00470         register char *cp, *xp;
00471 
00472         if ((cp = space(strlen(s)+1)) != NULL) {
00473                 setarea((char *)cp, a);
00474                 for (xp = cp; (*xp++ = *s++) != '\0';)
00475                         ;
00476                 return(cp);
00477         }
00478         return("");
00479 }
00480 
00481 void
00482 xfree(s)
00483 register char *s;
00484 {
00485         DELETE(s);
00486 }
00487 
00488 /*
00489  * trap handling
00490  */
00491 void
00492 sig(i)
00493 register int i;
00494 {
00495         trapset = i;
00496         signal(i, sig);
00497 }
00498 
00499 void runtrap(i)
00500 int i;
00501 {
00502         char *trapstr;
00503 
00504         if ((trapstr = trap[i]) == NULL)
00505                 return;
00506         if (i == 0)
00507                 trap[i] = 0;
00508         RUN(aword, trapstr, nlchar);
00509 }
00510 
00511 /* -------- var.c -------- */
00512 /* #include "sh.h" */
00513 
00514 /*
00515  * Find the given name in the dictionary
00516  * and return its value.  If the name was
00517  * not previously there, enter it now and
00518  * return a null value.
00519  */
00520 struct var *
00521 lookup(n)
00522 register char *n;
00523 {
00524         register struct var *vp;
00525         register char *cp;
00526         register int c;
00527         static struct var dummy;
00528 
00529         if (digit(*n)) {
00530                 dummy.name = n;
00531                 for (c = 0; digit(*n) && c < 1000; n++)
00532                         c = c*10 + *n-'0';
00533                 dummy.status = RONLY;
00534                 dummy.value = c <= dolc? dolv[c]: null;
00535                 return(&dummy);
00536         }
00537         for (vp = vlist; vp; vp = vp->next)
00538                 if (eqname(vp->name, n))
00539                         return(vp);
00540         cp = findeq(n);
00541         vp = (struct var *)space(sizeof(*vp));
00542         if (vp == 0 || (vp->name = space((int)(cp-n)+2)) == 0) {
00543                 dummy.name = dummy.value = "";
00544                 return(&dummy);
00545         }
00546         for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++)
00547                 ;
00548         if (*cp == 0)
00549                 *cp = '=';
00550         *++cp = 0;
00551         setarea((char *)vp, 0);
00552         setarea((char *)vp->name, 0);
00553         vp->value = null;
00554         vp->next = vlist;
00555         vp->status = GETCELL;
00556         vlist = vp;
00557         return(vp);
00558 }
00559 
00560 /*
00561  * give variable at `vp' the value `val'.
00562  */
00563 void
00564 setval(vp, val)
00565 struct var *vp;
00566 char *val;
00567 {
00568         nameval(vp, val, (char *)NULL);
00569 }
00570 
00571 /*
00572  * if name is not NULL, it must be
00573  * a prefix of the space `val',
00574  * and end with `='.
00575  * this is all so that exporting
00576  * values is reasonably painless.
00577  */
00578 void
00579 nameval(vp, val, name)
00580 register struct var *vp;
00581 char *val, *name;
00582 {
00583         register char *cp, *xp;
00584         char *nv;
00585         int fl;
00586 
00587         if (vp->status & RONLY) {
00588                 for (xp = vp->name; *xp && *xp != '=';)
00589                         putc(*xp++);
00590                 err(" is read-only");
00591                 return;
00592         }
00593         fl = 0;
00594         if (name == NULL) {
00595                 xp = space(strlen(vp->name)+strlen(val)+2);
00596                 if (xp == 0)
00597                         return;
00598                 /* make string:  name=value */
00599                 setarea((char *)xp, 0);
00600                 name = xp;
00601                 for (cp = vp->name; (*xp = *cp++) && *xp!='='; xp++)
00602                         ;
00603                 if (*xp++ == 0)
00604                         xp[-1] = '=';
00605                 nv = xp;
00606                 for (cp = val; (*xp++ = *cp++) != '\0';)
00607                         ;
00608                 val = nv;
00609                 fl = GETCELL;
00610         }
00611         if (vp->status & GETCELL)
00612                 xfree(vp->name);        /* form new string `name=value' */
00613         vp->name = name;
00614         vp->value = val;
00615         vp->status |= fl;
00616 }
00617 
00618 void
00619 export(vp)
00620 struct var *vp;
00621 {
00622         vp->status |= EXPORT;
00623 }
00624 
00625 void
00626 ronly(vp)
00627 struct var *vp;
00628 {
00629         if (letter(vp->name[0]))        /* not an internal symbol ($# etc) */
00630                 vp->status |= RONLY;
00631 }
00632 
00633 int
00634 isassign(s)
00635 register char *s;
00636 {
00637         if (!letter((int)*s))
00638                 return(0);
00639         for (; *s != '='; s++)
00640                 if (*s == 0 || !letnum(*s))
00641                         return(0);
00642         return(1);
00643 }
00644 
00645 int
00646 assign(s, cf)
00647 register char *s;
00648 int cf;
00649 {
00650         register char *cp;
00651         struct var *vp;
00652 
00653         if (!letter(*s))
00654                 return(0);
00655         for (cp = s; *cp != '='; cp++)
00656                 if (*cp == 0 || !letnum(*cp))
00657                         return(0);
00658         vp = lookup(s);
00659         nameval(vp, ++cp, cf == COPYV? (char *)NULL: s);
00660         if (cf != COPYV)
00661                 vp->status &= ~GETCELL;
00662         return(1);
00663 }
00664 
00665 int
00666 checkname(cp)
00667 register char *cp;
00668 {
00669         if (!letter(*cp++))
00670                 return(0);
00671         while (*cp)
00672                 if (!letnum(*cp++))
00673                         return(0);
00674         return(1);
00675 }
00676 
00677 void
00678 putvlist(f, out)
00679 register int f, out;
00680 {
00681         register struct var *vp;
00682 
00683         for (vp = vlist; vp; vp = vp->next)
00684                 if (vp->status & f && letter(*vp->name)) {
00685                         if (vp->status & EXPORT)
00686                                 write(out, "export ", 7);
00687                         if (vp->status & RONLY)
00688                                 write(out, "readonly ", 9);
00689                         write(out, vp->name, (int)(findeq(vp->name) - vp->name));
00690                         write(out, "\n", 1);
00691                 }
00692 }
00693 
00694 int
00695 eqname(n1, n2)
00696 register char *n1, *n2;
00697 {
00698         for (; *n1 != '=' && *n1 != 0; n1++)
00699                 if (*n2++ != *n1)
00700                         return(0);
00701         return(*n2 == 0 || *n2 == '=');
00702 }
00703 
00704 static char *
00705 findeq(cp)
00706 register char *cp;
00707 {
00708         while (*cp != '\0' && *cp != '=')
00709                 cp++;
00710         return(cp);
00711 }
00712 
00713 /* -------- gmatch.c -------- */
00714 /*
00715  * int gmatch(string, pattern)
00716  * char *string, *pattern;
00717  *
00718  * Match a pattern as in sh(1).
00719  */
00720 
00721 #define CMASK   0377
00722 #define QUOTE   0200
00723 #define QMASK   (CMASK&~QUOTE)
00724 #define NOT     '!'     /* might use ^ */
00725 
00726 int
00727 gmatch(s, p)
00728 register char *s, *p;
00729 {
00730         register int sc, pc;
00731 
00732         if (s == NULL || p == NULL)
00733                 return(0);
00734         while ((pc = *p++ & CMASK) != '\0') {
00735                 sc = *s++ & QMASK;
00736                 switch (pc) {
00737                 case '[':
00738                         if ((p = cclass(p, sc)) == NULL)
00739                                 return(0);
00740                         break;
00741 
00742                 case '?':
00743                         if (sc == 0)
00744                                 return(0);
00745                         break;
00746 
00747                 case '*':
00748                         s--;
00749                         do {
00750                                 if (*p == '\0' || gmatch(s, p))
00751                                         return(1);
00752                         } while (*s++ != '\0');
00753                         return(0);
00754 
00755                 default:
00756                         if (sc != (pc&~QUOTE))
00757                                 return(0);
00758                 }
00759         }
00760         return(*s == 0);
00761 }
00762 
00763 static char *
00764 cclass(p, sub)
00765 register char *p;
00766 register int sub;
00767 {
00768         register int c, d, not, found;
00769 
00770         if ((not = *p == NOT) != 0)
00771                 p++;
00772         found = not;
00773         do {
00774                 if (*p == '\0')
00775                         return((char *)NULL);
00776                 c = *p & CMASK;
00777                 if (p[1] == '-' && p[2] != ']') {
00778                         d = p[2] & CMASK;
00779                         p++;
00780                 } else
00781                         d = c;
00782                 if (c == sub || (c <= sub && sub <= d))
00783                         found = !not;
00784         } while (*++p != ']');
00785         return(found? p+1: (char *)NULL);
00786 }
00787 
00788 /* -------- area.c -------- */
00789 #define REGSIZE         sizeof(struct region)
00790 #define GROWBY          256
00791 #undef  SHRINKBY        64
00792 #define FREE 32767
00793 #define BUSY 0
00794 #define ALIGN (sizeof(int)-1)
00795 
00796 /* #include "area.h" */
00797 
00798 struct region {
00799         struct  region *next;
00800         int     area;
00801 };
00802 
00803 /*
00804  * All memory between (char *)areabot and (char *)(areatop+1) is
00805  * exclusively administered by the area management routines.
00806  * It is assumed that sbrk() and brk() manipulate the high end.
00807  */
00808 static  struct region *areabot;         /* bottom of area */
00809 static  struct region *areatop;         /* top of area */
00810 static  struct region *areanxt;         /* starting point of scan */
00811 
00812 void
00813 initarea()
00814 {
00815         while ((int)sbrk(0) & ALIGN)
00816                 sbrk(1);
00817         areabot = (struct region *)sbrk(REGSIZE);
00818         areabot->next = areabot;
00819         areabot->area = BUSY;
00820         areatop = areabot;
00821         areanxt = areabot;
00822 }
00823 
00824 char *
00825 getcell(nbytes)
00826 unsigned nbytes;
00827 {
00828         register int nregio;
00829         register struct region *p, *q;
00830         register i;
00831 
00832         if (nbytes == 0)
00833                 abort();        /* silly and defeats the algorithm */
00834         /*
00835          * round upwards and add administration area
00836          */
00837         nregio = (nbytes+(REGSIZE-1))/REGSIZE + 1;
00838         for (p = areanxt;;) {
00839                 if (p->area > areanum) {
00840                         /*
00841                          * merge free cells
00842                          */
00843                         while ((q = p->next)->area > areanum && q != areanxt)
00844                                 p->next = q->next;
00845                         /*
00846                          * exit loop if cell big enough
00847                          */
00848                         if (q >= p + nregio)
00849                                 goto found;
00850                 }
00851                 p = p->next;
00852                 if (p == areanxt)
00853                         break;
00854         }
00855         i = nregio >= GROWBY ? nregio : GROWBY;
00856         p = (struct region *)sbrk(i * REGSIZE);
00857         if (p == (struct region *)-1)
00858                 return((char *)NULL);
00859         p--;
00860         if (p != areatop)
00861                 abort();        /* allocated areas are contiguous */
00862         q = p + i;
00863         p->next = q;
00864         p->area = FREE;
00865         q->next = areabot;
00866         q->area = BUSY;
00867         areatop = q;
00868 found:
00869         /*
00870          * we found a FREE area big enough, pointed to by 'p', and up to 'q'
00871          */
00872         areanxt = p + nregio;
00873         if (areanxt < q) {
00874                 /*
00875                  * split into requested area and rest
00876                  */
00877                 if (areanxt+1 > q)
00878                         abort();        /* insufficient space left for admin */
00879                 areanxt->next = q;
00880                 areanxt->area = FREE;
00881                 p->next = areanxt;
00882         }
00883         p->area = areanum;
00884         return((char *)(p+1));
00885 }
00886 
00887 void
00888 freecell(cp)
00889 char *cp;
00890 {
00891         register struct region *p;
00892 
00893         if ((p = (struct region *)cp) != NULL) {
00894                 p--;
00895                 if (p < areanxt)
00896                         areanxt = p;
00897                 p->area = FREE;
00898         }
00899 }
00900 
00901 void
00902 freearea(a)
00903 register int a;
00904 {
00905         register struct region *p, *top;
00906 
00907         top = areatop;
00908         for (p = areabot; p != top; p = p->next)
00909                 if (p->area >= a)
00910                         p->area = FREE;
00911 }
00912 
00913 void
00914 setarea(cp,a)
00915 char *cp;
00916 int a;
00917 {
00918         register struct region *p;
00919 
00920         if ((p = (struct region *)cp) != NULL)
00921                 (p-1)->area = a;
00922 }
00923 
00924 int
00925 getarea(cp)
00926 char *cp;
00927 {
00928         return ((struct region*)cp-1)->area;
00929 }
00930 
00931 void
00932 garbage()
00933 {
00934         register struct region *p, *q, *top;
00935 
00936         top = areatop;
00937         for (p = areabot; p != top; p = p->next) {
00938                 if (p->area > areanum) {
00939                         while ((q = p->next)->area > areanum)
00940                                 p->next = q->next;
00941                         areanxt = p;
00942                 }
00943         }
00944 #ifdef SHRINKBY
00945         if (areatop >= q + SHRINKBY && q->area > areanum) {
00946                 brk((char *)(q+1));
00947                 q->next = areabot;
00948                 q->area = BUSY;
00949                 areatop = q;
00950         }
00951 #endif
00952 }

Generated on Fri Apr 14 22:57:03 2006 for minix by  doxygen 1.4.6