conversion of ino_t from u_short to u_long (making dir entries 32 bytes each)
[unix-history] / usr / src / sys / kern / tty_subr.c
CommitLineData
231ed58b 1/* tty_subr.c 4.12 81/10/11 */
8f6119af 2
11bd398c 3#include "../h/param.h"
11bd398c
BJ
4#include "../h/systm.h"
5#include "../h/conf.h"
6#include "../h/buf.h"
48575cec 7#include "../h/tty.h"
d4df41fe 8#include "../h/clist.h"
11bd398c 9
48575cec 10char cwaiting;
11bd398c
BJ
11
12/*
13 * Character list get/put
14 */
15getc(p)
16register struct clist *p;
17{
18 register struct cblock *bp;
19 register int c, s;
20
7eb2e67e 21 s = spl5();
11bd398c
BJ
22 if (p->c_cc <= 0) {
23 c = -1;
24 p->c_cc = 0;
25 p->c_cf = p->c_cl = NULL;
26 } else {
27 c = *p->c_cf++ & 0377;
28 if (--p->c_cc<=0) {
29 bp = (struct cblock *)(p->c_cf-1);
30 bp = (struct cblock *) ((int)bp & ~CROUND);
31 p->c_cf = NULL;
32 p->c_cl = NULL;
33 bp->c_next = cfreelist;
34 cfreelist = bp;
48575cec
BJ
35 cfreecount += CBSIZE;
36 if (cwaiting) {
37 wakeup(&cwaiting);
38 cwaiting = 0;
39 }
11bd398c
BJ
40 } else if (((int)p->c_cf & CROUND) == 0){
41 bp = (struct cblock *)(p->c_cf);
42 bp--;
43 p->c_cf = bp->c_next->c_info;
44 bp->c_next = cfreelist;
45 cfreelist = bp;
48575cec
BJ
46 cfreecount += CBSIZE;
47 if (cwaiting) {
48 wakeup(&cwaiting);
49 cwaiting = 0;
50 }
11bd398c
BJ
51 }
52 }
53 splx(s);
54 return(c);
55}
56
57/*
58 * copy clist to buffer.
59 * return number of bytes moved.
60 */
61q_to_b(q, cp, cc)
62register struct clist *q;
63register char *cp;
64{
65 register struct cblock *bp;
66 register int s;
67 char *acp;
68
69 if (cc <= 0)
70 return(0);
7eb2e67e 71 s = spl5();
11bd398c
BJ
72 if (q->c_cc <= 0) {
73 q->c_cc = 0;
74 q->c_cf = q->c_cl = NULL;
48575cec 75 splx(s);
11bd398c
BJ
76 return(0);
77 }
78 acp = cp;
79 cc++;
80
81 while (--cc) {
82 *cp++ = *q->c_cf++;
83 if (--q->c_cc <= 0) {
84 bp = (struct cblock *)(q->c_cf-1);
85 bp = (struct cblock *)((int)bp & ~CROUND);
86 q->c_cf = q->c_cl = NULL;
87 bp->c_next = cfreelist;
88 cfreelist = bp;
48575cec
BJ
89 cfreecount += CBSIZE;
90 if (cwaiting) {
91 wakeup(&cwaiting);
92 cwaiting = 0;
93 }
11bd398c
BJ
94 break;
95 }
96 if (((int)q->c_cf & CROUND) == 0) {
97 bp = (struct cblock *)(q->c_cf);
98 bp--;
99 q->c_cf = bp->c_next->c_info;
100 bp->c_next = cfreelist;
101 cfreelist = bp;
48575cec
BJ
102 cfreecount += CBSIZE;
103 if (cwaiting) {
104 wakeup(&cwaiting);
105 cwaiting = 0;
106 }
11bd398c
BJ
107 }
108 }
109 splx(s);
110 return(cp-acp);
111}
112
11bd398c
BJ
113/*
114 * Return count of contiguous characters
115 * in clist starting at q->c_cf.
116 * Stop counting if flag&character is non-null.
117 */
118ndqb(q, flag)
119register struct clist *q;
120{
121register cc;
122int s;
123
7eb2e67e 124 s = spl5();
11bd398c
BJ
125 if (q->c_cc <= 0) {
126 cc = -q->c_cc;
127 goto out;
128 }
129 cc = ((int)q->c_cf + CBSIZE) & ~CROUND;
130 cc -= (int)q->c_cf;
131 if (q->c_cc < cc)
132 cc = q->c_cc;
133 if (flag) {
134 register char *p, *end;
135
136 p = q->c_cf;
137 end = p;
138 end += cc;
139 while (p < end) {
140 if (*p & flag) {
48575cec
BJ
141 cc = (int)p;
142 cc -= (int)q->c_cf;
11bd398c
BJ
143 break;
144 }
145 p++;
146 }
147 }
148out:
149 splx(s);
150 return(cc);
151}
152
48575cec
BJ
153
154
11bd398c 155/*
48575cec 156 * Flush cc bytes from q.
11bd398c
BJ
157 */
158ndflush(q, cc)
159register struct clist *q;
160register cc;
161{
48575cec
BJ
162register struct cblock *bp;
163char *end;
164int rem;
11bd398c
BJ
165register s;
166
7eb2e67e 167 s = spl5();
11bd398c 168 if (q->c_cc < 0) {
48575cec 169 printf("neg q flush\n");
11bd398c
BJ
170 goto out;
171 }
172 if (q->c_cc == 0) {
173 goto out;
174 }
48575cec
BJ
175 while (cc>0 && q->c_cc) {
176 bp = (struct cblock *)((int)q->c_cf & ~CROUND);
177 if ((int)bp == (((int)q->c_cl-1) & ~CROUND)) {
178 end = q->c_cl;
179 } else {
180 end = (char *)((int)bp + sizeof (struct cblock));
181 }
182 rem = end - q->c_cf;
183 if (cc >= rem) {
184 cc -= rem;
185 q->c_cc -= rem;
11bd398c 186 q->c_cf = bp->c_next->c_info;
48575cec
BJ
187 bp->c_next = cfreelist;
188 cfreelist = bp;
189 cfreecount += CBSIZE;
190 if (cwaiting) {
191 wakeup(&cwaiting);
192 cwaiting = 0;
193 }
11bd398c 194 } else {
48575cec
BJ
195 q->c_cc -= cc;
196 q->c_cf += cc;
197 if (q->c_cc <= 0) {
198 bp->c_next = cfreelist;
199 cfreelist = bp;
200 cfreecount += CBSIZE;
201 if (cwaiting) {
202 wakeup(&cwaiting);
203 cwaiting = 0;
204 }
205 }
206 break;
11bd398c 207 }
48575cec
BJ
208 }
209 if (q->c_cc <= 0) {
11bd398c 210 q->c_cf = q->c_cl = NULL;
48575cec 211 q->c_cc = 0;
11bd398c
BJ
212 }
213out:
214 splx(s);
215}
b8f09f36 216
48575cec 217
11bd398c
BJ
218putc(c, p)
219register struct clist *p;
220{
221 register struct cblock *bp;
222 register char *cp;
223 register s;
224
7eb2e67e 225 s = spl5();
11bd398c
BJ
226 if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
227 if ((bp = cfreelist) == NULL) {
228 splx(s);
229 return(-1);
230 }
231 cfreelist = bp->c_next;
48575cec 232 cfreecount -= CBSIZE;
11bd398c
BJ
233 bp->c_next = NULL;
234 p->c_cf = cp = bp->c_info;
235 } else if (((int)cp & CROUND) == 0) {
236 bp = (struct cblock *)cp - 1;
237 if ((bp->c_next = cfreelist) == NULL) {
238 splx(s);
239 return(-1);
240 }
241 bp = bp->c_next;
242 cfreelist = bp->c_next;
48575cec 243 cfreecount -= CBSIZE;
11bd398c
BJ
244 bp->c_next = NULL;
245 cp = bp->c_info;
246 }
247 *cp++ = c;
248 p->c_cc++;
249 p->c_cl = cp;
250 splx(s);
251 return(0);
252}
253
48575cec
BJ
254
255
11bd398c
BJ
256/*
257 * copy buffer to clist.
258 * return number of bytes not transfered.
259 */
260b_to_q(cp, cc, q)
261register char *cp;
262struct clist *q;
263register int cc;
264{
265 register char *cq;
266 register struct cblock *bp;
267 register s, acc;
268
269 if (cc <= 0)
270 return(0);
271 acc = cc;
48575cec
BJ
272
273
7eb2e67e 274 s = spl5();
11bd398c
BJ
275 if ((cq = q->c_cl) == NULL || q->c_cc < 0) {
276 if ((bp = cfreelist) == NULL)
277 goto out;
278 cfreelist = bp->c_next;
48575cec 279 cfreecount -= CBSIZE;
11bd398c
BJ
280 bp->c_next = NULL;
281 q->c_cf = cq = bp->c_info;
282 }
283
284 while (cc) {
285 if (((int)cq & CROUND) == 0) {
286 bp = (struct cblock *) cq - 1;
287 if ((bp->c_next = cfreelist) == NULL)
288 goto out;
289 bp = bp->c_next;
290 cfreelist = bp->c_next;
48575cec 291 cfreecount -= CBSIZE;
11bd398c
BJ
292 bp->c_next = NULL;
293 cq = bp->c_info;
294 }
295 *cq++ = *cp++;
296 cc--;
297 }
298out:
299 q->c_cl = cq;
300 q->c_cc += acc-cc;
301 splx(s);
302 return(cc);
303}
304
b8f09f36
BJ
305/*
306 * Given a non-NULL pointter into the list (like c_cf which
307 * always points to a real character if non-NULL) return the pointer
308 * to the next character in the list or return NULL if no more chars.
309 *
310 * Callers must not allow getc's to happen between nextc's so that the
311 * pointer becomes invalid. Note that interrupts are NOT masked.
312 */
313char *
314nextc(p, cp)
315register struct clist *p;
316register char *cp;
317{
318
319 if (p->c_cc && ++cp != p->c_cl) {
320 if (((int)cp & CROUND) == 0)
321 return (((struct cblock *)cp)[-1].c_next->c_info);
322 return (cp);
323 }
324 return (0);
325}
326
327/*
328 * Remove the last character in the list and return it.
329 */
330unputc(p)
331register struct clist *p;
332{
333 register struct cblock *bp;
334 register int c, s;
335 struct cblock *obp;
336
7eb2e67e 337 s = spl5();
b8f09f36
BJ
338 if (p->c_cc <= 0)
339 c = -1;
340 else {
341 c = *--p->c_cl;
342 if (--p->c_cc <= 0) {
343 bp = (struct cblock *)p->c_cl;
344 bp = (struct cblock *)((int)bp & ~CROUND);
345 p->c_cl = p->c_cf = NULL;
346 bp->c_next = cfreelist;
347 cfreelist = bp;
48575cec 348 cfreecount += CBSIZE;
b8f09f36
BJ
349 } else if (((int)p->c_cl & CROUND) == sizeof(bp->c_next)) {
350 p->c_cl = (char *)((int)p->c_cl & ~CROUND);
351 bp = (struct cblock *)p->c_cf;
352 bp = (struct cblock *)((int)bp & ~CROUND);
353 while (bp->c_next != (struct cblock *)p->c_cl)
354 bp = bp->c_next;
355 obp = bp;
356 p->c_cl = (char *)(bp + 1);
357 bp = bp->c_next;
358 bp->c_next = cfreelist;
359 cfreelist = bp;
48575cec 360 cfreecount += CBSIZE;
b8f09f36
BJ
361 obp->c_next = NULL;
362 }
363 }
364 splx(s);
365 return (c);
366}
367
368/*
369 * Put the chars in the from que
370 * on the end of the to que.
371 *
372 * SHOULD JUST USE q_to_b AND THEN b_to_q HERE.
373 */
374catq(from, to)
375struct clist *from, *to;
376{
377 register c;
378
379 while ((c = getc(from)) >= 0)
380 (void) putc(c, to);
381}
382
11bd398c
BJ
383/*
384 * integer (2-byte) get/put
385 * using clists
386 */
a0eab615 387#ifdef unneeded
11bd398c
BJ
388getw(p)
389register struct clist *p;
390{
391 register int s;
392
393 if (p->c_cc <= 1)
394 return(-1);
395 s = getc(p);
396 return(s | (getc(p)<<8));
397}
a0eab615 398#endif
48575cec 399
11bd398c
BJ
400putw(c, p)
401register struct clist *p;
402{
403 register s;
404
7eb2e67e 405 s = spl5();
11bd398c
BJ
406 if (cfreelist==NULL) {
407 splx(s);
408 return(-1);
409 }
81263dba
BJ
410 (void) putc(c, p);
411 (void) putc(c>>8, p);
11bd398c
BJ
412 splx(s);
413 return(0);
414}