# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/pdx/library.c

##### Functions

    back              X
    backv             X
    call              X
    callv             X
    catcherrs         X
    cmp               X
    errmsg            X
    error             X
    fatal             X
    fswap             X
    mov               X
    numerrors         X
    numwarnings       X
    onsyserr          X
    panic             X
    pfind             X
    pwait             X
    shell             X
    syserr            X
    warning           X

##### Variables

    cmdname           X
    errfilename       X
    errlineno         X
    nerrs             X
    nwarnings         X
    pidlist           X
    public            X

##### Macros

    BADEXEC           X
    DEF_SHELL         X
    ERR_CATCH         X
    ERR_IGNORE        X
    MAXNARGS          X
    alloc             X
    and               X
    dispose           X
    get               X
    ischild           X
    nil               X
    not               X
    or                X
    ord               X
    private           X
    public            X
    put               X
    strdup            X
    streq             X

##### struct's

    pidlist           X

##### typedef's

    Filename          X
    Pidlist           X
    String            X

       1: /*
       2:  * Copyright (c) 1982 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #ifndef lint
       8: static char sccsid[] = "@(#)library.c	5.1 (Berkeley) 6/7/85";
       9: #endif not lint
      10:
      11: /*
      12:  * General purpose routines.
      13:  */
      14:
      15: #include <stdio.h>
      16: #include <errno.h>
      17:
      18: #define public
      19: #define private static
      20: #define and &&
      21: #define or ||
      22: #define not !
      23: #define ord(enumcon)    ((int) enumcon)
      24: #define nil(type)   ((type) 0)
      25:
      26: typedef enum { FALSE, TRUE } Boolean;
      27: typedef char *String;
      28: typedef FILE *File;
      29: typedef String Filename;
      30:
      31: #undef FILE
      32:
      33: /*
      34:  * Definitions of standard C library routines that aren't in the
      35:  * standard I/O library, but which are generally useful.
      36:  */
      37:
      38: extern long atol();     /* ascii to long */
      39: extern double atof();       /* ascii to floating point */
      40: extern char *mktemp();      /* make a temporary file name */
      41:
      42: String cmdname;         /* name of command for error messages */
      43: Filename errfilename;       /* current file associated with error */
      44: short errlineno;        /* line number associated with error */
      45:
      46: /*
      47:  * Definitions for doing memory allocation.
      48:  */
      49:
      50: extern char *malloc();
      51:
      52: #define alloc(n, type)  ((type *) malloc((unsigned) (n) * sizeof(type)))
      53: #define dispose(p)  { free((char *) p); p = 0; }
      54:
      55: /*
      56:  * Macros for doing freads + fwrites.
      57:  */
      58:
      59: #define get(fp, var)    fread((char *) &(var), sizeof(var), 1, fp)
      60: #define put(fp, var)    fwrite((char *) &(var), sizeof(var), 1, fp)
      61:
      62: /*
      63:  * String definitions.
      64:  */
      65:
      66: extern String strcpy(), index(), rindex();
      67: extern int strlen();
      68:
      69: #define strdup(s)       strcpy(malloc((unsigned) strlen(s) + 1), s)
      70: #define streq(s1, s2)   (strcmp(s1, s2) == 0)
      71:
      72: typedef int INTFUNC();
      73:
      74: typedef struct {
      75:     INTFUNC *func;
      76: } ERRINFO;
      77:
      78: #define ERR_IGNORE ((INTFUNC *) 0)
      79: #define ERR_CATCH  ((INTFUNC *) 1)
      80:
      81: /*
      82:  * Call a program.
      83:  *
      84:  * Four entries:
      85:  *
      86:  *	call, callv - call a program and wait for it, returning status
      87:  *	back, backv - call a program and don't wait, returning process id
      88:  *
      89:  * The command's standard input and output are passed as FILE's.
      90:  */
      91:
      92:
      93: #define MAXNARGS 100    /* unchecked upper limit on max num of arguments */
      94: #define BADEXEC 127 /* exec fails */
      95:
      96: #define ischild(pid)    ((pid) == 0)
      97:
      98: /* VARARGS3 */
      99: public int call(name, in, out, args)
     100: String name;
     101: File in;
     102: File out;
     103: String args;
     104: {
     105:     String *ap, *argp;
     106:     String argv[MAXNARGS];
     107:
     108:     argp = &argv[0];
     109:     *argp++ = name;
     110:     ap = &args;
     111:     while (*ap != nil(String)) {
     112:     *argp++ = *ap++;
     113:     }
     114:     *argp = nil(String);
     115:     return callv(name, in, out, argv);
     116: }
     117:
     118: /* VARARGS3 */
     119: public int back(name, in, out, args)
     120: String name;
     121: File in;
     122: File out;
     123: String args;
     124: {
     125:     String *ap, *argp;
     126:     String argv[MAXNARGS];
     127:
     128:     argp = &argv[0];
     129:     *argp++ = name;
     130:     ap = &args;
     131:     while (*ap != nil(String)) {
     132:     *argp++ = *ap++;
     133:     }
     134:     *argp = nil(String);
     135:     return backv(name, in, out, argv);
     136: }
     137:
     138: public int callv(name, in, out, argv)
     139: String name;
     140: File in;
     141: File out;
     142: String *argv;
     143: {
     144:     int pid, status;
     145:
     146:     pid = backv(name, in, out, argv);
     147:     pwait(pid, &status);
     148:     return status;
     149: }
     150:
     151: public int backv(name, in, out, argv)
     152: String name;
     153: File in;
     154: File out;
     155: String *argv;
     156: {
     157:     int pid;
     158:
     159:     fflush(stdout);
     160:     if (ischild(pid = fork())) {
     161:     fswap(0, fileno(in));
     162:     fswap(1, fileno(out));
     163:     onsyserr(EACCES, ERR_IGNORE);
     164:     execvp(name, argv);
     165:     _exit(BADEXEC);
     166:     }
     167:     return pid;
     168: }
     169:
     170: /*
     171:  * Swap file numbers so as to redirect standard input and output.
     172:  */
     173:
     174: private fswap(oldfd, newfd)
     175: int oldfd;
     176: int newfd;
     177: {
     178:     if (oldfd != newfd) {
     179:     close(oldfd);
     180:     dup(newfd);
     181:     close(newfd);
     182:     }
     183: }
     184:
     185: /*
     186:  * Invoke a shell on a command line.
     187:  */
     188:
     189: #define DEF_SHELL   "csh"
     190:
     191: public shell(s)
     192: String s;
     193: {
     194:     extern String getenv();
     195:     String sh;
     196:
     197:     if ((sh = getenv("SHELL")) == nil(String)) {
     198:     sh = DEF_SHELL;
     199:     }
     200:     call(sh, stdin, stdout, "-c", s, 0);
     201: }
     202:
     203: /*
     204:  * Wait for a process the right way.  We wait for a particular
     205:  * process and if any others come along in between, we remember them
     206:  * in case they are eventually waited for.
     207:  *
     208:  * This routine is not very efficient when the number of processes
     209:  * to be remembered is large.
     210:  */
     211:
     212: typedef struct pidlist {
     213:     int pid;
     214:     int status;
     215:     struct pidlist *next;
     216: } Pidlist;
     217:
     218: private Pidlist *pidlist, *pfind();
     219:
     220: public pwait(pid, statusp)
     221: int pid, *statusp;
     222: {
     223:     Pidlist *p;
     224:     int pnum, status;
     225:
     226:     p = pfind(pid);
     227:     if (p != nil(Pidlist *)) {
     228:         *statusp = p->status;
     229:         dispose(p);
     230:         return;
     231:     }
     232:     while ((pnum = wait(&status)) != pid && pnum >= 0) {
     233:         p = alloc(1, Pidlist);
     234:         p->pid = pnum;
     235:         p->status = status;
     236:         p->next = pidlist;
     237:         pidlist = p;
     238:     }
     239:     if (pnum < 0) {
     240:         p = pfind(pid);
     241:         if (p == nil(Pidlist *)) {
     242:         panic("pwait: pid %d not found", pid);
     243:         }
     244:         *statusp = p->status;
     245:         dispose(p);
     246:     } else {
     247:         *statusp = status;
     248:     }
     249: }
     250:
     251: /*
     252:  * Look for the given process id on the pidlist.
     253:  *
     254:  * Unlink it from list if found.
     255:  */
     256:
     257: private Pidlist *pfind(pid)
     258: int pid;
     259: {
     260:     register Pidlist *p, *prev;
     261:
     262:     prev = nil(Pidlist *);
     263:     for (p = pidlist; p != nil(Pidlist *); p = p->next) {
     264:     if (p->pid == pid) {
     265:         break;
     266:     }
     267:     prev = p;
     268:     }
     269:     if (p != nil(Pidlist *)) {
     270:     if (prev == nil(Pidlist *)) {
     271:         pidlist = p->next;
     272:     } else {
     273:         prev->next = p->next;
     274:     }
     275:     }
     276:     return p;
     277: }
     278:
     279: /*
     280:  * System call error handler.
     281:  *
     282:  * The syserr routine is called when a system call is about to
     283:  * set the c-bit to report an error.  Certain errors are caught
     284:  * and cause the process to print a message and immediately exit.
     285:  */
     286:
     287: extern int sys_nerr;
     288: extern char *sys_errlist[];
     289:
     290: /*
     291:  * Before calling syserr, the integer errno is set to contain the
     292:  * number of the error.  The routine "_mycerror" is a dummy which
     293:  * is used to force the loader to get my version of cerror rather
     294:  * than the usual one.
     295:  */
     296:
     297: extern int errno;
     298: extern _mycerror();
     299:
     300: /*
     301:  * default error handling
     302:  */
     303:
     304: private ERRINFO errinfo[] ={
     305: /* no error */  ERR_IGNORE,
     306: /* EPERM */ ERR_IGNORE,
     307: /* ENOENT */    ERR_IGNORE,
     308: /* ESRCH */ ERR_IGNORE,
     309: /* EINTR */ ERR_CATCH,
     310: /* EIO */   ERR_CATCH,
     311: /* ENXIO */ ERR_CATCH,
     312: /* E2BIG */ ERR_CATCH,
     313: /* ENOEXEC */   ERR_CATCH,
     314: /* EBADF */ ERR_IGNORE,
     315: /* ECHILD */    ERR_CATCH,
     316: /* EAGAIN */    ERR_CATCH,
     317: /* ENOMEM */    ERR_CATCH,
     318: /* EACCES */    ERR_CATCH,
     319: /* EFAULT */    ERR_CATCH,
     320: /* ENOTBLK */   ERR_CATCH,
     321: /* EBUSY */ ERR_CATCH,
     322: /* EEXIST */    ERR_CATCH,
     323: /* EXDEV */ ERR_CATCH,
     324: /* ENODEV */    ERR_CATCH,
     325: /* ENOTDIR */   ERR_CATCH,
     326: /* EISDIR */    ERR_CATCH,
     327: /* EINVAL */    ERR_CATCH,
     328: /* ENFILE */    ERR_CATCH,
     329: /* EMFILE */    ERR_CATCH,
     330: /* ENOTTY */    ERR_IGNORE,
     331: /* ETXTBSY */   ERR_CATCH,
     332: /* EFBIG */ ERR_CATCH,
     333: /* ENOSPC */    ERR_CATCH,
     334: /* ESPIPE */    ERR_CATCH,
     335: /* EROFS */ ERR_CATCH,
     336: /* EMLINK */    ERR_CATCH,
     337: /* EPIPE */ ERR_CATCH,
     338: /* EDOM */  ERR_CATCH,
     339: /* ERANGE */    ERR_CATCH,
     340: /* EQUOT */ ERR_CATCH,
     341: };
     342:
     343: public syserr()
     344: {
     345:     ERRINFO *e;
     346:
     347:     e = &errinfo[errno];
     348:     if (e->func == ERR_CATCH) {
     349:     if (errno < sys_nerr) {
     350:         panic(sys_errlist[errno]);
     351:     } else {
     352:         panic("errno %d", errno);
     353:     }
     354:     } else if (e->func != ERR_IGNORE) {
     355:     (*e->func)();
     356:     }
     357: }
     358:
     359: /*
     360:  * Catcherrs only purpose is to get this module loaded and make
     361:  * sure my cerror is loaded (only applicable when this is in a library).
     362:  */
     363:
     364: public catcherrs()
     365: {
     366:     _mycerror();
     367: }
     368:
     369: /*
     370:  * Change the action on receipt of an error.
     371:  */
     372:
     373: public onsyserr(n, f)
     374: int n;
     375: INTFUNC *f;
     376: {
     377:     errinfo[n].func = f;
     378: }
     379:
     380: /*
     381:  * Standard error handling routines.
     382:  */
     383:
     384: private short nerrs;
     385: private short nwarnings;
     386:
     387: /*
     388:  * Main driver of error message reporting.
     389:  */
     390:
     391: /* VARARGS2 */
     392: private errmsg(errname, shouldquit, s, a, b, c, d, e, f, g, h, i, j, k, l, m)
     393: String errname;
     394: Boolean shouldquit;
     395: String s;
     396: {
     397:     fflush(stdout);
     398:     if (shouldquit and cmdname != nil(String)) {
     399:     fprintf(stderr, "%s: ", cmdname);
     400:     }
     401:     if (errfilename != nil(Filename)) {
     402:     fprintf(stderr, "%s: ", errfilename);
     403:     }
     404:     if (errlineno > 0) {
     405:     fprintf(stderr, "%d: ", errlineno);
     406:     }
     407:     if (errname != nil(String)) {
     408:     fprintf(stderr, "%s: ", errname);
     409:     }
     410:     fprintf(stderr, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
     411:     putc('\n', stderr);
     412:     if (shouldquit) {
     413:     quit(1);
     414:     }
     415: }
     416:
     417: /*
     418:  * The messages are listed in increasing order of seriousness.
     419:  *
     420:  * First are warnings.
     421:  */
     422:
     423: /* VARARGS1 */
     424: public warning(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
     425: String s;
     426: {
     427:     nwarnings++;
     428:     errmsg("warning", FALSE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
     429: }
     430:
     431: /*
     432:  * Errors are a little worse, they mean something is wrong,
     433:  * but not so bad that processing can't continue.
     434:  *
     435:  * The routine "erecover" is called to recover from the error,
     436:  * a default routine is provided that does nothing.
     437:  */
     438:
     439: /* VARARGS1 */
     440: public error(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
     441: String s;
     442: {
     443:     extern erecover();
     444:
     445:     nerrs++;
     446:     errmsg(nil(String), FALSE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
     447:     erecover();
     448: }
     449:
     450: /*
     451:  * Non-recoverable user error.
     452:  */
     453:
     454: /* VARARGS1 */
     455: public fatal(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
     456: String s;
     457: {
     458:     errmsg("fatal error", TRUE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
     459: }
     460:
     461: /*
     462:  * Panics indicate an internal program error.
     463:  */
     464:
     465: /* VARARGS1 */
     466: public panic(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
     467: String s;
     468: {
     469:     errmsg("panic", TRUE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
     470: }
     471:
     472: short numerrors()
     473: {
     474:     short r;
     475:
     476:     r = nerrs;
     477:     nerrs = 0;
     478:     return r;
     479: }
     480:
     481: short numwarnings()
     482: {
     483:     short r;
     484:
     485:     r = nwarnings;
     486:     nwarnings = 0;
     487:     return r;
     488: }
     489:
     490: /*
     491:  * Recover from an error.
     492:  *
     493:  * This is the default routine which we aren't using since we have our own.
     494:  *
     495: public erecover()
     496: {
     497: }
     498:  *
     499:  */
     500:
     501: /*
     502:  * Default way to quit from a program is just to exit.
     503:  *
     504: public quit(r)
     505: int r;
     506: {
     507:     exit(r);
     508: }
     509:  *
     510:  */
     511:
     512: /*
     513:  * Compare n-byte areas pointed to by s1 and s2
     514:  * if n is 0 then compare up until one has a null byte.
     515:  */
     516:
     517: public int cmp(s1, s2, n)
     518: register char *s1, *s2;
     519: register unsigned int n;
     520: {
     521:     if (s1 == nil(char *) || s2 == nil(char *)) {
     522:     panic("cmp: nil pointer");
     523:     }
     524:     if (n == 0) {
     525:     while (*s1 == *s2++) {
     526:         if (*s1++ == '\0') {
     527:         return(0);
     528:         }
     529:     }
     530:     return(*s1 - *(s2-1));
     531:     } else {
     532:     for (; n != 0; n--) {
     533:         if (*s1++ != *s2++) {
     534:         return(*(s1-1) - *(s2-1));
     535:         }
     536:     }
     537:     return(0);
     538:     }
     539: }
     540:
     541: /*
     542:  * Move n bytes from src to dest.
     543:  * If n is 0 move until a null is found.
     544:  */
     545:
     546: public mov(src, dest, n)
     547: register char *src, *dest;
     548: register unsigned int n;
     549: {
     550:     if (src == nil(char *))
     551:     panic("mov: nil source");
     552:     if (dest == nil(char *))
     553:     panic("mov: nil destination");
     554:     if (n > 0) {
     555:     for (; n != 0; n--) {
     556:         *dest++ = *src++;
     557:     }
     558:     } else {
     559:     while ((*dest++ = *src++) != '\0');
     560:     }
     561: }

#### Defined functions

back defined in line 119; never used
backv defined in line 151; used 2 times

- in line 135, 146

call defined in line 99; used 1 times

- in line 200

callv defined in line 138; used 1 times

- in line 115

catcherrs defined in line 364; never used
cmp defined in line 517; never used
errmsg defined in line 392; used 4 times

- in line 428, 446, 458, 469

error defined in line 440; used 1 times

- in /usr/src/ucb/PORT/pascal/pdx/defs.h line 58

fatal defined in line 455; never used
fswap defined in line 174; used 2 times

- in line 161-162(2)

mov defined in line 546; never used
numerrors defined in line 472; used 1 times

- in /usr/src/ucb/PORT/pascal/pdx/defs.h line 60

numwarnings defined in line 481; never used
onsyserr defined in line 373; used 1 times

- in line 163

panic defined in line 466; used 7 times

- in line 242, 350-352(2), 522, 551-553(2)
- in /usr/src/ucb/PORT/pascal/pdx/defs.h line 59

pfind defined in line 257; used 3 times

- in line 218, 226, 240

pwait defined in line 220; used 1 times

- in line 147

shell defined in line 191; never used
syserr defined in line 343; used 1 times

- in /usr/src/ucb/PORT/pascal/pdx/cerror.s line 21

warning defined in line 424; never used

#### Defined variables

cmdname defined in line 42; used 2 times

- in line 398-399(2)

errfilename defined in line 43; used 2 times

- in line 401-402(2)

errlineno defined in line 44; used 2 times

- in line 404-405(2)

nerrs defined in line 384; used 3 times

- in line 445, 476-477(2)

nwarnings defined in line 385; used 3 times

- in line 427, 485-486(2)

pidlist defined in line 218; used 4 times

- in line 236-237(2), 263, 271

public defined in line 517; never used
sccsid defined in line 8; never used

#### Defined struct's

pidlist defined in line 212; used 2 times

- in line 215(2)

#### Defined typedef's

Filename defined in line 29; used 2 times

- in line 43, 401

Pidlist defined in line 216; used 11 times

- in line 218, 257-227(3), 233, 241, 260-263(3), 269-270(2)

String defined in line 27; used 32 times

- in line 29, 42, 66, 100-103(2), 120-123(2), 139-142(2), 152-155(2), 192, 393-395(2), 425, 441, 456, 467-114(5), 125-134(4), 194-197(3), 398, 407, 446

#### Defined macros

BADEXEC defined in line 94; used 1 times

- in line 165

DEF_SHELL defined in line 189; used 1 times

- in line 198

ERR_CATCH defined in line 79; used 31 times

- in line 309-340(30), 348

ERR_IGNORE defined in line 78; used 8 times

- in line 163, 305-308(4), 314, 330, 354

MAXNARGS defined in line 93; used 2 times

- in line 106, 126

alloc defined in line 52; used 1 times

- in line 233

and defined in line 20; used 1 times

- in line 398

dispose defined in line 53; used 2 times

- in line 229, 245

get defined in line 59; never used
ischild defined in line 96; used 1 times

- in line 160

nil defined in line 24; used 19 times

- in line 111-114(2), 131-134(2), 197, 227, 241, 262-263(2), 269-270(2), 398-401(2), 407, 446, 521(2), 550-552(2)

not defined in line 22; never used
or defined in line 21; never used
ord defined in line 23; never used
private defined in line 19; used 7 times

- in line 174, 218, 257, 304, 384-385(2), 392

public defined in line 18; used 14 times

- in line 99, 119, 138, 151, 191, 220, 343, 364, 373, 424, 440, 455, 466, 546

put defined in line 60; never used
strdup defined in line 69; never used
streq defined in line 70; never used

Last modified: 1985-06-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2373 |