Annotation of researchv10dc/cmd/icon/src/iconx/fsys.c, revision 1.1.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.