kernel/libc: Remove sigstack() remains.
[dragonfly.git] / sys / kern / tty_subr.c
blob1b73ba6e3df3beea1ee4beef8d9f432793c59699
1 /*
2 * Copyright (c) 1994, David Greenman
3 * All rights reserved.
4 * Copyright (c) 2003-2011 The DragonFly Project. All rights reserved.
6 * This code is derived from software contributed to The DragonFly Project
7 * by Matthew Dillon <dillon@backplane.com>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice unmodified, this list of conditions, and the following
14 * disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
33 * clist support routines
35 * The clist now contains two linear buffers c_quote and c_info, sized
36 * to c_cbmax. The caller must hold a lock or token specific to the clist
37 * being manipulated.
39 #include <sys/param.h>
40 #include <sys/kernel.h>
41 #include <sys/systm.h>
42 #include <sys/malloc.h>
43 #include <sys/tty.h>
44 #include <sys/thread2.h>
47 * Allocate or reallocate clist buffers.
49 void
50 clist_alloc_cblocks(struct clist *cl, int ccmax)
52 short *data;
53 int count;
54 int n;
56 if (ccmax == cl->c_ccmax)
57 return;
58 if (ccmax == 0) {
59 clist_free_cblocks(cl);
60 return;
62 data = kmalloc(ccmax * sizeof(*data), M_TTYS, M_INTWAIT|M_ZERO);
63 /* NOTE: cl fields may now be different due to blocking */
65 count = cl->c_cc;
66 if (cl->c_cc) {
67 if (count > ccmax)
68 count = ccmax;
69 n = cl->c_ccmax - cl->c_cchead;
70 if (n > count)
71 n = count;
72 bcopy(cl->c_data + cl->c_cchead, data, n * sizeof(*data));
73 if (n < count) {
74 bcopy(cl->c_data, data + n,
75 (count - n) * sizeof(*data));
78 cl->c_cc = count;
79 cl->c_ccmax = ccmax;
80 cl->c_cchead = 0;
81 cl->c_data = data;
85 * Free the clist's buffer.
87 void
88 clist_free_cblocks(struct clist *cl)
90 short *data;
92 data = cl->c_data;
94 cl->c_cc = 0;
95 cl->c_ccmax = 0;
96 cl->c_cchead = 0;
97 cl->c_unused01 = 0;
98 cl->c_data = NULL;
99 if (data)
100 kfree(data, M_TTYS);
104 * Get a character from the head of a clist.
107 clist_getc(struct clist *cl)
109 short c;
110 int i;
112 if (cl->c_cc == 0)
113 return -1;
114 i = cl->c_cchead;
115 c = cl->c_data[i];
116 if (++i == cl->c_ccmax)
117 i = 0;
118 cl->c_cchead = i;
119 --cl->c_cc;
120 return ((int)c);
124 * Copy data from the clist to the destination linear buffer.
125 * Return the number of characters actually copied.
128 clist_qtob(struct clist *cl, char *dest, int n)
130 int count;
131 int i;
132 short c;
134 if (n > cl->c_cc)
135 n = cl->c_cc;
136 count = n;
137 i = cl->c_cchead;
139 while (n) {
140 c = cl->c_data[i];
141 if (++i == cl->c_ccmax)
142 i = 0;
143 *dest++ = (char)c;
144 --n;
146 cl->c_cchead = i;
147 cl->c_cc -= count;
149 return count;
153 * Flush characters from the head of the clist, deleting them.
155 void
156 ndflush(struct clist *cl, int n)
158 int i;
160 if (n > cl->c_cc)
161 n = cl->c_cc;
162 i = cl->c_cchead + n;
163 if (i >= cl->c_ccmax)
164 i -= cl->c_ccmax;
165 cl->c_cchead = i;
166 cl->c_cc -= n;
170 * Append a character to the clist, return 0 on success, -1 if
171 * there is no room. The character can be quoted by setting TTY_QUOTE.
174 clist_putc(int c, struct clist *cl)
176 int i;
178 if (cl->c_cc == cl->c_ccmax)
179 return -1;
180 i = cl->c_cchead + cl->c_cc;
181 if (i >= cl->c_ccmax)
182 i -= cl->c_ccmax;
183 cl->c_data[i] = (short)c & (TTY_QUOTE | TTY_CHARMASK);
184 ++cl->c_cc;
186 return 0;
190 * Copy data from linear buffer to clist chain. Return the
191 * number of characters not copied. The data will be flagged
192 * as not being quoted.
195 clist_btoq(char *src, int n, struct clist *cl)
197 int i;
198 int count;
199 int remain;
201 count = cl->c_ccmax - cl->c_cc; /* space available */
202 if (count > n)
203 count = n; /* count = bytes to copy */
204 remain = n - count; /* remain = bytes not copied */
206 i = cl->c_cchead + cl->c_cc; /* clist write index */
207 if (i >= cl->c_ccmax)
208 i -= cl->c_ccmax;
210 while (count) {
211 cl->c_data[i] = (short)(uint8_t)*src;
212 if (++i == cl->c_ccmax)
213 i = 0;
214 ++src;
215 --count;
217 cl->c_cc += n - remain; /* bytes actually copied */
219 return remain; /* return bytes not copied */
223 * Get the next character in the clist relative to cp. If cp is NULL
224 * returns the first character in the clist. The character is stored in
225 * *dst. No clist pointers are advanced or adjusted.
227 * The returned pointer can be used as an iterator but should not be
228 * directly dereferenced.
230 void *
231 clist_nextc(struct clist *cl, void *cp, int *dst)
233 int i;
235 if (cp == NULL) {
236 if (cl->c_cc == 0) {
237 *dst = -1;
238 return NULL;
240 cp = &cl->c_data[cl->c_cchead];
241 *dst = (uint16_t)*(short *)cp; /* can be quoted */
242 return cp;
246 * Use i to calculate the next logical index to determine if
247 * there are any characters remaining.
249 i = (short *)cp - cl->c_data;
250 if (i < cl->c_cchead)
251 i += cl->c_ccmax - cl->c_cchead;
252 else
253 i -= cl->c_cchead;
254 if (i + 1 == cl->c_cc) { /* no more chars */
255 *dst = 0;
256 return NULL;
260 * We can just use cp to iterate the next actual buffer
261 * position.
263 cp = (short *)cp + 1; /* next char (use pointer) */
264 if (cp == &cl->c_data[cl->c_ccmax])
265 cp = &cl->c_data[0];
266 *dst = (uint16_t)*(short *)cp;
268 return cp;
272 * "Unput" a character from a clist, returning it.
275 clist_unputc(struct clist *cl)
277 int c;
278 int i;
280 if (cl->c_cc == 0)
281 return -1;
282 --cl->c_cc;
283 i = cl->c_cchead + cl->c_cc;
284 if (i >= cl->c_ccmax)
285 i -= cl->c_ccmax;
286 c = (int)(uint16_t)cl->c_data[i];
288 return c;
292 * Move characters in source clist to destination clist,
293 * preserving quote bits. Non-critical path.
295 void
296 clist_catq(struct clist *cls, struct clist *cld)
298 int c;
300 while ((c = clist_getc(cls)) != -1)
301 clist_putc(c, cld);