Annotation of 43BSDTahoe/lib/old_compiler/dbx/library.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 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.2 (Berkeley) 1/12/88";
        !             9: #endif not lint
        !            10: 
        !            11: static char rcsid[] = "$Header: library.c,v 1.2 87/03/25 20:50:14 donn Exp $";
        !            12: 
        !            13: /*
        !            14:  * General purpose routines.
        !            15:  */
        !            16: 
        !            17: #include <stdio.h>
        !            18: #include <errno.h>
        !            19: #include <signal.h>
        !            20: 
        !            21: #define public
        !            22: #define private static
        !            23: #define and &&
        !            24: #define or ||
        !            25: #define not !
        !            26: #define ord(enumcon)   ((int) enumcon)
        !            27: #define nil(type)      ((type) 0)
        !            28: 
        !            29: typedef int integer;
        !            30: typedef enum { FALSE, TRUE } boolean;
        !            31: typedef char *String;
        !            32: typedef FILE *File;
        !            33: typedef String Filename;
        !            34: 
        !            35: #undef FILE
        !            36: 
        !            37: String cmdname;                        /* name of command for error messages */
        !            38: Filename errfilename;          /* current file associated with error */
        !            39: short errlineno;               /* line number associated with error */
        !            40: 
        !            41: /*
        !            42:  * Definitions for doing memory allocation.
        !            43:  */
        !            44: 
        !            45: extern char *malloc();
        !            46: 
        !            47: #define alloc(n, type) ((type *) malloc((unsigned) (n) * sizeof(type)))
        !            48: #define dispose(p)     { free((char *) p); p = 0; }
        !            49: 
        !            50: /*
        !            51:  * Macros for doing freads + fwrites.
        !            52:  */
        !            53: 
        !            54: #define get(fp, var)   fread((char *) &(var), sizeof(var), 1, fp)
        !            55: #define put(fp, var)   fwrite((char *) &(var), sizeof(var), 1, fp)
        !            56: 
        !            57: /*
        !            58:  * String definitions.
        !            59:  */
        !            60: 
        !            61: extern String strcpy(), index(), rindex();
        !            62: extern int strlen();
        !            63: 
        !            64: #define strdup(s)              strcpy(malloc((unsigned) strlen(s) + 1), s)
        !            65: #define streq(s1, s2)  (strcmp(s1, s2) == 0)
        !            66: 
        !            67: typedef int IntFunc();
        !            68: 
        !            69: IntFunc *onsyserr();
        !            70: 
        !            71: typedef struct {
        !            72:     IntFunc *func;
        !            73: } ErrInfo;
        !            74: 
        !            75: #define ERR_IGNORE ((IntFunc *) 0)
        !            76: #define ERR_CATCH  ((IntFunc *) 1)
        !            77: 
        !            78: /*
        !            79:  * Call a program.
        !            80:  *
        !            81:  * Four entries:
        !            82:  *
        !            83:  *     call, callv - call a program and wait for it, returning status
        !            84:  *     back, backv - call a program and don't wait, returning process id
        !            85:  *
        !            86:  * The command's standard input and output are passed as FILE's.
        !            87:  */
        !            88: 
        !            89: 
        !            90: #define MAXNARGS 1000    /* unchecked upper limit on max num of arguments */
        !            91: #define BADEXEC 127    /* exec fails */
        !            92: 
        !            93: #define ischild(pid)    ((pid) == 0)
        !            94: 
        !            95: /* VARARGS3 */
        !            96: public int call(name, in, out, args)
        !            97: String name;
        !            98: File in;
        !            99: File out;
        !           100: String args;
        !           101: {
        !           102:     String *ap, *argp;
        !           103:     String argv[MAXNARGS];
        !           104: 
        !           105:     argp = &argv[0];
        !           106:     *argp++ = name;
        !           107:     ap = &args;
        !           108:     while (*ap != nil(String)) {
        !           109:        *argp++ = *ap++;
        !           110:     }
        !           111:     *argp = nil(String);
        !           112:     return callv(name, in, out, argv);
        !           113: }
        !           114: 
        !           115: /* VARARGS3 */
        !           116: public int back(name, in, out, args)
        !           117: String name;
        !           118: File in;
        !           119: File out;
        !           120: String args;
        !           121: {
        !           122:     String *ap, *argp;
        !           123:     String argv[MAXNARGS];
        !           124: 
        !           125:     argp = &argv[0];
        !           126:     *argp++ = name;
        !           127:     ap = &args;
        !           128:     while (*ap != nil(String)) {
        !           129:        *argp++ = *ap++;
        !           130:     }
        !           131:     *argp = nil(String);
        !           132:     return backv(name, in, out, argv);
        !           133: }
        !           134: 
        !           135: public int callv(name, in, out, argv)
        !           136: String name;
        !           137: File in;
        !           138: File out;
        !           139: String *argv;
        !           140: {
        !           141:     int pid, status;
        !           142: 
        !           143:     pid = backv(name, in, out, argv);
        !           144:     pwait(pid, &status);
        !           145:     return status;
        !           146: }
        !           147: 
        !           148: public int backv(name, in, out, argv)
        !           149: String name;
        !           150: File in;
        !           151: File out;
        !           152: String *argv;
        !           153: {
        !           154:     int pid;
        !           155: 
        !           156:     fflush(stdout);
        !           157:     if (ischild(pid = fork())) {
        !           158:        fswap(0, fileno(in));
        !           159:        fswap(1, fileno(out));
        !           160:        onsyserr(EACCES, ERR_IGNORE);
        !           161:        execvp(name, argv);
        !           162:        _exit(BADEXEC);
        !           163:     }
        !           164:     return pid;
        !           165: }
        !           166: 
        !           167: /*
        !           168:  * Swap file numbers so as to redirect standard input and output.
        !           169:  */
        !           170: 
        !           171: private fswap(oldfd, newfd)
        !           172: int oldfd;
        !           173: int newfd;
        !           174: {
        !           175:     if (oldfd != newfd) {
        !           176:        close(oldfd);
        !           177:        dup(newfd);
        !           178:        close(newfd);
        !           179:     }
        !           180: }
        !           181: 
        !           182: /*
        !           183:  * Invoke a shell on a command line.
        !           184:  */
        !           185: 
        !           186: #define DEF_SHELL      "csh"
        !           187: 
        !           188: public shell(s)
        !           189: String s;
        !           190: {
        !           191:     extern String getenv();
        !           192:     String sh;
        !           193: 
        !           194:     if ((sh = getenv("SHELL")) == nil(String)) {
        !           195:        sh = DEF_SHELL;
        !           196:     }
        !           197:     if (s != nil(String) and *s != '\0') {
        !           198:        call(sh, stdin, stdout, "-c", s, 0);
        !           199:     } else {
        !           200:        call(sh, stdin, stdout, 0);
        !           201:     }
        !           202: }
        !           203: 
        !           204: /*
        !           205:  * Wait for a process the right way.  We wait for a particular
        !           206:  * process and if any others come along in between, we remember them
        !           207:  * in case they are eventually waited for.
        !           208:  *
        !           209:  * This routine is not very efficient when the number of processes
        !           210:  * to be remembered is large.
        !           211:  *
        !           212:  * To deal with a kernel idiosyncrasy, we keep a list on the side
        !           213:  * of "traced" processes, and do not notice them when waiting for
        !           214:  * another process.
        !           215:  */
        !           216: 
        !           217: typedef struct pidlist {
        !           218:     int pid;
        !           219:     int status;
        !           220:     struct pidlist *next;
        !           221: } Pidlist;
        !           222: 
        !           223: private Pidlist *pidlist, *ptrclist, *pfind();
        !           224: 
        !           225: public ptraced(pid)
        !           226: int pid;
        !           227: {
        !           228:     Pidlist *p;
        !           229: 
        !           230:     p = alloc(1, Pidlist);
        !           231:     p->pid = pid;
        !           232:     p->next = ptrclist;
        !           233:     ptrclist = p;
        !           234: }
        !           235: 
        !           236: public unptraced(pid)
        !           237: int pid;
        !           238: {
        !           239:     register Pidlist *p, *prev;
        !           240: 
        !           241:     prev = nil(Pidlist *);
        !           242:     p = ptrclist;
        !           243:     while (p != nil(Pidlist *) and p->pid != pid) {
        !           244:        prev = p;
        !           245:        p = p->next;
        !           246:     }
        !           247:     if (p != nil(Pidlist *)) {
        !           248:        if (prev == nil(Pidlist *)) {
        !           249:            ptrclist = p->next;
        !           250:        } else {
        !           251:            prev->next = p->next;
        !           252:        }
        !           253:        dispose(p);
        !           254:     }
        !           255: }
        !           256: 
        !           257: private boolean isptraced(pid)
        !           258: int pid;
        !           259: {
        !           260:     register Pidlist *p;
        !           261: 
        !           262:     p = ptrclist;
        !           263:     while (p != nil(Pidlist *) and p->pid != pid) {
        !           264:        p = p->next;
        !           265:     }
        !           266:     return (boolean) (p != nil(Pidlist *));
        !           267: }
        !           268: 
        !           269: public pwait(pid, statusp)
        !           270: int pid, *statusp;
        !           271: {
        !           272:     Pidlist *p;
        !           273:     int pnum, status;
        !           274: 
        !           275:     p = pfind(pid);
        !           276:     if (p != nil(Pidlist *)) {
        !           277:        *statusp = p->status;
        !           278:        dispose(p);
        !           279:     } else {
        !           280:        pnum = wait(&status);
        !           281:        while (pnum != pid and pnum >= 0) {
        !           282:            if (not isptraced(pnum)) {
        !           283:                p = alloc(1, Pidlist);
        !           284:                p->pid = pnum;
        !           285:                p->status = status;
        !           286:                p->next = pidlist;
        !           287:                pidlist = p;
        !           288:            }
        !           289:            pnum = wait(&status);
        !           290:        }
        !           291:        if (pnum < 0) {
        !           292:            p = pfind(pid);
        !           293:            if (p == nil(Pidlist *)) {
        !           294:                panic("pwait: pid %d not found", pid);
        !           295:            }
        !           296:            *statusp = p->status;
        !           297:            dispose(p);
        !           298:        } else {
        !           299:            *statusp = status;
        !           300:        }
        !           301:     }
        !           302: }
        !           303: 
        !           304: /*
        !           305:  * Look for the given process id on the pidlist.
        !           306:  *
        !           307:  * Unlink it from list if found.
        !           308:  */
        !           309: 
        !           310: private Pidlist *pfind(pid)
        !           311: int pid;
        !           312: {
        !           313:     register Pidlist *p, *prev;
        !           314: 
        !           315:     prev = nil(Pidlist *);
        !           316:     for (p = pidlist; p != nil(Pidlist *); p = p->next) {
        !           317:        if (p->pid == pid) {
        !           318:            break;
        !           319:        }
        !           320:        prev = p;
        !           321:     }
        !           322:     if (p != nil(Pidlist *)) {
        !           323:        if (prev == nil(Pidlist *)) {
        !           324:            pidlist = p->next;
        !           325:        } else {
        !           326:            prev->next = p->next;
        !           327:        }
        !           328:     }
        !           329:     return p;
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * System call error handler.
        !           334:  *
        !           335:  * The syserr routine is called when a system call is about to
        !           336:  * set the c-bit to report an error.  Certain errors are caught
        !           337:  * and cause the process to print a message and immediately exit.
        !           338:  */
        !           339: 
        !           340: extern int sys_nerr;
        !           341: extern char *sys_errlist[];
        !           342:  
        !           343: /*
        !           344:  * Before calling syserr, the integer errno is set to contain the
        !           345:  * number of the error.  The routine "_mycerror" is a dummy which
        !           346:  * is used to force the loader to get my version of cerror rather
        !           347:  * than the usual one.
        !           348:  */
        !           349: 
        !           350: extern int errno;
        !           351: extern _mycerror();
        !           352: 
        !           353: /*
        !           354:  * Initialize error information, setting defaults for handling errors.
        !           355:  */
        !           356: 
        !           357: private ErrInfo *errinfo;
        !           358: 
        !           359: private initErrInfo ()
        !           360: {
        !           361:     integer i;
        !           362: 
        !           363:     errinfo = alloc(sys_nerr, ErrInfo);
        !           364:     for (i = 0; i < sys_nerr; i++) {
        !           365:        errinfo[i].func = ERR_CATCH;
        !           366:     }
        !           367:     errinfo[0].func = ERR_IGNORE;
        !           368:     errinfo[EPERM].func = ERR_IGNORE;
        !           369:     errinfo[ENOENT].func = ERR_IGNORE;
        !           370:     errinfo[ESRCH].func = ERR_IGNORE;
        !           371:     errinfo[EBADF].func = ERR_IGNORE;
        !           372:     errinfo[ENOTTY].func = ERR_IGNORE;
        !           373:     errinfo[EOPNOTSUPP].func = ERR_IGNORE;
        !           374: }
        !           375: 
        !           376: public syserr()
        !           377: {
        !           378:     register ErrInfo *e;
        !           379: 
        !           380:     if (errno < 0 or errno > sys_nerr) {
        !           381:        fatal("errno %d", errno);
        !           382:     } else {
        !           383:        if (errinfo == nil(ErrInfo *)) {
        !           384:            initErrInfo();
        !           385:        }
        !           386:        e = &(errinfo[errno]);
        !           387:        if (e->func == ERR_CATCH) {
        !           388:            fatal(sys_errlist[errno]);
        !           389:        } else if (e->func != ERR_IGNORE) {
        !           390:            (*e->func)();
        !           391:        }
        !           392:     }
        !           393: }
        !           394: 
        !           395: /*
        !           396:  * Catcherrs' purpose is to initialize the errinfo table, get this module
        !           397:  * loaded, and make sure my cerror is loaded (only applicable when this is
        !           398:  * in a library).
        !           399:  */
        !           400: 
        !           401: public catcherrs()
        !           402: {
        !           403:     _mycerror();
        !           404:     initErrInfo();
        !           405: }
        !           406: 
        !           407: /*
        !           408:  * Turn off the error catching mechanism completely by having all errors
        !           409:  * ignored.  This is most useful between a fork and an exec.
        !           410:  */
        !           411: 
        !           412: public nocatcherrs()
        !           413: {
        !           414:     integer i;
        !           415: 
        !           416:     for (i = 0; i < sys_nerr; i++) {
        !           417:        errinfo[i].func = ERR_IGNORE;
        !           418:     }
        !           419: }
        !           420: 
        !           421: /*
        !           422:  * Change the action on receipt of an error, returning the previous action.
        !           423:  */
        !           424: 
        !           425: public IntFunc *onsyserr(n, f)
        !           426: int n;
        !           427: IntFunc *f;
        !           428: {
        !           429:     IntFunc *oldf;
        !           430: 
        !           431:     if (errinfo == nil(ErrInfo *)) {
        !           432:        initErrInfo();
        !           433:     }
        !           434:     oldf = errinfo[n].func;
        !           435:     errinfo[n].func = f;
        !           436:     return oldf;
        !           437: }
        !           438: 
        !           439: /*
        !           440:  * Print the message associated with the given signal.
        !           441:  * Like a "perror" for signals.
        !           442:  */
        !           443: 
        !           444: #ifdef SIGWINCH
        !           445: public int sys_nsig = NSIG;
        !           446: #else not 4.3 BSD
        !           447: /*
        !           448:  * This table is correct for 4.2-like systems but will
        !           449:  * be inadequate for System V (which is the sort of
        !           450:  * Unix that needs it!).
        !           451:  */
        !           452: public String sys_siglist[] = {
        !           453:     "no signal",
        !           454:     "hangup",
        !           455:     "interrupt",
        !           456:     "quit",
        !           457:     "illegal instruction",
        !           458:     "trace trap",
        !           459:     "IOT instruction",
        !           460:     "EMT instruction",
        !           461:     "floating point exception",
        !           462:     "kill",
        !           463:     "bus error",
        !           464:     "segmentation violation",
        !           465:     "bad argument to system call",
        !           466:     "broken pipe",
        !           467:     "alarm clock",
        !           468:     "soft kill",
        !           469:     "urgent I/O condition",
        !           470:     "stop signal not from tty",
        !           471:     "stop signal from tty",
        !           472:     "continue",
        !           473:     "child termination",
        !           474:     "stop (tty input)",
        !           475:     "stop (tty output)",
        !           476:     "possible input/output",
        !           477:     "exceeded CPU time limit",
        !           478:     "exceeded file size limit"
        !           479: };
        !           480: public int sys_nsig = sizeof sys_siglist / sizeof sys_siglist[0];
        !           481: #endif
        !           482: 
        !           483: public psignal(s, n)
        !           484: String s;
        !           485: integer n;
        !           486: {
        !           487:     String msg;
        !           488:     integer len;
        !           489:     extern String sys_siglist[];
        !           490: 
        !           491:     if (n >= 0 and n < sys_nsig) {
        !           492:        msg = sys_siglist[n];
        !           493:     } else {
        !           494:        msg = "Unknown signal";
        !           495:     }
        !           496:     len = strlen(s);
        !           497:     if (len > 0) {
        !           498:        write(2, s, len);
        !           499:        write(2, ": ", 2);
        !           500:     }
        !           501:     write(2, msg, strlen(msg));
        !           502:     write(2, "\n", 1);
        !           503: }
        !           504: 
        !           505: /*
        !           506:  * Standard error handling routines.
        !           507:  */
        !           508: 
        !           509: private short nerrs;
        !           510: private short nwarnings;
        !           511: 
        !           512: /*
        !           513:  * Main driver of error message reporting.
        !           514:  */
        !           515: 
        !           516: /* VARARGS2 */
        !           517: private errmsg(errname, shouldquit, s, a, b, c, d, e, f, g, h, i, j, k, l, m)
        !           518: String errname;
        !           519: boolean shouldquit;
        !           520: String s;
        !           521: {
        !           522:     fflush(stdout);
        !           523:     if (shouldquit and cmdname != nil(String)) {
        !           524:        fprintf(stderr, "%s: ", cmdname);
        !           525:     }
        !           526:     if (errfilename != nil(Filename)) {
        !           527:        fprintf(stderr, "%s: ", errfilename);
        !           528:     }
        !           529:     if (errlineno > 0) {
        !           530:        fprintf(stderr, "%d: ", errlineno);
        !           531:     }
        !           532:     if (errname != nil(String)) {
        !           533:        fprintf(stderr, "%s: ", errname);
        !           534:     }
        !           535:     fprintf(stderr, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
        !           536:     putc('\n', stderr);
        !           537:     fflush(stderr);
        !           538:     if (shouldquit) {
        !           539:        quit(1);
        !           540:     }
        !           541: }
        !           542: 
        !           543: /*
        !           544:  * For when printf isn't sufficient for printing the error message ...
        !           545:  */
        !           546: 
        !           547: public beginerrmsg()
        !           548: {
        !           549:     fflush(stdout);
        !           550:     if (errfilename != nil(String)) {
        !           551:        fprintf(stderr, "%s: ", errfilename);
        !           552:     }
        !           553:     if (errlineno > 0) {
        !           554:        fprintf(stderr, "%d: ", errlineno);
        !           555:     }
        !           556: }
        !           557: 
        !           558: public enderrmsg()
        !           559: {
        !           560:     putc('\n', stderr);
        !           561:     fflush(stderr);
        !           562:     erecover();
        !           563: }
        !           564: 
        !           565: /*
        !           566:  * The messages are listed in increasing order of seriousness.
        !           567:  *
        !           568:  * First are warnings.
        !           569:  */
        !           570: 
        !           571: /* VARARGS1 */
        !           572: public warning(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
        !           573: String s;
        !           574: {
        !           575:     nwarnings++;
        !           576:     errmsg("warning", FALSE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
        !           577: }
        !           578: 
        !           579: /*
        !           580:  * Errors are a little worse, they mean something is wrong,
        !           581:  * but not so bad that processing can't continue.
        !           582:  *
        !           583:  * The routine "erecover" is called to recover from the error,
        !           584:  * a default routine is provided that does nothing.
        !           585:  */
        !           586: 
        !           587: /* VARARGS1 */
        !           588: public error(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
        !           589: String s;
        !           590: {
        !           591:     extern erecover();
        !           592: 
        !           593:     nerrs++;
        !           594:     errmsg(nil(String), FALSE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
        !           595:     erecover();
        !           596: }
        !           597: 
        !           598: /*
        !           599:  * Non-recoverable user error.
        !           600:  */
        !           601: 
        !           602: /* VARARGS1 */
        !           603: public fatal(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
        !           604: String s;
        !           605: {
        !           606:     errmsg("fatal error", TRUE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
        !           607: }
        !           608: 
        !           609: /*
        !           610:  * Panics indicate an internal program error.
        !           611:  */
        !           612: 
        !           613: /* VARARGS1 */
        !           614: public panic(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
        !           615: String s;
        !           616: {
        !           617:     errmsg("internal error", TRUE, s, a, b, c, d, e, f, g, h, i, j, k, l, m);
        !           618: }
        !           619: 
        !           620: short numerrors()
        !           621: {
        !           622:     short r;
        !           623: 
        !           624:     r = nerrs;
        !           625:     nerrs = 0;
        !           626:     return r;
        !           627: }
        !           628: 
        !           629: short numwarnings()
        !           630: {
        !           631:     short r;
        !           632: 
        !           633:     r = nwarnings;
        !           634:     nwarnings = 0;
        !           635:     return r;
        !           636: }
        !           637: 
        !           638: /*
        !           639:  * Recover from an error.
        !           640:  *
        !           641:  * This is the default routine which we aren't using since we have our own.
        !           642:  *
        !           643: public erecover()
        !           644: {
        !           645: }
        !           646:  *
        !           647:  */
        !           648: 
        !           649: /*
        !           650:  * Default way to quit from a program is just to exit.
        !           651:  *
        !           652: public quit(r)
        !           653: int r;
        !           654: {
        !           655:     exit(r);
        !           656: }
        !           657:  *
        !           658:  */
        !           659: 
        !           660: /*
        !           661:  * Compare n-byte areas pointed to by s1 and s2
        !           662:  * if n is 0 then compare up until one has a null byte.
        !           663:  */
        !           664: 
        !           665: public int cmp(s1, s2, n)
        !           666: register char *s1, *s2;
        !           667: register unsigned int n;
        !           668: {
        !           669:     if (s1 == nil(char *) || s2 == nil(char *)) {
        !           670:        panic("cmp: nil pointer");
        !           671:     }
        !           672:     if (n == 0) {
        !           673:        while (*s1 == *s2++) {
        !           674:            if (*s1++ == '\0') {
        !           675:                return(0);
        !           676:            }
        !           677:        }
        !           678:        return(*s1 - *(s2-1));
        !           679:     } else {
        !           680:        for (; n != 0; n--) {
        !           681:            if (*s1++ != *s2++) {
        !           682:                return(*(s1-1) - *(s2-1));
        !           683:            }
        !           684:        }
        !           685:        return(0);
        !           686:     }
        !           687: }
        !           688: 
        !           689: /*
        !           690:  * Move n bytes from src to dest.
        !           691:  * If n is 0 move until a null is found.
        !           692:  */
        !           693: 
        !           694: public mov(src, dest, n)
        !           695: register char *src, *dest;
        !           696: register unsigned int n;
        !           697: {
        !           698:     if (src == nil(char *))
        !           699:        panic("mov: nil source");
        !           700:     if (dest == nil(char *))
        !           701:        panic("mov: nil destination");
        !           702:     if (n != 0) {
        !           703:        for (; n != 0; n--) {
        !           704:            *dest++ = *src++;
        !           705:        }
        !           706:     } else {
        !           707:        while ((*dest++ = *src++) != '\0');
        !           708:     }
        !           709: }
        !           710: 
        !           711: #ifdef IRIS /* or in general for 4.2 - System V C library interface */
        !           712: 
        !           713: public bcopy (fromaddr, toaddr, n)
        !           714: char *fromaddr, *toaddr;
        !           715: int n;
        !           716: {
        !           717:     blt(toaddr, fromaddr, n);
        !           718: }
        !           719: 
        !           720: public bzero (addr, n)
        !           721: char *addr;
        !           722: int n;
        !           723: {
        !           724:     register char *p, *q;
        !           725: 
        !           726:     p = addr;
        !           727:     q = p + n;
        !           728:     while (p < q) {
        !           729:        *p++ = '\0';
        !           730:     }
        !           731: }
        !           732: 
        !           733: #include <string.h>
        !           734: 
        !           735: public char *index (s, c)
        !           736: char *s, c;
        !           737: {
        !           738:     return strchr(s, c);
        !           739: }
        !           740: 
        !           741: public char *rindex (s, c)
        !           742: char *s, c;
        !           743: {
        !           744:     return strrchr(s, c);
        !           745: }
        !           746: 
        !           747: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.