BSD 4_3 development
[unix-history] / usr / contrib / jove / fp.c
CommitLineData
394a1d25
C
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
19static File _openfiles[MAXFILES] = {0};
20
21static File *
22f_alloc(name, flags, fd, buffer, buf_size)
23char *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
47gc_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
56File *
57fd_open(name, flags, fd, buffer, bsize)
58char *buffer;
59{
60 return f_alloc(name, flags, fd, buffer, bsize);
61}
62
63File *
64f_open(name, flags, buffer, buf_size)
65char *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
87f_close(fp)
88File *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
102filbuf(fp)
103File *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
121putstr(s)
122register char *s;
123{
124 register int c;
125
126 while (c = *s++)
127 putchar(c);
128}
129
130fputnchar(s, n, fp)
131register char *s;
132register int n;
133register File *fp;
134{
135 while (--n >= 0)
136 putc(*s++, fp);
137}
138
139putnchar(s, n)
140register char *s;
141register int n;
142{
143 fputnchar(s, n, stdout);
144}
145
146flusho()
147{
148 _flush(EOF, stdout);
149}
150
151flush(fp)
152File *fp;
153{
154 _flush(EOF, fp);
155}
156
157_flush(c, fp)
158register 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
179f_gets(fp, buf, max)
180register File *fp;
181char *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
214static char one_buf;
215
216int BufSize = 1;
217
218static File _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
219File *stdout = &_stdout;
220
221/* put a string with padding */
222
223tputc(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. */
230putchar(c)
231{
232 putc(c, stdout);
233}
234
235putpad(str, lines)
236char *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
248settout(ttbuf)
249char *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