|
|
1.1 ! root 1: /*************************************************************************** ! 2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * ! 3: * is provided to you without charge, and with no warranty. You may give * ! 4: * away copies of JOVE, including sources, provided that this notice is * ! 5: * included in all the files. * ! 6: ***************************************************************************/ ! 7: ! 8: #include "jove.h" ! 9: #include "fp.h" ! 10: #include "ctype.h" ! 11: #include "termcap.h" ! 12: #include "disp.h" ! 13: ! 14: #ifdef MAC ! 15: # include "mac.h" ! 16: #else ! 17: # include <sys/stat.h> ! 18: # ifndef MSDOS ! 19: # include <sys/file.h> ! 20: # else /* MSDOS */ ! 21: # include <fcntl.h> ! 22: # include <io.h> ! 23: # endif /* MSDOS */ ! 24: #endif /* MAC */ ! 25: ! 26: #include <errno.h> ! 27: ! 28: private File * f_alloc proto((char *, int, int, char *, int)); ! 29: #ifdef RAINBOW ! 30: private int rbwrite proto((int, char *, int)); ! 31: #endif ! 32: ! 33: #ifndef L_SET ! 34: # define L_SET 0 ! 35: #endif ! 36: ! 37: #define MAXFILES 20 /* good enough for my purposes */ ! 38: ! 39: private File _openfiles[MAXFILES]; /* must be zeroed initially */ ! 40: ! 41: private File * ! 42: f_alloc(name, flags, fd, buffer, buf_size) ! 43: char *name, ! 44: *buffer; ! 45: int flags, ! 46: fd, ! 47: buf_size; ! 48: { ! 49: register File *fp; ! 50: register int i; ! 51: ! 52: for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++) ! 53: if (fp->f_flags == 0) ! 54: break; ! 55: if (i == MAXFILES) ! 56: complain("[Too many open files!]"); ! 57: fp->f_bufsize = buf_size; ! 58: fp->f_cnt = 0; ! 59: fp->f_fd = fd; ! 60: fp->f_flags = flags; ! 61: if (buffer == 0) { ! 62: buffer = emalloc((size_t)buf_size); ! 63: fp->f_flags |= F_MYBUF; ! 64: } ! 65: fp->f_base = fp->f_ptr = buffer; ! 66: fp->f_name = copystr(name); ! 67: ! 68: return fp; ! 69: } ! 70: ! 71: void ! 72: gc_openfiles() ! 73: { ! 74: register File *fp; ! 75: ! 76: for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++) ! 77: if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0) ! 78: f_close(fp); ! 79: } ! 80: ! 81: File * ! 82: fd_open(name, flags, fd, buffer, bsize) ! 83: char *name, ! 84: *buffer; ! 85: int flags, ! 86: fd, ! 87: bsize; ! 88: { ! 89: return f_alloc(name, flags, fd, buffer, bsize); ! 90: } ! 91: ! 92: File * ! 93: f_open(name, flags, buffer, buf_size) ! 94: char *name, ! 95: *buffer; ! 96: int flags, ! 97: buf_size; ! 98: { ! 99: register int fd; ! 100: int mode = F_MODE(flags); ! 101: ! 102: if (mode == F_READ) ! 103: fd = open(name, 0); ! 104: if (mode == F_APPEND) { ! 105: fd = open(name, 1); ! 106: if (fd == -1) ! 107: mode = F_WRITE; ! 108: else ! 109: (void) lseek(fd, 0L, 2); ! 110: } ! 111: if (mode == F_WRITE) ! 112: fd = creat(name, CreatMode); ! 113: if (fd == -1) ! 114: return NIL; ! 115: #ifdef MSDOS ! 116: else ! 117: setmode(fd, 0x8000); ! 118: #endif /* MSDOS */ ! 119: return f_alloc(name, flags, fd, buffer, buf_size); ! 120: } ! 121: ! 122: void ! 123: f_close(fp) ! 124: File *fp; ! 125: { ! 126: flush(fp); ! 127: #ifdef BSD4_2 ! 128: if (fp->f_flags & (F_WRITE|F_APPEND)) ! 129: (void) fsync(fp->f_fd); ! 130: #endif ! 131: (void) close(fp->f_fd); ! 132: if (fp->f_flags & F_MYBUF) ! 133: free(fp->f_base); ! 134: free(fp->f_name); ! 135: fp->f_flags = 0; /* indicates that we're available */ ! 136: } ! 137: ! 138: int ! 139: filbuf(fp) ! 140: File *fp; ! 141: { ! 142: if (fp->f_flags & (F_EOF|F_ERR)) ! 143: return EOF; ! 144: fp->f_ptr = fp->f_base; ! 145: #ifndef MSDOS ! 146: do ! 147: #endif /* MSDOS */ ! 148: fp->f_cnt = read(fp->f_fd, fp->f_base, (size_t) fp->f_bufsize); ! 149: #ifndef MSDOS ! 150: while (fp->f_cnt == -1 && errno == EINTR); ! 151: #endif /* MSDOS */ ! 152: if (fp->f_cnt == -1) { ! 153: writef("[Read error %d]", errno); ! 154: fp->f_flags |= F_ERR; ! 155: } ! 156: if (fp->f_cnt == 0) { ! 157: fp->f_flags |= F_EOF; ! 158: return EOF; ! 159: } ! 160: io_chars += fp->f_cnt; ! 161: return jgetc(fp); ! 162: } ! 163: ! 164: void ! 165: putstr(s) ! 166: register char *s; ! 167: { ! 168: #ifndef IBMPC ! 169: register int c; ! 170: ! 171: while ((c = *s++) != '\0') ! 172: jputchar(c); ! 173: #else /* IBMPC */ ! 174: write_emif(s); ! 175: #endif /* IBMPC */ ! 176: } ! 177: ! 178: void ! 179: fputnchar(s, n, fp) ! 180: register char *s; ! 181: register int n; ! 182: register File *fp; ! 183: { ! 184: while (--n >= 0) ! 185: jputc(*s++, fp); ! 186: } ! 187: ! 188: void ! 189: flusho() ! 190: { ! 191: #ifndef IBMPC ! 192: _flush(EOF, stdout); ! 193: #endif /* IBMPC */ ! 194: } ! 195: ! 196: void ! 197: flush(fp) ! 198: File *fp; ! 199: { ! 200: _flush(EOF, fp); ! 201: } ! 202: ! 203: void ! 204: f_seek(fp, offset) ! 205: register File *fp; ! 206: off_t offset; ! 207: { ! 208: if (fp->f_flags & F_WRITE) ! 209: flush(fp); ! 210: fp->f_cnt = 0; /* next read will filbuf(), next write ! 211: will flush() with no bad effects */ ! 212: lseek(fp->f_fd, (long) offset, L_SET); ! 213: } ! 214: ! 215: int /* is void - but for lints sake */ ! 216: _flush(c, fp) ! 217: int c; ! 218: register File *fp; ! 219: { ! 220: register int n; ! 221: ! 222: if (fp->f_flags & (F_READ | F_STRING | F_ERR)) ! 223: return EOF; ! 224: if (((n = (fp->f_ptr - fp->f_base)) > 0) && ! 225: #ifndef RAINBOW ! 226: (write(fp->f_fd, fp->f_base, (size_t)n) != n) && ! 227: #else ! 228: (rbwrite(fp->f_fd, fp->f_base, n) != n) && ! 229: #endif ! 230: (fp != stdout)) { ! 231: fp->f_flags |= F_ERR; ! 232: error("[I/O error(%d); file = %s, fd = %d]", ! 233: errno, fp->f_name, fp->f_fd); ! 234: } ! 235: ! 236: fp->f_cnt = fp->f_bufsize; ! 237: fp->f_ptr = fp->f_base; ! 238: if (c != EOF) ! 239: return jputc(c, fp); ! 240: return EOF; ! 241: } ! 242: ! 243: int ! 244: f_gets(fp, buf, max) ! 245: register File *fp; ! 246: char *buf; ! 247: size_t max; ! 248: { ! 249: register char *cp = buf; ! 250: register int c; ! 251: char *endp = buf + max - 1; ! 252: ! 253: if (fp->f_flags & F_EOF) ! 254: return EOF; ! 255: while (((c = jgetc(fp)) != EOF) && (c != '\n')) { ! 256: if (c == '\0') /* possibly different from NULL */ ! 257: break; /* sorry we don't read nulls */ ! 258: #ifdef MSDOS ! 259: if (c == '\r') { ! 260: if ((c = jgetc(fp)) == '\n') ! 261: break; ! 262: else ! 263: *cp++ = '\r'; ! 264: } ! 265: #endif /* MSDOS */ ! 266: if (cp >= endp) { ! 267: add_mess(" [Line too long]"); ! 268: rbell(); ! 269: return EOF; ! 270: } ! 271: *cp++ = c; ! 272: } ! 273: *cp = '\0'; ! 274: if (c == EOF) { ! 275: if (cp != buf) ! 276: add_mess(" [Incomplete last line]"); ! 277: fp->f_flags |= F_EOF; ! 278: return EOF; ! 279: } ! 280: io_lines += 1; ! 281: return 0; /* this means okay */ ! 282: } ! 283: ! 284: /* skip to beginning of next line, i.e., next read returns first ! 285: character of new line */ ! 286: ! 287: void ! 288: f_toNL(fp) ! 289: register File *fp; ! 290: { ! 291: register int c; ! 292: ! 293: if (fp->f_flags & F_EOF) ! 294: return; ! 295: while (((c = jgetc(fp)) != EOF) && (c != '\n')) ! 296: ; ! 297: if (c == EOF) ! 298: fp->f_flags |= F_EOF; ! 299: } ! 300: ! 301: int ! 302: f_readn(fp, addr, n) ! 303: register File *fp; ! 304: register char *addr; ! 305: register int n; ! 306: { ! 307: int c, ! 308: nbytes = n; ! 309: ! 310: while (--n >= 0) { ! 311: c = jgetc(fp); ! 312: if (f_eof(fp)) ! 313: break; ! 314: *addr++ = c; ! 315: } ! 316: return (nbytes - (n + 1)); ! 317: } ! 318: ! 319: int ! 320: f_getint(fp) ! 321: File *fp; ! 322: { ! 323: int n = 0, ! 324: c; ! 325: ! 326: while (isdigit(c = jgetc(fp))) ! 327: n = (n * 10) + c; ! 328: return n; ! 329: } ! 330: ! 331: /* Deals with output to the terminal, setting up the amount of characters ! 332: to be buffered depending on the output baud rate. Why it's in a ! 333: separate file I don't know ... */ ! 334: ! 335: private char one_buf; ! 336: ! 337: int BufSize = 1; ! 338: ! 339: private File _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf, (char *) NIL}; ! 340: File *stdout = &_stdout; ! 341: ! 342: #undef jputchar /* for files which forget to include fp.h, ! 343: here's a real jputchar procedure. */ ! 344: void ! 345: jputchar(c) ! 346: int c; ! 347: { ! 348: jputc(c, stdout); ! 349: } ! 350: ! 351: #ifdef RAINBOW ! 352: ! 353: /* ! 354: * use the Rainbow's video output function ! 355: */ ! 356: ! 357: #include <dos.h> ! 358: ! 359: private int ! 360: rbwrite(fd, buf, cnt) ! 361: char *buf; ! 362: { ! 363: union REGS vr; ! 364: ! 365: if (fd != 1) { ! 366: write(fd, buf, cnt); ! 367: } else { ! 368: while (cnt-- > 0) { ! 369: vr.x.ax = *buf++; ! 370: vr.x.di = 0; ! 371: int86(0x18, &vr, &vr); ! 372: } ! 373: } ! 374: } ! 375: #endif /* RAINBOW */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.