|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T f ┃
Length: 5151 (0x141f) Types: TextFile Names: »fp.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/jove/fp.c«
/************************************************************************ * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * * provided to you without charge, and with no warranty. You may give * * away copies of JOVE, including sources, provided that this notice is * * included in all the files. * ************************************************************************/ #include "jove.h" #include "io.h" #include "termcap.h" #include <sys/stat.h> #include <sys/file.h> #include <errno.h> #define MAXFILES 20 /* good enough for my purposes */ static File _openfiles[MAXFILES] = {0}; static File * f_alloc(name, flags, fd, buffer, buf_size) char *name, *buffer; { register File *fp; register int i; for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++) if (fp->f_flags == 0) break; if (i == MAXFILES) complain("[Too many open files!]"); fp->f_bufsize = buf_size; fp->f_cnt = 0; fp->f_fd = fd; fp->f_flags = flags; if (buffer == 0) { buffer = emalloc(buf_size); fp->f_flags |= F_MYBUF; } fp->f_base = fp->f_ptr = buffer; fp->f_name = copystr(name); return fp; } gc_openfiles() { register File *fp; for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++) if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0) f_close(fp); } File * fd_open(name, flags, fd, buffer, bsize) char *name, *buffer; { return f_alloc(name, flags, fd, buffer, bsize); } File * f_open(name, flags, buffer, buf_size) char *name, *buffer; { register int fd; int mode = F_MODE(flags); if (mode == F_READ) fd = open(name, 0); if (mode == F_APPEND) { fd = open(name, 1); if (fd == -1) mode = F_WRITE; else (void) lseek(fd, 0L, 2); } if (mode == F_WRITE) fd = creat(name, CreatMode); if (fd == -1) return NIL; return f_alloc(name, flags, fd, buffer, buf_size); } f_close(fp) File *fp; { flush(fp); #ifdef BSD4_2 if (fp->f_flags & (F_WRITE|F_APPEND)) (void) fsync(fp->f_fd); #endif (void) close(fp->f_fd); if (fp->f_flags & F_MYBUF) free(fp->f_base); free(fp->f_name); fp->f_flags = 0; /* indicates that we're available */ } filbuf(fp) File *fp; { if (fp->f_flags & (F_EOF|F_ERR)) return EOF; fp->f_ptr = fp->f_base; fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize); if (fp->f_cnt == -1) { printf("[Read error %d]", errno); fp->f_flags |= F_ERR; } if (fp->f_cnt == 0) { fp->f_flags |= F_EOF; return EOF; } io_chars += fp->f_cnt; return getc(fp); } putstr(s) register char *s; { register int c; while (c = *s++) putchar(c); } fputnchar(s, n, fp) register char *s; register int n; register File *fp; { while (--n >= 0) putc(*s++, fp); } flusho() { _flush(EOF, stdout); } flush(fp) File *fp; { _flush(EOF, fp); } _flush(c, fp) register File *fp; { register int n; if (fp->f_flags & (F_READ | F_STRING | F_ERR)) return; if (((n = (fp->f_ptr - fp->f_base)) > 0) && (write(fp->f_fd, fp->f_base, n) != n) && (fp != stdout)) { fp->f_flags |= F_ERR; error("[I/O error(%d); file = %s, fd = %d]", errno, fp->f_name, fp->f_fd); } if (fp == stdout) OkayAbort = YES; fp->f_cnt = fp->f_bufsize; fp->f_ptr = fp->f_base; if (c != EOF) putc(c, fp); } f_gets(fp, buf, max) register File *fp; char *buf; { register char *cp = buf; register int c; char *endp = buf + max - 1; if (fp->f_flags & F_EOF) return EOF; while (((c = getc(fp)) != EOF) && (c != '\n')) { if (c == NULL) continue; /* sorry we don't read nulls */ if (cp >= endp) { add_mess(" [Line too long]"); rbell(); return EOF; } *cp++ = c; } *cp = '\0'; if (c == EOF) { if (cp != buf) add_mess(" [Incomplete last line]"); fp->f_flags |= F_EOF; return EOF; } io_lines++; return NIL; /* this means okay */ } /* Deals with output to the terminal, setting up the amount of characters to be buffered depending on the output baud rate. Why it's in a separate file I don't know ... */ static char one_buf; int BufSize = 1; static File _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf}; File *stdout = &_stdout; /* put a string with padding */ tputc(c) { putchar(c); } #undef putchar /* for files which forget to include io.h, here's a real putchar procedure. */ putchar(c) { putc(c, stdout); } putpad(str, lines) char *str; { if (str) tputs(str, lines, tputc); } /* Determine the number of characters to buffer at each baud rate. The lower the number, the quicker the response when new input arrives. Of course the lower the number, the more prone the program is to stop in output. Decide what matters most to you. This sets BufSize to the right number or chars, and initiaizes `stdout'. */ settout(ttbuf) char *ttbuf; { static int speeds[] = { 1, /* 0 */ 1, /* 50 */ 1, /* 75 */ 1, /* 110 */ 1, /* 134 */ 1, /* 150 */ 1, /* 200 */ 2, /* 300 */ 4, /* 600 */ 8, /* 1200 */ 16, /* 1800 */ 32, /* 2400 */ 128, /* 4800 */ 256, /* 9600 */ 512, /* EXTA */ 512 /* EXT */ }; BufSize = min(512, (speeds[ospeed] * max(LI / 24, 1))); stdout = fd_open("/dev/tty", F_WRITE|F_LOCKED, 1, ttbuf, BufSize); }