|
|
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.