Annotation of researchv10dc/cmd/icon/src/iconx/fsys.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * File: fsys.c
        !             3:  *  Contents: close, exit, open, read, reads, stop, system, write, writes
        !             4:  */
        !             5: 
        !             6: #include "../h/rt.h"
        !             7: 
        !             8: /*
        !             9:  * close(f) - close file f.
        !            10:  */
        !            11: 
        !            12: FncDcl(close,1)
        !            13:    {
        !            14:    register int i;
        !            15: 
        !            16:    /*
        !            17:     * f must be a file.
        !            18:     */
        !            19:    if (Arg1.dword != D_File)
        !            20:       runerr(105, &Arg1);
        !            21: 
        !            22:    /*
        !            23:     * If f has a buffer associated with it, "free" it.
        !            24:     */
        !            25:    for (i = 0; i < numbufs; i++) {
        !            26:       if (bufused[i] == BlkLoc(Arg1)->file.fd) {
        !            27:         bufused[i] = NULL;
        !            28:         break;
        !            29:         }
        !            30:       }
        !            31: 
        !            32:    /*
        !            33:     * Close f, using fclose or pclose as appropriate.
        !            34:     */
        !            35: #ifndef MSDOS
        !            36:    if (BlkLoc(Arg1)->file.status & Fs_Pipe)
        !            37:       pclose(BlkLoc(Arg1)->file.fd);
        !            38:    else
        !            39: #endif MSDOS
        !            40:       fclose(BlkLoc(Arg1)->file.fd);
        !            41:    BlkLoc(Arg1)->file.status = 0;
        !            42: 
        !            43:    /*
        !            44:     * Return the closed file.
        !            45:     */
        !            46:    Arg0 = Arg1;
        !            47:    Return;
        !            48:    }
        !            49: 
        !            50: 
        !            51: /*
        !            52:  * exit(status) - exit process with specified status, defaults to 0.
        !            53:  */
        !            54: 
        !            55: FncDcl(exit,1)
        !            56:    {
        !            57:    defshort(&Arg1, NormalExit);
        !            58:    c_exit((int)IntVal(Arg1));
        !            59:    }
        !            60: 
        !            61: 
        !            62: /*
        !            63:  * open(s1,s2) - open file s1 with specification s2.
        !            64:  */
        !            65: FncDcl(open,2)
        !            66:    {
        !            67:    register word slen;
        !            68:    register int i;
        !            69:    register char *s;
        !            70:    int status;
        !            71: #ifndef MSDOS
        !            72:    char sbuf1[MaxCvtLen], sbuf2[MaxCvtLen], mode[3];
        !            73: #else MSDOS
        !            74:    char sbuf1[MaxCvtLen], sbuf2[MaxCvtLen], mode[4];
        !            75:    char untranslated;
        !            76: #endif MSDOS
        !            77:    FILE *f;
        !            78:    extern struct b_file *alcfile();
        !            79:    extern char *alcstr();
        !            80: #ifndef MSDOS
        !            81:    extern FILE *fopen(), *popen();
        !            82: #else MSDOS
        !            83:    extern FILE *fopen();
        !            84: #endif MSDOS
        !            85:    /*
        !            86:     * s1 must be a string and a C string copy of it is also needed.
        !            87:     *  Make it a string if it isn't one; make a C string if s1 is
        !            88:     *  a string.
        !            89:     */
        !            90:    switch (cvstr(&Arg1, sbuf1)) {
        !            91: 
        !            92:       case Cvt:
        !            93:         strreq(StrLen(Arg1));
        !            94:         StrLoc(Arg1) = alcstr(StrLoc(Arg1), StrLen(Arg1));
        !            95:         break;
        !            96: 
        !            97:       case NoCvt:
        !            98:         qtos(&Arg1, sbuf1);
        !            99:         break;
        !           100: 
        !           101:       default:
        !           102:         runerr(103, &Arg1);
        !           103:       }
        !           104:    /*
        !           105:     * s2 defaults to "r".
        !           106:     */
        !           107:    defstr(&Arg2, sbuf2, &letr);
        !           108: 
        !           109:    blkreq((word)sizeof(struct b_file));
        !           110:    status = 0;
        !           111: #ifdef MSDOS
        !           112:    untranslated = 0;
        !           113: #endif MSDOS
        !           114:    /*
        !           115:     * Scan s2, setting appropriate bits in status.  Produce a runerr
        !           116:     *  if an unknown character is encountered.
        !           117:     */
        !           118:    s = StrLoc(Arg2);
        !           119:    slen = StrLen(Arg2);
        !           120:    for (i = 0; i < slen; i++) {
        !           121:       switch (*s++) {
        !           122:         case 'a': case 'A':
        !           123:            status |= Fs_Write|Fs_Append;
        !           124:            continue;
        !           125:         case 'b': case 'B':
        !           126:            status |= Fs_Read|Fs_Write;
        !           127:            continue;
        !           128:         case 'c': case 'C':
        !           129:            status |= Fs_Create|Fs_Write;
        !           130:            continue;
        !           131: #ifndef MSDOS
        !           132:         case 'p': case 'P':
        !           133:            status |= Fs_Pipe;
        !           134:            continue;
        !           135: #else MSDOS
        !           136:         case 't': case 'T':   /* Add a translated (default) */
        !           137:            untranslated = 0;
        !           138:            continue;
        !           139:         case 'u': case 'U':   /* Add a translated (default) */
        !           140:            untranslated = 1;
        !           141:            continue;
        !           142: #endif MSDOS
        !           143:         case 'r': case 'R':
        !           144:            status |= Fs_Read;
        !           145:            continue;
        !           146:         case 'w': case 'W':
        !           147:            status |= Fs_Write;
        !           148:            continue;
        !           149:         default:
        !           150:            runerr(209, &Arg2);
        !           151:         }
        !           152:       }
        !           153: 
        !           154:    /*
        !           155:     * Construct a mode field for fopen/popen.
        !           156:     */
        !           157:    mode[0] = '\0';
        !           158:    mode[1] = '\0';
        !           159:    mode[2] = '\0';
        !           160: #ifdef MSDOS
        !           161:    mode[3] = '\0';
        !           162: #endif MSDOS
        !           163:    if ((status & (Fs_Read|Fs_Write)) == 0)   /* default: read only */
        !           164:       status |= Fs_Read;
        !           165:    if (status & Fs_Create)
        !           166:       mode[0] = 'w';
        !           167:    else if (status & Fs_Append)
        !           168:       mode[0] = 'a';
        !           169:    else if (status & Fs_Read)
        !           170:       mode[0] = 'r';
        !           171:    else
        !           172:       mode[0] = 'w';
        !           173: #ifndef MSDOS
        !           174:    if ((status & (Fs_Read|Fs_Write)) == (Fs_Read|Fs_Write))
        !           175:       mode[1] = '+';
        !           176: #else MSDOS
        !           177:    if ((status & (Fs_Read|Fs_Write)) == (Fs_Read|Fs_Write)) {
        !           178:       mode[1] = '+';
        !           179:       mode[2] = untranslated ? 'b' : 't';
        !           180:    }
        !           181:    else mode[1] = untranslated ? 'b' : 't';
        !           182: #endif MSDOS
        !           183: 
        !           184:    /*
        !           185:     * Open the file with fopen or popen.
        !           186:     */
        !           187: #ifndef MSDOS
        !           188:    if (status & Fs_Pipe) {
        !           189:       if (status != (Fs_Read|Fs_Pipe) && status != (Fs_Write|Fs_Pipe))
        !           190:         runerr(209, &Arg2);
        !           191:       f = popen(sbuf1, mode);
        !           192:       }
        !           193:    else
        !           194: #endif MSDOS
        !           195:       f = fopen(sbuf1, mode);
        !           196:    /*
        !           197:     * Fail if the file can't be opened.
        !           198:     */
        !           199:    if (f == NULL)
        !           200:       Fail;
        !           201:    /*
        !           202:     * If the file isn't a terminal and a buffer is available, assign
        !           203:     *  it to the file.
        !           204:     */
        !           205: #ifndef VMS
        !           206:    if (!isatty(fileno(f))) {
        !           207:       for (i = 0; i < numbufs; i++)
        !           208:         if (bufused[i] == NULL)
        !           209:            break;
        !           210:       if (i < numbufs) {             /* Use buffer if any free. */
        !           211:         setbuf(f, bufs[i]);
        !           212:         bufused[i] = f;
        !           213:         }
        !           214:       else
        !           215:         setbuf(f, NULL);
        !           216:       }
        !           217:    else
        !           218:       setbuf(f, NULL);
        !           219: #endif VMS
        !           220:    /*
        !           221:     * Return the resulting file value.
        !           222:     */
        !           223:    Arg0.dword = D_File;
        !           224:    BlkLoc(Arg0) = (union block *) alcfile(f, status, &Arg1);
        !           225:    Return;
        !           226:    }
        !           227: 
        !           228: 
        !           229: /*
        !           230:  * read(f) - read line on file f.
        !           231:  */
        !           232: FncDcl(read,1)
        !           233:    {
        !           234:    register word slen;
        !           235:    int status;
        !           236:    static char sbuf[MaxReadStr];
        !           237:    FILE *f;
        !           238:    extern char *alcstr();
        !           239: 
        !           240:    /*
        !           241:     * Default f to &input.
        !           242:     */
        !           243:    deffile(&Arg1, &input);
        !           244:    /*
        !           245:     * Get a pointer to the file and be sure that it's open for reading.
        !           246:     */
        !           247:    f = BlkLoc(Arg1)->file.fd;
        !           248:    status = BlkLoc(Arg1)->file.status;
        !           249:    if ((status & Fs_Read) == 0)
        !           250:       runerr(212, &Arg1);
        !           251: 
        !           252:    /*
        !           253:     * Use getstr to read a line from the file, failing if getstr
        !           254:     *  encounters end of file.
        !           255:     */
        !           256:    if ((slen = getstr(sbuf,MaxReadStr,f)) < 0)
        !           257:       Fail;
        !           258:    /*
        !           259:     * Allocate the string read and make Arg0 a descriptor for it.
        !           260:     */
        !           261:    strreq(slen);
        !           262:    StrLen(Arg0) = slen;
        !           263:    StrLoc(Arg0) = alcstr(sbuf,slen);
        !           264:    Return;
        !           265:    }
        !           266: 
        !           267: 
        !           268: /*
        !           269:  * reads(f,i) - read i characters on file f.
        !           270:  */
        !           271: FncDcl(reads,2)
        !           272:    {
        !           273:    register int cnt;
        !           274:    int status;
        !           275:    FILE *f;
        !           276: 
        !           277:    /*
        !           278:     * f defaults to &input and i defaults to 1 (character).
        !           279:     */
        !           280:    deffile(&Arg1, &input);
        !           281:    defshort(&Arg2, 1);
        !           282: 
        !           283:    /*
        !           284:     * Get a pointer to the file and be sure that it's open for reading.
        !           285:     */
        !           286:    f = BlkLoc(Arg1)->file.fd;
        !           287:    status = BlkLoc(Arg1)->file.status;
        !           288:    if ((status & Fs_Read) == 0)
        !           289:       runerr(212, &Arg1);
        !           290: 
        !           291:    /*
        !           292:     * Be sure that a positive number of bytes is to be read.
        !           293:     */
        !           294:    if ((cnt = IntVal(Arg2)) <= 0)
        !           295:       runerr(205, &Arg2);
        !           296: 
        !           297:    /*
        !           298:     * Ensure that enough space for the string exists and read it directly
        !           299:     *  into the string space.  (By reading directly into the string space,
        !           300:     *  no arbitrary restrictions are placed on the size of the string that
        !           301:     *  can be read.)  Make Arg0 a descriptor for the string and return it.
        !           302:     */
        !           303:    strreq((word)cnt);
        !           304:    if (strfree + cnt > strend)
        !           305:       syserr("string allocation botch");
        !           306:    StrLoc(Arg0) = strfree;
        !           307:    if ((cnt = fread(StrLoc(Arg0), sizeof(char), cnt, f)) <= 0)
        !           308:       Fail;
        !           309:    StrLen(Arg0) = cnt;
        !           310:    strfree += cnt;
        !           311:    Return;
        !           312:    }
        !           313: 
        !           314: 
        !           315: /*
        !           316:  * stop(a,b,...) - write arguments (starting on error output) and stop.
        !           317:  */
        !           318: 
        !           319: FncDclV(stop)
        !           320:     {
        !           321:    register word n;
        !           322:    char sbuf[MaxCvtLen];
        !           323:    struct descrip arg;
        !           324:    FILE *f;
        !           325: 
        !           326:    f = stderr;
        !           327:    /*
        !           328:     *  Loop through arguments.
        !           329:     */
        !           330: 
        !           331:    for (n = 1; n <= nargs; n++) {
        !           332:       arg = Arg(n);
        !           333:       if (arg.dword == D_File) {
        !           334:         if (n > 1)
        !           335:            putc('\n', f);
        !           336:         if ((BlkLoc(arg)->file.status & Fs_Write) == 0)
        !           337:            runerr(213, &arg);
        !           338:         f = BlkLoc(arg)->file.fd;
        !           339:         }
        !           340:       else {
        !           341:         if (n == 1 && (k_output.status & Fs_Write) == 0)
        !           342:            runerr(213, NULL);
        !           343:         if (ChkNull(arg))
        !           344:            arg = emptystr;
        !           345:         if (cvstr(&arg, sbuf) == NULL)
        !           346:            runerr(109, &arg);
        !           347:         putstr(f, StrLoc(arg), StrLen(arg));
        !           348:         }
        !           349:       }
        !           350: 
        !           351:    putc('\n', f);
        !           352:    c_exit(ErrorExit);
        !           353:    }
        !           354: 
        !           355: 
        !           356: /*
        !           357:  * system(s) - execute string s as a system command.
        !           358:  */
        !           359: 
        !           360: FncDcl(system,1)
        !           361:    {
        !           362:    char sbuf1[MaxCvtLen], sbuf2[MaxCvtLen];
        !           363: #ifdef VMS
        !           364:     struct { long size; char *ptr; } descr;
        !           365:     int status;
        !           366: #endif VMS
        !           367: 
        !           368:    /*
        !           369:     * s must be string and smaller than MaxCvtLen characters long.
        !           370:     */
        !           371:    if (cvstr(&Arg1, sbuf1) == NULL)
        !           372:       runerr(103, &Arg1);
        !           373:    if (StrLen(Arg1) >= MaxCvtLen)
        !           374:       runerr(210, &Arg1);
        !           375:    qtos(&Arg1, sbuf2);
        !           376: 
        !           377:    /*
        !           378:     * Pass the C string made by qtos to the UNIX system() function and
        !           379:     *  return the exit code of the command as the result of system().
        !           380:     */
        !           381: #ifndef VMS
        !           382:    Mkint((long)((system(sbuf2) >> 8) & 0377), &Arg0);
        !           383:    Return;
        !           384: #else
        !           385:     descr.ptr = sbuf2; descr.size = StrLen(Arg1); status = 0;
        !           386:     status = lib$spawn(&descr,0,0,0,0,0, &status,0,0,0);
        !           387:     Mkint((long)status|ErrorExit, &Arg0);
        !           388:     Return;
        !           389: #endif VMS
        !           390:    }
        !           391: 
        !           392: 
        !           393: /*
        !           394:  * write(a,b,...) - write arguments.
        !           395:  */
        !           396: FncDclV(write)
        !           397:    {
        !           398:    register word n;
        !           399:    char sbuf[MaxCvtLen];
        !           400:    struct descrip arg;
        !           401:    FILE *f;
        !           402:    extern char *alcstr();
        !           403: 
        !           404:    f = stdout;
        !           405:    arg = emptystr;
        !           406: 
        !           407:    /*
        !           408:     * Loop through the arguments.
        !           409:     */
        !           410:    for (n = 1; n <= nargs; n++) {
        !           411:       arg = Arg(n);
        !           412:       if (arg.dword == D_File) {/* Current argument is a file */
        !           413:         /*
        !           414:          * If this isn't the first argument, output a newline to the current
        !           415:          *  file and flush it.
        !           416:          */
        !           417:         if (n > 1) {
        !           418:            putc('\n', f);
        !           419:            fflush(f);
        !           420:            }
        !           421:         /*
        !           422:          * Switch the current file to the file named by the current argument
        !           423:          *  providing it is a file.  arg is made to be a empty string to
        !           424:          *  avoid a special case.
        !           425:          */
        !           426:         if ((BlkLoc(arg)->file.status & Fs_Write) == 0)
        !           427:            runerr(213, &arg);
        !           428:         f = BlkLoc(arg)->file.fd;
        !           429:         arg = emptystr;
        !           430:         }
        !           431:       else {   /* Current argument is a string */
        !           432:         /*
        !           433:          * On first argument, check to be sure that &output is open
        !           434:          *  for output.
        !           435:          */
        !           436:         if (n == 1 && (k_output.status & Fs_Write) == 0)
        !           437:            runerr(213, NULL);
        !           438:         /*
        !           439:          * Convert the argument to a string, defaulting to a empty string.
        !           440:          */
        !           441:         if (ChkNull(arg))
        !           442:            arg = emptystr;
        !           443:         if (cvstr(&arg, sbuf) == NULL)
        !           444:            runerr(109, &arg);
        !           445:         /*
        !           446:          * Output the string.
        !           447:          */
        !           448:         putstr(f, StrLoc(arg), StrLen(arg));
        !           449:         }
        !           450:       }
        !           451:    /*
        !           452:     * Append a newline to the file and flush it.
        !           453:     */
        !           454:    putc('\n', f);
        !           455:    fflush(f);
        !           456:    /*
        !           457:     * If the beginning of the last string output lies in sbuf,
        !           458:     *  allocate it as a real string.  Note that some of the string
        !           459:     *  conversions don't always leave the converted string at the
        !           460:     *  start of the conversion buffer, hence the range check.
        !           461:     */
        !           462:    if (StrLoc(arg) >= sbuf && StrLoc(arg) < sbuf + MaxCvtLen) {
        !           463:       strreq(StrLen(arg));
        !           464:       StrLoc(arg) = alcstr(StrLoc(arg), StrLen(arg));
        !           465:       }
        !           466:    /*
        !           467:     * Return the string corresponding to the last argument.
        !           468:     */
        !           469:    Arg(0) = arg;
        !           470:    Return;
        !           471:    }
        !           472: 
        !           473: 
        !           474: /*
        !           475:  * writes(a,b,...) - write arguments without newline terminator.
        !           476:  */
        !           477: 
        !           478: FncDclV(writes)
        !           479:    {
        !           480:    register word n;
        !           481:    char sbuf[MaxCvtLen];
        !           482:    struct descrip arg;
        !           483:    FILE *f;
        !           484:    extern char *alcstr();
        !           485: 
        !           486:    f = stdout;
        !           487:    arg = emptystr;
        !           488: 
        !           489:    /*
        !           490:     * Loop through the arguments.
        !           491:     */
        !           492:    for (n = 1; n <= nargs; n++) {
        !           493:       arg = Arg(n);
        !           494:       if (arg.dword == D_File) {/* Current argument is a file */
        !           495:         /*
        !           496:          * Switch the current file to the file named by the current argument
        !           497:          *  providing it is a file.  arg is made to be a empty string to
        !           498:          *  avoid a special case.
        !           499:          */
        !           500:         if ((BlkLoc(arg)->file.status & Fs_Write) == 0)
        !           501:            runerr(213, &arg);
        !           502:         f = BlkLoc(arg)->file.fd;
        !           503:         arg = emptystr;
        !           504:         }
        !           505:       else {   /* Current argument is a string */
        !           506:         /*
        !           507:          * On first argument, check to be sure that &output is open
        !           508:          *  for output.
        !           509:          */
        !           510:         if (n == 1 && (k_output.status & Fs_Write) == 0)
        !           511:            runerr(213, NULL);
        !           512:         /*
        !           513:          * Convert the argument to a string, defaulting to a empty string.
        !           514:          */
        !           515:         if (ChkNull(arg))
        !           516:            arg = emptystr;
        !           517:         if (cvstr(&arg, sbuf) == NULL)
        !           518:            runerr(109, &arg);
        !           519:         /*
        !           520:          * Output the string and flush the file.
        !           521:          */
        !           522:         putstr(f, StrLoc(arg), StrLen(arg));
        !           523:         fflush(f);
        !           524:         }
        !           525:       }
        !           526:    /*
        !           527:     * If the beginning of the last string output lies in sbuf,
        !           528:     *  allocate it as a real string.  Note that some of the string
        !           529:     *  conversions don't always leave the converted string at the
        !           530:     *  start of the conversion buffer, hence the range check.
        !           531:     */
        !           532:    if (StrLoc(arg) >= sbuf && StrLoc(arg) < sbuf + MaxCvtLen) {
        !           533:       strreq(StrLen(arg));
        !           534:       StrLoc(arg) = alcstr(StrLoc(arg), StrLen(arg));
        !           535:       }
        !           536:    /*
        !           537:     * Return the string corresponding to the last argument.
        !           538:     */
        !           539:    Arg(0) = arg;
        !           540:    Return;
        !           541:    }

unix.superglobalmegacorp.com

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