|
|
1.1 ! root 1: #include "../h/rt.h" ! 2: ! 3: /* ! 4: * open(s1,s2) - open file s1 with specification s2. ! 5: */ ! 6: Xopen(nargs, arg2, arg1, arg0) ! 7: int nargs; ! 8: struct descrip arg2, arg1, arg0; ! 9: { ! 10: register int slen, i; ! 11: register char *s; ! 12: int status; ! 13: char sbuf1[MAXSTRING], sbuf2[MAXSTRING], mode[3]; ! 14: FILE *f; ! 15: extern struct b_file *alcfile(); ! 16: extern char *alcstr(); ! 17: extern FILE *fopen(), *popen(); ! 18: ! 19: /* ! 20: * s1 must be a string and a C string copy of it is also needed. ! 21: * Make it a string if it isn't one; make a C string if s1 is ! 22: * a string. ! 23: */ ! 24: switch (cvstr(&arg1, sbuf1)) { ! 25: case 1: ! 26: sneed(STRLEN(arg1)); ! 27: STRLOC(arg1) = alcstr(STRLOC(arg1), STRLEN(arg1)); ! 28: break; ! 29: case 2: ! 30: qtos(&arg1, sbuf1); ! 31: break; ! 32: default: ! 33: runerr(103, &arg1); ! 34: } ! 35: /* ! 36: * s2 defaults to "r". ! 37: */ ! 38: defstr(&arg2, sbuf2, &letr); ! 39: ! 40: hneed(sizeof(struct b_file)); ! 41: status = 0; ! 42: ! 43: /* ! 44: * Scan s2, setting appropriate bits in status. Produce a runerr ! 45: * if an unknown character is encountered. ! 46: */ ! 47: s = STRLOC(arg2); ! 48: slen = STRLEN(arg2); ! 49: for (i = 0; i < slen; i++) { ! 50: switch (*s++) { ! 51: case 'a': case 'A': ! 52: status |= FS_WRITE|FS_APPEND; ! 53: continue; ! 54: case 'b': case 'B': ! 55: status |= FS_READ|FS_WRITE; ! 56: continue; ! 57: case 'c': case 'C': ! 58: status |= FS_CREATE|FS_WRITE; ! 59: continue; ! 60: case 'p': case 'P': ! 61: status |= FS_PIPE; ! 62: continue; ! 63: case 'r': case 'R': ! 64: status |= FS_READ; ! 65: continue; ! 66: case 'w': case 'W': ! 67: status |= FS_WRITE; ! 68: continue; ! 69: default: ! 70: runerr(209, &arg2); ! 71: } ! 72: } ! 73: ! 74: /* ! 75: * Construct a mode field for fopen/popen. ! 76: */ ! 77: mode[0] = '\0'; ! 78: mode[1] = '\0'; ! 79: mode[2] = '\0'; ! 80: if ((status & (FS_READ|FS_WRITE)) == 0) /* default: read only */ ! 81: status |= FS_READ; ! 82: if (status & FS_CREATE) ! 83: mode[0] = 'w'; ! 84: else if (status & FS_APPEND) ! 85: mode[0] = 'a'; ! 86: else if (status & FS_READ) ! 87: mode[0] = 'r'; ! 88: else ! 89: mode[0] = 'w'; ! 90: if ((status & (FS_READ|FS_WRITE)) == (FS_READ|FS_WRITE)) ! 91: mode[1] = '+'; ! 92: ! 93: /* ! 94: * Open the file with fopen or popen. ! 95: */ ! 96: if (status & FS_PIPE) { ! 97: if (status != (FS_READ|FS_PIPE) && status != (FS_WRITE|FS_PIPE)) ! 98: runerr(209, &arg2); ! 99: f = popen(sbuf1, mode); ! 100: } ! 101: else ! 102: f = fopen(sbuf1, mode); ! 103: /* ! 104: * Fail if the file can't be opened. ! 105: */ ! 106: if (f == NULL) ! 107: fail(); ! 108: /* ! 109: * If the file isn't a terminal and a buffer is available, assign ! 110: * it to the file. ! 111: */ ! 112: if (!isatty(fileno(f))) { ! 113: for (i = 0; i < numbufs; i++) ! 114: if (bufused[i] == NULL) ! 115: break; ! 116: if (i < numbufs) { /* Use buffer if any free. */ ! 117: setbuf(f, bufs[i]); ! 118: bufused[i] = f; ! 119: } ! 120: else ! 121: setbuf(f, NULL); ! 122: } ! 123: else ! 124: setbuf(f, NULL); ! 125: /* ! 126: * Return the resulting file value. ! 127: */ ! 128: arg0.type = D_FILE; ! 129: BLKLOC(arg0) = (union block *) alcfile(f, status, &arg1); ! 130: } ! 131: ! 132: Procblock(open,2)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.