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