annotate miscellany/less-177/ch.c @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
bce86c4163a3 Initial revision
kono
parents:
diff changeset
1 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
2 * Low level character input from the input file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
3 * We use these special purpose routines which optimize moving
bce86c4163a3 Initial revision
kono
parents:
diff changeset
4 * both forward and backward from the current read pointer.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
5 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
6
bce86c4163a3 Initial revision
kono
parents:
diff changeset
7 #include "less.h"
bce86c4163a3 Initial revision
kono
parents:
diff changeset
8
bce86c4163a3 Initial revision
kono
parents:
diff changeset
9 public int file = -1; /* File descriptor of the input file */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
10 public int ignore_eoi;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
11
bce86c4163a3 Initial revision
kono
parents:
diff changeset
12 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
13 * Pool of buffers holding the most recently used blocks of the input file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
14 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
15 #define BUFSIZ 1024
bce86c4163a3 Initial revision
kono
parents:
diff changeset
16 struct buf {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
17 struct buf *next, *prev; /* Must be first to match struct filestate */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
18 long block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
19 unsigned int datasize;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
20 unsigned char data[BUFSIZ];
bce86c4163a3 Initial revision
kono
parents:
diff changeset
21 };
bce86c4163a3 Initial revision
kono
parents:
diff changeset
22
bce86c4163a3 Initial revision
kono
parents:
diff changeset
23 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
24 * The buffer pool is kept as a doubly-linked circular list,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
25 * in order from most- to least-recently used.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
26 * The circular list is anchored by the file state "thisfile".
bce86c4163a3 Initial revision
kono
parents:
diff changeset
27 *
bce86c4163a3 Initial revision
kono
parents:
diff changeset
28 * The file state is maintained in a filestate structure.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
29 * There are two such structures, one used when input is a pipe
bce86c4163a3 Initial revision
kono
parents:
diff changeset
30 * and the other when input is an ordinary file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
31 * This is so that we can leave a pipe, look and other files,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
32 * and return to the pipe without losing buffered data.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
33 * Buffered data can be reconstructed for a non-pipe file by
bce86c4163a3 Initial revision
kono
parents:
diff changeset
34 * simply re-reading the file, but a pipe cannot be re-read.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
35 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
36
bce86c4163a3 Initial revision
kono
parents:
diff changeset
37 struct filestate {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
38 struct buf *next, *prev; /* Must be first to match struct buf */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
39 POSITION fpos;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
40 int nbufs;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
41 long block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
42 int offset;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
43 POSITION fsize;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
44 };
bce86c4163a3 Initial revision
kono
parents:
diff changeset
45
bce86c4163a3 Initial revision
kono
parents:
diff changeset
46 #define END_OF_CHAIN ((struct buf *)thisfile)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
47 #define buf_head thisfile->next
bce86c4163a3 Initial revision
kono
parents:
diff changeset
48 #define buf_tail thisfile->prev
bce86c4163a3 Initial revision
kono
parents:
diff changeset
49 #define ch_nbufs thisfile->nbufs
bce86c4163a3 Initial revision
kono
parents:
diff changeset
50 #define ch_block thisfile->block
bce86c4163a3 Initial revision
kono
parents:
diff changeset
51 #define ch_offset thisfile->offset
bce86c4163a3 Initial revision
kono
parents:
diff changeset
52 #define ch_fpos thisfile->fpos
bce86c4163a3 Initial revision
kono
parents:
diff changeset
53 #define ch_fsize thisfile->fsize
bce86c4163a3 Initial revision
kono
parents:
diff changeset
54
bce86c4163a3 Initial revision
kono
parents:
diff changeset
55 static struct filestate pipefile =
bce86c4163a3 Initial revision
kono
parents:
diff changeset
56 { (struct buf *)&pipefile, (struct buf *)&pipefile };
bce86c4163a3 Initial revision
kono
parents:
diff changeset
57
bce86c4163a3 Initial revision
kono
parents:
diff changeset
58 static struct filestate nonpipefile =
bce86c4163a3 Initial revision
kono
parents:
diff changeset
59 { (struct buf *)&nonpipefile, (struct buf *)&nonpipefile };
bce86c4163a3 Initial revision
kono
parents:
diff changeset
60
bce86c4163a3 Initial revision
kono
parents:
diff changeset
61 static struct filestate *thisfile;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
62
bce86c4163a3 Initial revision
kono
parents:
diff changeset
63 extern int ispipe;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
64 extern int autobuf;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
65 extern int sigs;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
66 #if LOGFILE
bce86c4163a3 Initial revision
kono
parents:
diff changeset
67 extern int logfile;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
68 extern char *namelogfile;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
69 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
70
bce86c4163a3 Initial revision
kono
parents:
diff changeset
71 static int ch_addbuf();
bce86c4163a3 Initial revision
kono
parents:
diff changeset
72
bce86c4163a3 Initial revision
kono
parents:
diff changeset
73
bce86c4163a3 Initial revision
kono
parents:
diff changeset
74 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
75 * Get the character pointed to by the read pointer.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
76 * ch_get() is a macro which is more efficient to call
bce86c4163a3 Initial revision
kono
parents:
diff changeset
77 * than fch_get (the function), in the usual case
bce86c4163a3 Initial revision
kono
parents:
diff changeset
78 * that the block desired is at the head of the chain.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
79 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
80 #define ch_get() ((ch_block == buf_head->block && \
bce86c4163a3 Initial revision
kono
parents:
diff changeset
81 ch_offset < buf_head->datasize) ? \
bce86c4163a3 Initial revision
kono
parents:
diff changeset
82 buf_head->data[ch_offset] : fch_get())
bce86c4163a3 Initial revision
kono
parents:
diff changeset
83 static int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
84 fch_get()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
85 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
86 register struct buf *bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
87 register int n;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
88 register int slept;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
89 POSITION pos;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
90 POSITION len;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
91
bce86c4163a3 Initial revision
kono
parents:
diff changeset
92 slept = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
93
bce86c4163a3 Initial revision
kono
parents:
diff changeset
94 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
95 * Look for a buffer holding the desired block.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
96 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
97 for (bp = buf_head; bp != END_OF_CHAIN; bp = bp->next)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
98 if (bp->block == ch_block)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
99 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
100 if (ch_offset >= bp->datasize)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
101 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
102 * Need more data in this buffer.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
103 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
104 goto read_more;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
105 goto found;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
106 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
107 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
108 * Block is not in a buffer.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
109 * Take the least recently used buffer
bce86c4163a3 Initial revision
kono
parents:
diff changeset
110 * and read the desired block into it.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
111 * If the LRU buffer has data in it,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
112 * and autobuf is true, and input is a pipe,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
113 * then try to allocate a new buffer first.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
114 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
115 if (autobuf && ispipe && buf_tail->block != (long)(-1))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
116 if (ch_addbuf(1))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
117 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
118 * Allocation failed: turn off autobuf.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
119 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
120 autobuf = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
121 bp = buf_tail;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
122 bp->block = ch_block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
123 bp->datasize = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
124
bce86c4163a3 Initial revision
kono
parents:
diff changeset
125 read_more:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
126 pos = (ch_block * BUFSIZ) + bp->datasize;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
127 if ((len = ch_length()) != NULL_POSITION && pos >= len)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
128 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
129 * At end of file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
130 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
131 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
132
bce86c4163a3 Initial revision
kono
parents:
diff changeset
133 if (pos != ch_fpos)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
134 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
135 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
136 * Not at the correct position: must seek.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
137 * If input is a pipe, we're in trouble (can't seek on a pipe).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
138 * Some data has been lost: just return "?".
bce86c4163a3 Initial revision
kono
parents:
diff changeset
139 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
140 if (ispipe)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
141 return ('?');
bce86c4163a3 Initial revision
kono
parents:
diff changeset
142 if (lseek(file, (offset_t)pos, 0) == BAD_LSEEK)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
143 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
144 error("seek error", NULL_PARG);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
145 quit(1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
146 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
147 ch_fpos = pos;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
148 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
149
bce86c4163a3 Initial revision
kono
parents:
diff changeset
150 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
151 * Read the block.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
152 * If we read less than a full block, that's ok.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
153 * We use partial block and pick up the rest next time.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
154 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
155 n = iread(file, &bp->data[bp->datasize],
bce86c4163a3 Initial revision
kono
parents:
diff changeset
156 (unsigned int)(BUFSIZ - bp->datasize));
bce86c4163a3 Initial revision
kono
parents:
diff changeset
157 if (n == READ_INTR)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
158 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
159 if (n < 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
160 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
161 error("read error", NULL_PARG);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
162 quit(1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
163 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
164 ch_fpos += n;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
165
bce86c4163a3 Initial revision
kono
parents:
diff changeset
166 #if LOGFILE
bce86c4163a3 Initial revision
kono
parents:
diff changeset
167 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
168 * If we have a log file, write the new data to it.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
169 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
170 if (logfile >= 0 && n > 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
171 write(logfile, (char *) &bp->data[bp->datasize], n);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
172 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
173
bce86c4163a3 Initial revision
kono
parents:
diff changeset
174 bp->datasize += n;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
175
bce86c4163a3 Initial revision
kono
parents:
diff changeset
176 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
177 * If we have read to end of file, set ch_fsize to indicate
bce86c4163a3 Initial revision
kono
parents:
diff changeset
178 * the position of the end of file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
179 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
180 if (n == 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
181 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
182 ch_fsize = pos;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
183 if (ignore_eoi)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
184 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
185 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
186 * We are ignoring EOF.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
187 * Wait a while, then try again.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
188 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
189 if (!slept)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
190 ierror("Waiting for data", NULL_PARG);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
191 sleep(1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
192 slept = 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
193 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
194 if (sigs)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
195 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
196 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
197
bce86c4163a3 Initial revision
kono
parents:
diff changeset
198 found:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
199 if (buf_head != bp)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
200 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
201 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
202 * Move the buffer to the head of the buffer chain.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
203 * This orders the buffer chain, most- to least-recently used.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
204 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
205 bp->next->prev = bp->prev;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
206 bp->prev->next = bp->next;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
207
bce86c4163a3 Initial revision
kono
parents:
diff changeset
208 bp->next = buf_head;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
209 bp->prev = END_OF_CHAIN;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
210 buf_head->prev = bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
211 buf_head = bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
212 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
213
bce86c4163a3 Initial revision
kono
parents:
diff changeset
214 if (ch_offset >= bp->datasize)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
215 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
216 * After all that, we still don't have enough data.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
217 * Go back and try again.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
218 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
219 goto read_more;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
220
bce86c4163a3 Initial revision
kono
parents:
diff changeset
221 return (bp->data[ch_offset]);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
222 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
223
bce86c4163a3 Initial revision
kono
parents:
diff changeset
224 #if LOGFILE
bce86c4163a3 Initial revision
kono
parents:
diff changeset
225 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
226 * Close the logfile.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
227 * If we haven't read all of standard input into it, do that now.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
228 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
229 public void
bce86c4163a3 Initial revision
kono
parents:
diff changeset
230 end_logfile()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
231 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
232 static int tried = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
233
bce86c4163a3 Initial revision
kono
parents:
diff changeset
234 if (logfile < 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
235 return;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
236 if (!tried && ch_fsize == NULL_POSITION)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
237 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
238 tried = 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
239 ierror("Finishing logfile", NULL_PARG);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
240 while (ch_forw_get() != EOI)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
241 if (sigs)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
242 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
243 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
244 close(logfile);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
245 logfile = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
246 namelogfile = NULL;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
247 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
248
bce86c4163a3 Initial revision
kono
parents:
diff changeset
249 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
250 * Start a log file AFTER less has already been running.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
251 * Invoked from the - command; see toggle_option().
bce86c4163a3 Initial revision
kono
parents:
diff changeset
252 * Write all the existing buffered data to the log file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
253 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
254 public void
bce86c4163a3 Initial revision
kono
parents:
diff changeset
255 sync_logfile()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
256 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
257 register struct buf *bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
258 long block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
259 long last_block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
260
bce86c4163a3 Initial revision
kono
parents:
diff changeset
261 last_block = (ch_fpos + BUFSIZ - 1) / BUFSIZ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
262 for (block = 0; block <= last_block; block++)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
263 for (bp = buf_head; bp != END_OF_CHAIN; bp = bp->next)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
264 if (bp->block == block)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
265 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
266 write(logfile, (char *) bp->data, bp->datasize);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
267 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
268 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
269 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
270
bce86c4163a3 Initial revision
kono
parents:
diff changeset
271 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
272
bce86c4163a3 Initial revision
kono
parents:
diff changeset
273 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
274 * Determine if a specific block is currently in one of the buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
275 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
276 static int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
277 buffered(block)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
278 long block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
279 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
280 register struct buf *bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
281
bce86c4163a3 Initial revision
kono
parents:
diff changeset
282 for (bp = buf_head; bp != END_OF_CHAIN; bp = bp->next)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
283 if (bp->block == block)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
284 return (1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
285 return (0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
286 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
287
bce86c4163a3 Initial revision
kono
parents:
diff changeset
288 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
289 * Seek to a specified position in the file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
290 * Return 0 if successful, non-zero if can't seek there.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
291 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
292 public int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
293 ch_seek(pos)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
294 register POSITION pos;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
295 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
296 long new_block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
297 POSITION len;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
298
bce86c4163a3 Initial revision
kono
parents:
diff changeset
299 len = ch_length();
bce86c4163a3 Initial revision
kono
parents:
diff changeset
300 if (pos < ch_zero() || (len != NULL_POSITION && pos > len))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
301 return (1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
302
bce86c4163a3 Initial revision
kono
parents:
diff changeset
303 new_block = pos / BUFSIZ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
304 if (ispipe && pos != ch_fpos && !buffered(new_block))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
305 return (1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
306 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
307 * Set read pointer.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
308 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
309 ch_block = new_block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
310 ch_offset = pos % BUFSIZ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
311 return (0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
312 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
313
bce86c4163a3 Initial revision
kono
parents:
diff changeset
314 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
315 * Seek to the end of the file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
316 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
317 public int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
318 ch_end_seek()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
319 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
320 POSITION len;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
321
bce86c4163a3 Initial revision
kono
parents:
diff changeset
322 if (!ispipe)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
323 ch_fsize = filesize(file);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
324
bce86c4163a3 Initial revision
kono
parents:
diff changeset
325 len = ch_length();
bce86c4163a3 Initial revision
kono
parents:
diff changeset
326 if (len != NULL_POSITION)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
327 return (ch_seek(len));
bce86c4163a3 Initial revision
kono
parents:
diff changeset
328
bce86c4163a3 Initial revision
kono
parents:
diff changeset
329 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
330 * Do it the slow way: read till end of data.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
331 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
332 while (ch_forw_get() != EOI)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
333 if (sigs)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
334 return (1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
335 return (0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
336 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
337
bce86c4163a3 Initial revision
kono
parents:
diff changeset
338 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
339 * Seek to the beginning of the file, or as close to it as we can get.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
340 * We may not be able to seek there if input is a pipe and the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
341 * beginning of the pipe is no longer buffered.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
342 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
343 public int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
344 ch_beg_seek()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
345 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
346 register struct buf *bp, *firstbp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
347
bce86c4163a3 Initial revision
kono
parents:
diff changeset
348 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
349 * Try a plain ch_seek first.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
350 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
351 if (ch_seek(ch_zero()) == 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
352 return (0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
353
bce86c4163a3 Initial revision
kono
parents:
diff changeset
354 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
355 * Can't get to position 0.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
356 * Look thru the buffers for the one closest to position 0.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
357 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
358 firstbp = bp = buf_head;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
359 if (bp == END_OF_CHAIN)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
360 return (1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
361 while ((bp = bp->next) != END_OF_CHAIN)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
362 if (bp->block < firstbp->block)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
363 firstbp = bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
364 ch_block = firstbp->block;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
365 ch_offset = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
366 return (0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
367 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
368
bce86c4163a3 Initial revision
kono
parents:
diff changeset
369 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
370 * Return the length of the file, if known.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
371 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
372 public POSITION
bce86c4163a3 Initial revision
kono
parents:
diff changeset
373 ch_length()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
374 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
375 if (ignore_eoi)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
376 return (NULL_POSITION);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
377 return (ch_fsize);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
378 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
379
bce86c4163a3 Initial revision
kono
parents:
diff changeset
380 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
381 * Return the current position in the file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
382 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
383 #define tellpos(blk,off) ((POSITION)((((long)(blk)) * BUFSIZ) + (off)))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
384
bce86c4163a3 Initial revision
kono
parents:
diff changeset
385 public POSITION
bce86c4163a3 Initial revision
kono
parents:
diff changeset
386 ch_tell()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
387 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
388 return (tellpos(ch_block, ch_offset));
bce86c4163a3 Initial revision
kono
parents:
diff changeset
389 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
390
bce86c4163a3 Initial revision
kono
parents:
diff changeset
391 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
392 * Get the current char and post-increment the read pointer.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
393 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
394 public int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
395 ch_forw_get()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
396 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
397 register int c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
398
bce86c4163a3 Initial revision
kono
parents:
diff changeset
399 c = ch_get();
bce86c4163a3 Initial revision
kono
parents:
diff changeset
400 if (c == EOI)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
401 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
402 if (ch_offset < BUFSIZ-1)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
403 ch_offset++;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
404 else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
405 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
406 #if __ZOFFSET /* NOT WORKING */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
407 if (ch_fsize != NULL_POSITION &&
bce86c4163a3 Initial revision
kono
parents:
diff changeset
408 tellpos(ch_block+1, 0) >= ch_fsize)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
409 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
410 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
411 ch_block ++;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
412 ch_offset = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
413 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
414 return (c);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
415 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
416
bce86c4163a3 Initial revision
kono
parents:
diff changeset
417 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
418 * Pre-decrement the read pointer and get the new current char.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
419 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
420 public int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
421 ch_back_get()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
422 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
423 if (ch_offset > 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
424 ch_offset --;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
425 else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
426 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
427 #if __ZOFFSET /* NOT WORKING */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
428 if (tellpos(ch_block-1, BUFSIZ-1) < ch_zero())
bce86c4163a3 Initial revision
kono
parents:
diff changeset
429 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
430 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
431 if (ch_block <= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
432 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
433 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
434 if (ispipe && !buffered(ch_block-1))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
435 return (EOI);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
436 ch_block--;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
437 ch_offset = BUFSIZ-1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
438 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
439 return (ch_get());
bce86c4163a3 Initial revision
kono
parents:
diff changeset
440 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
441
bce86c4163a3 Initial revision
kono
parents:
diff changeset
442 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
443 * Allocate buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
444 * Caller wants us to have a total of at least want_nbufs buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
445 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
446 public int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
447 ch_nbuf(want_nbufs)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
448 int want_nbufs;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
449 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
450 PARG parg;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
451
bce86c4163a3 Initial revision
kono
parents:
diff changeset
452 if (ch_nbufs < want_nbufs && ch_addbuf(want_nbufs - ch_nbufs))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
453 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
454 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
455 * Cannot allocate enough buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
456 * If we don't have ANY, then quit.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
457 * Otherwise, just report the error and return.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
458 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
459 parg.p_int = want_nbufs - ch_nbufs;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
460 error("Cannot allocate %d buffers", &parg);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
461 if (ch_nbufs == 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
462 quit(1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
463 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
464 return (ch_nbufs);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
465 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
466
bce86c4163a3 Initial revision
kono
parents:
diff changeset
467 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
468 * Flush any saved file state, including buffer contents.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
469 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
470 public void
bce86c4163a3 Initial revision
kono
parents:
diff changeset
471 ch_flush()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
472 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
473 register struct buf *bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
474
bce86c4163a3 Initial revision
kono
parents:
diff changeset
475 if (ispipe)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
476 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
477 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
478 * If input is a pipe, we don't flush buffer contents,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
479 * since the contents can't be recovered.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
480 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
481 ch_fsize = NULL_POSITION;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
482 return;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
483 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
484
bce86c4163a3 Initial revision
kono
parents:
diff changeset
485 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
486 * Initialize all the buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
487 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
488 for (bp = buf_head; bp != END_OF_CHAIN; bp = bp->next)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
489 bp->block = (long)(-1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
490
bce86c4163a3 Initial revision
kono
parents:
diff changeset
491 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
492 * Figure out the size of the file, if we can.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
493 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
494 ch_fsize = filesize(file);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
495
bce86c4163a3 Initial revision
kono
parents:
diff changeset
496 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
497 * Seek to a known position: the beginning of the file.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
498 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
499 ch_fpos = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
500 ch_block = ch_fpos / BUFSIZ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
501 ch_offset = ch_fpos % BUFSIZ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
502
bce86c4163a3 Initial revision
kono
parents:
diff changeset
503 if (lseek(file, (offset_t)0, 0) == BAD_LSEEK)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
504 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
505 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
506 * Warning only; even if the seek fails for some reason,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
507 * there's a good chance we're at the beginning anyway.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
508 * {{ I think this is bogus reasoning. }}
bce86c4163a3 Initial revision
kono
parents:
diff changeset
509 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
510 error("seek error to 0", NULL_PARG);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
511 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
512 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
513
bce86c4163a3 Initial revision
kono
parents:
diff changeset
514 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
515 * Allocate some new buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
516 * The buffers are added to the tail of the buffer chain.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
517 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
518 static int
bce86c4163a3 Initial revision
kono
parents:
diff changeset
519 ch_addbuf(nnew)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
520 int nnew;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
521 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
522 register struct buf *bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
523 register struct buf *newbufs;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
524
bce86c4163a3 Initial revision
kono
parents:
diff changeset
525 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
526 * We don't have enough buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
527 * Allocate some new ones.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
528 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
529 newbufs = (struct buf *) calloc(nnew, sizeof(struct buf));
bce86c4163a3 Initial revision
kono
parents:
diff changeset
530 if (newbufs == NULL)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
531 return (1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
532
bce86c4163a3 Initial revision
kono
parents:
diff changeset
533 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
534 * Initialize the new buffers and link them together.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
535 * Link them all onto the tail of the buffer list.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
536 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
537 ch_nbufs += nnew;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
538 for (bp = &newbufs[0]; bp < &newbufs[nnew]; bp++)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
539 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
540 bp->next = bp + 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
541 bp->prev = bp - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
542 bp->block = (long)(-1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
543 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
544 newbufs[nnew-1].next = END_OF_CHAIN;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
545 newbufs[0].prev = buf_tail;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
546 buf_tail->next = &newbufs[0];
bce86c4163a3 Initial revision
kono
parents:
diff changeset
547 buf_tail = &newbufs[nnew-1];
bce86c4163a3 Initial revision
kono
parents:
diff changeset
548 return (0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
549 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
550
bce86c4163a3 Initial revision
kono
parents:
diff changeset
551 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
552 * Use the pipe file state.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
553 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
554 public void
bce86c4163a3 Initial revision
kono
parents:
diff changeset
555 ch_pipe()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
556 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
557 thisfile = &pipefile;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
558 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
559
bce86c4163a3 Initial revision
kono
parents:
diff changeset
560 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
561 * Use the non-pipe file state.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
562 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
563 public void
bce86c4163a3 Initial revision
kono
parents:
diff changeset
564 ch_nonpipe()
bce86c4163a3 Initial revision
kono
parents:
diff changeset
565 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
566 thisfile = &nonpipefile;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
567 }