Annotation of 43BSDReno/pgrm/dbx/library.c, revision 1.1

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

unix.superglobalmegacorp.com

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