|
|
1.1 ! root 1: /************************************************************************* ! 2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is * ! 3: * provided to you without charge for use only on a licensed Unix * ! 4: * system. You may copy JOVE provided that this notice is included with * ! 5: * the copy. You may not sell copies of this program or versions * ! 6: * modified for use on microcomputer systems, unless the copies are * ! 7: * included with a Unix system distribution and the source is provided. * ! 8: *************************************************************************/ ! 9: ! 10: #include "jove.h" ! 11: #include "io.h" ! 12: #include "termcap.h" ! 13: #include <sys/stat.h> ! 14: #include <sys/file.h> ! 15: #include <errno.h> ! 16: ! 17: #define MAXFILES 20 /* good enough for my purposes */ ! 18: ! 19: static File _openfiles[MAXFILES] = {0}; ! 20: ! 21: static File * ! 22: f_alloc(name, flags, fd, buffer, buf_size) ! 23: char *buffer; ! 24: { ! 25: register File *fp; ! 26: register int i; ! 27: ! 28: for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++) ! 29: if (fp->f_flags == 0) ! 30: break; ! 31: if (i == MAXFILES) ! 32: complain("[Too many open files!]"); ! 33: fp->f_bufsize = buf_size; ! 34: fp->f_cnt = 0; ! 35: fp->f_fd = fd; ! 36: fp->f_flags = flags; ! 37: if (buffer == 0) { ! 38: buffer = emalloc(buf_size); ! 39: fp->f_flags |= F_MYBUF; ! 40: } ! 41: fp->f_base = fp->f_ptr = buffer; ! 42: fp->f_name = copystr(name); ! 43: ! 44: return fp; ! 45: } ! 46: ! 47: gc_openfiles() ! 48: { ! 49: register File *fp; ! 50: ! 51: for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++) ! 52: if (fp->f_flags != 0 && (fp->f_flags & F_LOCK) == 0) ! 53: f_close(fp); ! 54: } ! 55: ! 56: File * ! 57: fd_open(name, flags, fd, buffer, bsize) ! 58: char *buffer; ! 59: { ! 60: return f_alloc(name, flags, fd, buffer, bsize); ! 61: } ! 62: ! 63: File * ! 64: f_open(name, flags, buffer, buf_size) ! 65: char *name, ! 66: *buffer; ! 67: { ! 68: register int fd; ! 69: int mode = F_MODE(flags); ! 70: ! 71: if (mode == F_READ) ! 72: fd = open(name, 0); ! 73: if (mode == F_APPEND) { ! 74: fd = open(name, 1); ! 75: if (fd == -1) ! 76: mode = F_WRITE; ! 77: else ! 78: (void) lseek(fd, (long) 0, 2); ! 79: } ! 80: if (mode == F_WRITE) ! 81: fd = creat(name, CreatMode); ! 82: if (fd == -1) ! 83: return NIL; ! 84: return f_alloc(name, flags, fd, buffer, buf_size); ! 85: } ! 86: ! 87: f_close(fp) ! 88: File *fp; ! 89: { ! 90: flush(fp); ! 91: #ifdef BSD4_2 ! 92: if (fp->f_flags & (F_WRITE|F_APPEND)) ! 93: (void) fsync(fp->f_fd); ! 94: #endif ! 95: (void) close(fp->f_fd); ! 96: if (fp->f_flags & F_MYBUF) ! 97: free(fp->f_base); ! 98: free(fp->f_name); ! 99: fp->f_flags = 0; /* indicates that we're available */ ! 100: } ! 101: ! 102: filbuf(fp) ! 103: File *fp; ! 104: { ! 105: if (fp->f_flags & (F_EOF|F_ERR)) ! 106: return EOF; ! 107: fp->f_ptr = fp->f_base; ! 108: fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize); ! 109: if (fp->f_cnt == -1) { ! 110: printf("[Read error %d]", errno); ! 111: fp->f_flags |= F_ERR; ! 112: } ! 113: if (fp->f_cnt == 0) { ! 114: fp->f_flags |= F_EOF; ! 115: return EOF; ! 116: } ! 117: io_chars += fp->f_cnt; ! 118: return getc(fp); ! 119: } ! 120: ! 121: putstr(s) ! 122: register char *s; ! 123: { ! 124: register int c; ! 125: ! 126: while (c = *s++) ! 127: putchar(c); ! 128: } ! 129: ! 130: fputnchar(s, n, fp) ! 131: register char *s; ! 132: register int n; ! 133: register File *fp; ! 134: { ! 135: while (--n >= 0) ! 136: putc(*s++, fp); ! 137: } ! 138: ! 139: putnchar(s, n) ! 140: register char *s; ! 141: register int n; ! 142: { ! 143: fputnchar(s, n, stdout); ! 144: } ! 145: ! 146: flusho() ! 147: { ! 148: _flush(EOF, stdout); ! 149: } ! 150: ! 151: flush(fp) ! 152: File *fp; ! 153: { ! 154: _flush(EOF, fp); ! 155: } ! 156: ! 157: _flush(c, fp) ! 158: register File *fp; ! 159: { ! 160: register int n; ! 161: ! 162: if ((fp->f_flags & F_READ) || ! 163: ((fp->f_flags & F_STRING))) ! 164: return; ! 165: if (((n = (fp->f_ptr - fp->f_base)) > 0) && ! 166: (write(fp->f_fd, fp->f_base, n) != n) && ! 167: (fp != stdout)) ! 168: error("[I/O error(%d); file = %s, fd = %d]", ! 169: errno, fp->f_name, fp->f_fd); ! 170: ! 171: if (fp == stdout) ! 172: OkayAbort = YES; ! 173: fp->f_cnt = fp->f_bufsize; ! 174: fp->f_ptr = fp->f_base; ! 175: if (c != EOF) ! 176: putc(c, fp); ! 177: } ! 178: ! 179: f_gets(fp, buf, max) ! 180: register File *fp; ! 181: char *buf; ! 182: { ! 183: register char *cp = buf; ! 184: register int c; ! 185: char *endp = buf + max - 1; ! 186: ! 187: if (fp->f_flags & F_EOF) ! 188: return EOF; ! 189: while (((c = getc(fp)) != EOF) && (c != '\n')) { ! 190: if (c == NULL) ! 191: continue; /* sorry we don't read nulls */ ! 192: if (cp >= endp) { ! 193: add_mess(" [Line too long]"); ! 194: rbell(); ! 195: return EOF; ! 196: } ! 197: *cp++ = c; ! 198: } ! 199: *cp = '\0'; ! 200: if (c == EOF) { ! 201: if (cp != buf) ! 202: add_mess(" [Incomplete last line]"); ! 203: fp->f_flags |= F_EOF; ! 204: return EOF; ! 205: } ! 206: io_lines++; ! 207: return NIL; /* this means okay */ ! 208: } ! 209: ! 210: /* Deals with output to the terminal, setting up the amount of characters ! 211: to be buffered depending on the output baud rate. Why it's in a ! 212: separate file I don't know ... */ ! 213: ! 214: static char one_buf; ! 215: ! 216: int BufSize = 1; ! 217: ! 218: static File _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf}; ! 219: File *stdout = &_stdout; ! 220: ! 221: /* put a string with padding */ ! 222: ! 223: tputc(c) ! 224: { ! 225: putchar(c); ! 226: } ! 227: ! 228: #undef putchar /* for files which forget to include io.h, ! 229: here's a real putchar procedure. */ ! 230: putchar(c) ! 231: { ! 232: putc(c, stdout); ! 233: } ! 234: ! 235: putpad(str, lines) ! 236: char *str; ! 237: { ! 238: if (str) ! 239: tputs(str, lines, tputc); ! 240: } ! 241: ! 242: /* Determine the number of characters to buffer at each baud rate. The ! 243: lower the number, the quicker the response when new input arrives. Of ! 244: course the lower the number, the more prone the program is to stop in ! 245: output. Decide what matters most to you. This sets BufSize to the right ! 246: number or chars, and initiaizes `stdout'. */ ! 247: ! 248: settout(ttbuf) ! 249: char *ttbuf; ! 250: { ! 251: static int speeds[] = { ! 252: 1, /* 0 */ ! 253: 1, /* 50 */ ! 254: 1, /* 75 */ ! 255: 1, /* 110 */ ! 256: 1, /* 134 */ ! 257: 1, /* 150 */ ! 258: 1, /* 200 */ ! 259: 2, /* 300 */ ! 260: 4, /* 600 */ ! 261: 8, /* 1200 */ ! 262: 16, /* 1800 */ ! 263: 32, /* 2400 */ ! 264: 128, /* 4800 */ ! 265: 256, /* 9600 */ ! 266: 512, /* EXTA */ ! 267: 512 /* EXT */ ! 268: }; ! 269: BufSize = min(512, (speeds[ospeed] * max(LI / 24, 1))); ! 270: stdout = fd_open("/dev/tty", F_WRITE|F_LOCK, 1, ttbuf, BufSize); ! 271: } ! 272:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.