4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
25 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
42 * Standard Streams Terminal Line Discipline module.
45 #include <sys/param.h>
46 #include <sys/types.h>
47 #include <sys/termio.h>
48 #include <sys/stream.h>
50 #include <sys/stropts.h>
51 #include <sys/strsubr.h>
52 #include <sys/strsun.h>
53 #include <sys/strtty.h>
54 #include <sys/signal.h>
56 #include <sys/errno.h>
57 #include <sys/debug.h>
58 #include <sys/cmn_err.h>
60 #include <sys/eucioctl.h>
61 #include <sys/csiioctl.h>
63 #include <sys/ldterm.h>
66 #include <sys/sunddi.h>
68 #include <sys/modctl.h>
70 /* Time limit when draining during a close(9E) invoked by exit(2) */
71 /* Can be set to zero to emulate the old, broken behavior */
72 int ldterm_drain_limit
= 15000000;
86 * The following for EUC handling:
92 * Table indicating character classes to tty driver. In particular,
93 * if the class is ORDINARY, then the character needs no special
94 * processing on output.
96 * Characters in the C1 set are all considered CONTROL; this will
97 * work with terminals that properly use the ANSI/ISO extensions,
98 * but might cause distress with terminals that put graphics in
99 * the range 0200-0237. On the other hand, characters in that
100 * range cause even greater distress to other UNIX terminal drivers....
103 static char typetab
[256] = {
104 /* 000 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
105 /* 004 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
106 /* 010 */ BACKSPACE
, TAB
, NEWLINE
, CONTROL
,
107 /* 014 */ VTAB
, RETURN
, CONTROL
, CONTROL
,
108 /* 020 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
109 /* 024 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
110 /* 030 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
111 /* 034 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
112 /* 040 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
113 /* 044 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
114 /* 050 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
115 /* 054 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
116 /* 060 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
117 /* 064 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
118 /* 070 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
119 /* 074 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
120 /* 100 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
121 /* 104 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
122 /* 110 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
123 /* 114 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
124 /* 120 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
125 /* 124 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
126 /* 130 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
127 /* 134 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
128 /* 140 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
129 /* 144 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
130 /* 150 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
131 /* 154 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
132 /* 160 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
133 /* 164 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
134 /* 170 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
135 /* 174 */ ORDINARY
, ORDINARY
, ORDINARY
, CONTROL
,
136 /* 200 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
137 /* 204 */ CONTROL
, CONTROL
, T_SS2
, T_SS3
,
138 /* 210 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
139 /* 214 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
140 /* 220 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
141 /* 224 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
142 /* 230 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
143 /* 234 */ CONTROL
, CONTROL
, CONTROL
, CONTROL
,
144 /* 240 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
145 /* 244 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
146 /* 250 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
147 /* 254 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
148 /* 260 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
149 /* 264 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
150 /* 270 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
151 /* 274 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
152 /* 300 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
153 /* 304 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
154 /* 310 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
155 /* 314 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
156 /* 320 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
157 /* 324 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
158 /* 330 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
159 /* 334 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
160 /* 340 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
161 /* 344 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
162 /* 350 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
163 /* 354 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
164 /* 360 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
165 /* 364 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
166 /* 370 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
168 * WARNING: For EUC, 0xFF must be an ordinary character. It is used with
169 * single-byte EUC in some of the "ISO Latin Alphabet" codesets, and occupies
170 * a screen position; in those ISO sets where that position isn't used, it
171 * shouldn't make any difference.
173 /* 374 */ ORDINARY
, ORDINARY
, ORDINARY
, ORDINARY
,
177 * Translation table for output without OLCUC. All ORDINARY-class characters
178 * translate to themselves. All other characters have a zero in the table,
179 * which stops the copying.
181 static unsigned char notrantab
[256] = {
182 /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
183 /* 010 */ 0, 0, 0, 0, 0, 0, 0, 0,
184 /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
185 /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
186 /* 040 */ ' ', '!', '"', '#', '$', '%', '&', '\'',
187 /* 050 */ '(', ')', '*', '+', ',', '-', '.', '/',
188 /* 060 */ '0', '1', '2', '3', '4', '5', '6', '7',
189 /* 070 */ '8', '9', ':', ';', '<', '=', '>', '?',
190 /* 100 */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
191 /* 110 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
192 /* 120 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
193 /* 130 */ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
194 /* 140 */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
195 /* 150 */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
196 /* 160 */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
197 /* 170 */ 'x', 'y', 'z', '{', '|', '}', '~', 0,
198 /* 200 */ 0, 0, 0, 0, 0, 0, 0, 0,
199 /* 210 */ 0, 0, 0, 0, 0, 0, 0, 0,
200 /* 220 */ 0, 0, 0, 0, 0, 0, 0, 0,
201 /* 230 */ 0, 0, 0, 0, 0, 0, 0, 0,
202 /* 240 */ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
203 /* 250 */ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
204 /* 260 */ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
205 /* 270 */ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
206 /* 300 */ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
207 /* 310 */ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
208 /* 320 */ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
209 /* 330 */ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
210 /* 340 */ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
211 /* 350 */ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
212 /* 360 */ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
214 * WARNING: as for above ISO sets, \377 may be used. Translate it to
217 /* 370 */ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
221 * Translation table for output with OLCUC. All ORDINARY-class characters
222 * translate to themselves, except for lower-case letters which translate
223 * to their upper-case equivalents. All other characters have a zero in
224 * the table, which stops the copying.
226 static unsigned char lcuctab
[256] = {
227 /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
228 /* 010 */ 0, 0, 0, 0, 0, 0, 0, 0,
229 /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
230 /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
231 /* 040 */ ' ', '!', '"', '#', '$', '%', '&', '\'',
232 /* 050 */ '(', ')', '*', '+', ',', '-', '.', '/',
233 /* 060 */ '0', '1', '2', '3', '4', '5', '6', '7',
234 /* 070 */ '8', '9', ':', ';', '<', '=', '>', '?',
235 /* 100 */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
236 /* 110 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
237 /* 120 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
238 /* 130 */ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
239 /* 140 */ '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
240 /* 150 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
241 /* 160 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
242 /* 170 */ 'X', 'Y', 'Z', '{', '|', '}', '~', 0,
243 /* 200 */ 0, 0, 0, 0, 0, 0, 0, 0,
244 /* 210 */ 0, 0, 0, 0, 0, 0, 0, 0,
245 /* 220 */ 0, 0, 0, 0, 0, 0, 0, 0,
246 /* 230 */ 0, 0, 0, 0, 0, 0, 0, 0,
247 /* 240 */ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
248 /* 250 */ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
249 /* 260 */ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
250 /* 270 */ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
251 /* 300 */ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
252 /* 310 */ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
253 /* 320 */ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
254 /* 330 */ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
255 /* 340 */ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
256 /* 350 */ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
257 /* 360 */ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
259 * WARNING: as for above ISO sets, \377 may be used. Translate it to
262 /* 370 */ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
266 * Input mapping table -- if an entry is non-zero, and XCASE is set,
267 * when the corresponding character is typed preceded by "\" the escape
268 * sequence is replaced by the table value. Mostly used for
269 * upper-case only terminals.
271 static char imaptab
[256] = {
272 /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
273 /* 010 */ 0, 0, 0, 0, 0, 0, 0, 0,
274 /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
275 /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
276 /* 040 */ 0, '|', 0, 0, 0, 0, 0, '`',
277 /* 050 */ '{', '}', 0, 0, 0, 0, 0, 0,
278 /* 060 */ 0, 0, 0, 0, 0, 0, 0, 0,
279 /* 070 */ 0, 0, 0, 0, 0, 0, 0, 0,
280 /* 100 */ 0, 0, 0, 0, 0, 0, 0, 0,
281 /* 110 */ 0, 0, 0, 0, 0, 0, 0, 0,
282 /* 120 */ 0, 0, 0, 0, 0, 0, 0, 0,
283 /* 130 */ 0, 0, 0, 0, '\\', 0, '~', 0,
284 /* 140 */ 0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
285 /* 150 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
286 /* 160 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
287 /* 170 */ 'X', 'Y', 'Z', 0, 0, 0, 0, 0,
288 /* 200-377 aren't mapped */
292 * Output mapping table -- if an entry is non-zero, and XCASE is set,
293 * the corresponding character is printed as "\" followed by the table
294 * value. Mostly used for upper-case only terminals.
296 static char omaptab
[256] = {
297 /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
298 /* 010 */ 0, 0, 0, 0, 0, 0, 0, 0,
299 /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
300 /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
301 /* 040 */ 0, 0, 0, 0, 0, 0, 0, 0,
302 /* 050 */ 0, 0, 0, 0, 0, 0, 0, 0,
303 /* 060 */ 0, 0, 0, 0, 0, 0, 0, 0,
304 /* 070 */ 0, 0, 0, 0, 0, 0, 0, 0,
305 /* 100 */ 0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
306 /* 110 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
307 /* 120 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
308 /* 130 */ 'X', 'Y', 'Z', 0, 0, 0, 0, 0,
309 /* 140 */ '\'', 0, 0, 0, 0, 0, 0, 0,
310 /* 150 */ 0, 0, 0, 0, 0, 0, 0, 0,
311 /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0,
312 /* 170 */ 0, 0, 0, '(', '!', ')', '^', 0,
313 /* 200-377 aren't mapped */
317 * Translation table for TS_MEUC output without OLCUC. All printing ASCII
318 * characters translate to themselves. All other _bytes_ have a zero in
319 * the table, which stops the copying. This and the following table exist
320 * only so we can use the existing movtuc processing with or without OLCUC.
321 * Maybe it speeds up something...because we can copy a block of characters
322 * by only looking for zeros in the table.
324 * If we took the simple expedient of DISALLOWING "olcuc" with multi-byte
325 * processing, we could rid ourselves of both these tables and save 512 bytes;
326 * seriously, it doesn't make much sense to use olcuc with multi-byte, and
327 * it will probably never be used. Consideration should be given to disallowing
328 * the combination TS_MEUC & OLCUC.
330 static unsigned char enotrantab
[256] = {
331 /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
332 /* 010 */ 0, 0, 0, 0, 0, 0, 0, 0,
333 /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
334 /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
335 /* 040 */ ' ', '!', '"', '#', '$', '%', '&', '\'',
336 /* 050 */ '(', ')', '*', '+', ',', '-', '.', '/',
337 /* 060 */ '0', '1', '2', '3', '4', '5', '6', '7',
338 /* 070 */ '8', '9', ':', ';', '<', '=', '>', '?',
339 /* 100 */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
340 /* 110 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
341 /* 120 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
342 /* 130 */ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
343 /* 140 */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
344 /* 150 */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
345 /* 160 */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
346 /* 170 */ 'x', 'y', 'z', '{', '|', '}', '~', 0,
347 /* 200 - 377 aren't mapped (they're stoppers). */
351 * Translation table for TS_MEUC output with OLCUC. All printing ASCII
352 * translate to themselves, except for lower-case letters which translate
353 * to their upper-case equivalents. All other bytes have a zero in
354 * the table, which stops the copying. Useless for ISO Latin Alphabet
355 * translations, but *sigh* OLCUC is really only defined for ASCII anyway.
356 * We only have this table so we can use the existing OLCUC processing with
357 * TS_MEUC set (multi-byte mode). Nobody would ever think of actually
358 * _using_ it...would they?
360 static unsigned char elcuctab
[256] = {
361 /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
362 /* 010 */ 0, 0, 0, 0, 0, 0, 0, 0,
363 /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
364 /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
365 /* 040 */ ' ', '!', '"', '#', '$', '%', '&', '\'',
366 /* 050 */ '(', ')', '*', '+', ',', '-', '.', '/',
367 /* 060 */ '0', '1', '2', '3', '4', '5', '6', '7',
368 /* 070 */ '8', '9', ':', ';', '<', '=', '>', '?',
369 /* 100 */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
370 /* 110 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
371 /* 120 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
372 /* 130 */ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
373 /* 140 */ '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
374 /* 150 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
375 /* 160 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
376 /* 170 */ 'X', 'Y', 'Z', '{', '|', '}', '~', 0,
377 /* 200 - 377 aren't mapped (they're stoppers). */
380 static struct streamtab ldtrinfo
;
382 static struct fmodsw fsw
= {
385 D_MTQPAIR
| D_MP
| _D_SINGLE_INSTANCE
388 static struct modlstrmod modlstrmod
= {
389 &mod_strmodops
, "terminal line discipline", &fsw
393 static struct modlinkage modlinkage
= {
394 MODREV_1
, &modlstrmod
, NULL
401 return (mod_install(&modlinkage
));
407 return (mod_remove(&modlinkage
));
411 _info(struct modinfo
*modinfop
)
413 return (mod_info(&modlinkage
, modinfop
));
417 static int ldtermopen(queue_t
*, dev_t
*, int, int, cred_t
*);
418 static int ldtermclose(queue_t
*, int, cred_t
*);
419 static void ldtermrput(queue_t
*, mblk_t
*);
420 static void ldtermrsrv(queue_t
*);
421 static int ldtermrmsg(queue_t
*, mblk_t
*);
422 static void ldtermwput(queue_t
*, mblk_t
*);
423 static void ldtermwsrv(queue_t
*);
424 static int ldtermwmsg(queue_t
*, mblk_t
*);
425 static mblk_t
*ldterm_docanon(unsigned char, mblk_t
*, size_t, queue_t
*,
426 ldtermstd_state_t
*, int *);
427 static int ldterm_unget(ldtermstd_state_t
*);
428 static void ldterm_trim(ldtermstd_state_t
*);
429 static void ldterm_rubout(unsigned char, queue_t
*, size_t,
430 ldtermstd_state_t
*);
431 static int ldterm_tabcols(ldtermstd_state_t
*);
432 static void ldterm_erase(queue_t
*, size_t, ldtermstd_state_t
*);
433 static void ldterm_werase(queue_t
*, size_t, ldtermstd_state_t
*);
434 static void ldterm_kill(queue_t
*, size_t, ldtermstd_state_t
*);
435 static void ldterm_reprint(queue_t
*, size_t, ldtermstd_state_t
*);
436 static mblk_t
*ldterm_dononcanon(mblk_t
*, mblk_t
*, size_t, queue_t
*,
437 ldtermstd_state_t
*);
438 static int ldterm_echo(unsigned char, queue_t
*, size_t,
439 ldtermstd_state_t
*);
440 static void ldterm_outchar(unsigned char, queue_t
*, size_t,
441 ldtermstd_state_t
*);
442 static void ldterm_outstring(unsigned char *, int, queue_t
*, size_t,
443 ldtermstd_state_t
*tp
);
444 static mblk_t
*newmsg(ldtermstd_state_t
*);
445 static void ldterm_msg_upstream(queue_t
*, ldtermstd_state_t
*);
446 static void ldterm_wenable(void *);
447 static mblk_t
*ldterm_output_msg(queue_t
*, mblk_t
*, mblk_t
**,
448 ldtermstd_state_t
*, size_t, int);
449 static void ldterm_flush_output(unsigned char, queue_t
*,
450 ldtermstd_state_t
*);
451 static void ldterm_dosig(queue_t
*, int, unsigned char, int, int);
452 static void ldterm_do_ioctl(queue_t
*, mblk_t
*);
453 static int chgstropts(struct termios
*, ldtermstd_state_t
*, queue_t
*);
454 static void ldterm_ioctl_reply(queue_t
*, mblk_t
*);
455 static void vmin_satisfied(queue_t
*, ldtermstd_state_t
*, int);
456 static void vmin_settimer(queue_t
*);
457 static void vmin_timed_out(void *);
458 static void ldterm_adjust_modes(ldtermstd_state_t
*);
459 static void ldterm_eucwarn(ldtermstd_state_t
*);
460 static void cp_eucwioc(eucioc_t
*, eucioc_t
*, int);
461 static int ldterm_codeset(uchar_t
, uchar_t
);
463 static void ldterm_csi_erase(queue_t
*, size_t, ldtermstd_state_t
*);
464 static void ldterm_csi_werase(queue_t
*, size_t, ldtermstd_state_t
*);
466 static uchar_t
ldterm_utf8_width(uchar_t
*, int);
468 /* Codeset type specific methods for EUC, PCCS, and, UTF-8 codeset types. */
469 static int __ldterm_dispwidth_euc(uchar_t
, void *, int);
470 static int __ldterm_memwidth_euc(uchar_t
, void *);
472 static int __ldterm_dispwidth_pccs(uchar_t
, void *, int);
473 static int __ldterm_memwidth_pccs(uchar_t
, void *);
475 static int __ldterm_dispwidth_utf8(uchar_t
, void *, int);
476 static int __ldterm_memwidth_utf8(uchar_t
, void *);
478 static const ldterm_cs_methods_t cs_methods
[LDTERM_CS_TYPE_MAX
+ 1] = {
484 __ldterm_dispwidth_euc
,
485 __ldterm_memwidth_euc
488 __ldterm_dispwidth_pccs
,
489 __ldterm_memwidth_pccs
492 __ldterm_dispwidth_utf8
,
493 __ldterm_memwidth_utf8
498 * The default codeset is presumably C locale's ISO 646 in EUC but
499 * the data structure at below defined as the default codeset data also
500 * support any single byte (EUC) locales.
502 static const ldterm_cs_data_t default_cs_data
= {
509 '\0', '\0', '\0', '\0',
510 '\0', '\0', '\0', '\0',
511 '\0', '\0', '\0', '\0',
512 '\0', '\0', '\0', '\0',
513 '\0', '\0', '\0', '\0',
514 '\0', '\0', '\0', '\0',
515 '\0', '\0', '\0', '\0',
516 '\0', '\0', '\0', '\0',
517 '\0', '\0', '\0', '\0',
518 '\0', '\0', '\0', '\0'
523 * The following tables are from either u8_textprep.c or uconv.c at
524 * usr/src/common/unicode/. The tables are used to figure out corresponding
525 * UTF-8 character byte lengths and also the validity of given character bytes.
527 extern const int8_t u8_number_of_bytes
[];
528 extern const uchar_t u8_masks_tbl
[];
529 extern const uint8_t u8_valid_min_2nd_byte
[];
530 extern const uint8_t u8_valid_max_2nd_byte
[];
533 * Unicode character width definition tables from uwidth.c:
535 extern const ldterm_unicode_data_cell_t ldterm_ucode
[][16384];
538 int ldterm_debug
= 0;
539 #define DEBUG1(a) if (ldterm_debug == 1) printf a
540 #define DEBUG2(a) if (ldterm_debug >= 2) printf a /* allocations */
541 #define DEBUG3(a) if (ldterm_debug >= 3) printf a /* M_CTL Stuff */
542 #define DEBUG4(a) if (ldterm_debug >= 4) printf a /* M_READ Stuff */
543 #define DEBUG5(a) if (ldterm_debug >= 5) printf a
544 #define DEBUG6(a) if (ldterm_debug >= 6) printf a
545 #define DEBUG7(a) if (ldterm_debug >= 7) printf a
558 * Since most of the buffering occurs either at the stream head or in
559 * the "message currently being assembled" buffer, we have a
560 * relatively small input queue, so that blockages above us get
561 * reflected fairly quickly to the module below us. We also have a
562 * small maximum packet size, since you can put a message of that
563 * size on an empty queue no matter how much bigger than the high
566 static struct module_info ldtermmiinfo
= {
576 static struct qinit ldtermrinit
= {
577 (int (*)())ldtermrput
,
578 (int (*)())ldtermrsrv
,
586 static struct module_info ldtermmoinfo
= {
596 static struct qinit ldtermwinit
= {
597 (int (*)())ldtermwput
,
598 (int (*)())ldtermwsrv
,
606 static struct streamtab ldtrinfo
= {
614 * Dummy qbufcall callback routine used by open and close.
615 * The framework will wake up qwait_sig when we return from
616 * this routine (as part of leaving the perimeters.)
617 * (The framework enters the perimeters before calling the qbufcall() callback
618 * and leaves the perimeters after the callback routine has executed. The
619 * framework performs an implicit wakeup of any thread in qwait/qwait_sig
620 * when it leaves the perimeter. See qwait(9E).)
624 dummy_callback(void *arg
)
629 open_ioctl(queue_t
*q
, uint_t cmd
)
635 while ((mp
= mkiocb(cmd
)) == NULL
) {
636 id
= qbufcall(q
, sizeof (struct iocblk
), BPRI_MED
,
637 dummy_callback
, NULL
);
647 open_mblk(queue_t
*q
, size_t len
)
653 while ((mp
= allocb(len
, BPRI_MED
)) == NULL
) {
654 id
= qbufcall(q
, len
, BPRI_MED
, dummy_callback
, NULL
);
664 * Line discipline open.
668 ldtermopen(queue_t
*q
, dev_t
*devp
, int oflag
, int sflag
, cred_t
*crp
)
670 ldtermstd_state_t
*tp
;
673 struct stroptions
*strop
;
674 struct termios
*termiosp
;
677 if (q
->q_ptr
!= NULL
) {
678 return (0); /* already attached */
681 tp
= (ldtermstd_state_t
*)kmem_zalloc(sizeof (ldtermstd_state_t
),
685 * Get termios defaults. These are stored as
686 * a property in the "options" node.
688 if (ddi_getlongprop(DDI_DEV_T_ANY
, ddi_root_node(), DDI_PROP_NOTPROM
,
689 "ttymodes", (caddr_t
)&termiosp
, &len
) == DDI_PROP_SUCCESS
&&
690 len
== sizeof (struct termios
)) {
691 tp
->t_modes
= *termiosp
;
692 tp
->t_amodes
= *termiosp
;
693 kmem_free(termiosp
, len
);
696 * Gack! Whine about it.
698 cmn_err(CE_WARN
, "ldterm: Couldn't get ttymodes property!");
700 bzero(&tp
->t_dmodes
, sizeof (struct termios
));
710 tp
->t_message
= NULL
;
713 tp
->t_rd_request
= 0;
720 q
->q_ptr
= (caddr_t
)tp
;
721 WR(q
)->q_ptr
= (caddr_t
)tp
;
723 * The following for EUC and also non-EUC codesets:
725 tp
->t_codeset
= tp
->t_eucleft
= tp
->t_eucign
= tp
->t_scratch_len
= 0;
726 bzero(&tp
->eucwioc
, EUCSIZE
);
727 tp
->eucwioc
.eucw
[0] = 1; /* ASCII mem & screen width */
728 tp
->eucwioc
.scrw
[0] = 1;
729 tp
->t_maxeuc
= 1; /* the max len in bytes of an EUC char */
731 tp
->t_csmethods
= cs_methods
[LDTERM_CS_TYPE_EUC
];
732 tp
->t_csdata
= default_cs_data
;
735 * Try to switch to UTF-8 mode by allocating buffer for multibyte
736 * chars, keep EUC if allocation fails.
738 if ((tp
->t_eucp_mp
= allocb(_TTY_BUFSIZ
, BPRI_HI
)) != NULL
) {
739 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
740 tp
->t_state
= TS_MEUC
; /* Multibyte mode. */
741 tp
->t_maxeuc
= 4; /* the max len in bytes of an UTF-8 char */
742 tp
->t_csdata
.codeset_type
= LDTERM_CS_TYPE_UTF8
;
743 tp
->t_csdata
.csinfo_num
= 4;
744 /* locale_name needs string length with terminating NUL */
745 tp
->t_csdata
.locale_name
= (char *)kmem_alloc(6, KM_SLEEP
);
746 (void) strcpy(tp
->t_csdata
.locale_name
, "UTF-8");
747 tp
->t_csmethods
= cs_methods
[LDTERM_CS_TYPE_UTF8
];
749 tp
->t_eucwarn
= 0; /* no bad chars seen yet */
754 * Find out if the module below us does canonicalization; if
755 * so, we won't do it ourselves.
758 if ((qryp
= open_ioctl(q
, MC_CANONQUERY
)) == NULL
)
762 * Reformulate as an M_CTL message. The actual data will
763 * be in the b_cont field.
765 qryp
->b_datap
->db_type
= M_CTL
;
769 /* allocate a TCSBRK ioctl in case we'll need it on close */
770 if ((qryp
= open_ioctl(q
, TCSBRK
)) == NULL
)
772 tp
->t_drainmsg
= qryp
;
773 if ((bp
= open_mblk(q
, sizeof (int))) == NULL
)
778 * Find out if the underlying driver supports proper POSIX close
779 * semantics. If not, we'll have to approximate it using TCSBRK. If
780 * it does, it will respond with MC_HAS_POSIX, and we'll catch that in
781 * the ldtermrput routine.
783 * When the ldterm_drain_limit tunable is set to zero, we behave the
784 * same as old ldterm: don't send this new message, and always use
785 * TCSBRK during close.
787 if (ldterm_drain_limit
!= 0) {
788 if ((qryp
= open_ioctl(q
, MC_POSIXQUERY
)) == NULL
)
790 qryp
->b_datap
->db_type
= M_CTL
;
794 /* prepare to clear the water marks on close */
795 if ((bp
= open_mblk(q
, sizeof (struct stroptions
))) == NULL
)
797 tp
->t_closeopts
= bp
;
800 * Set the high-water and low-water marks on the stream head
801 * to values appropriate for a terminal. Also set the "vmin"
802 * and "vtime" values to 1 and 0, turn on message-nondiscard
803 * mode (as we're in ICANON mode), and turn on "old-style
806 if ((bp
= open_mblk(q
, sizeof (struct stroptions
))) == NULL
)
808 strop
= (struct stroptions
*)bp
->b_wptr
;
809 strop
->so_flags
= SO_READOPT
|SO_HIWAT
|SO_LOWAT
|SO_NDELON
|SO_ISTTY
;
810 strop
->so_readopt
= RMSGN
;
811 strop
->so_hiwat
= _TTY_BUFSIZ
;
812 strop
->so_lowat
= LOWAT
;
813 bp
->b_wptr
+= sizeof (struct stroptions
);
814 bp
->b_datap
->db_type
= M_SETOPTS
;
817 return (0); /* this can become a controlling TTY */
823 freemsg(tp
->t_closeopts
);
824 freemsg(tp
->t_drainmsg
);
825 /* Dump the state structure */
826 kmem_free(tp
, sizeof (ldtermstd_state_t
));
832 ldtermstd_state_t
*tp
;
836 drain_timed_out(void *arg
)
838 struct close_timer
*ctp
= arg
;
841 ctp
->tp
->t_state
&= ~TS_IOCWAIT
;
846 ldtermclose(queue_t
*q
, int cflag
, cred_t
*crp
)
848 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)q
->q_ptr
;
849 struct stroptions
*strop
;
851 struct close_timer cltimer
;
854 * If we have an outstanding vmin timeout, cancel it.
856 tp
->t_state
|= TS_CLOSE
;
858 (void) quntimeout(q
, tp
->t_vtid
);
862 * Cancel outstanding qbufcall request.
864 if (tp
->t_wbufcid
!= 0)
865 qunbufcall(q
, tp
->t_wbufcid
);
868 * Reset the high-water and low-water marks on the stream
869 * head (?), turn on byte-stream mode, and turn off
870 * "old-style NODELAY" mode.
872 bp
= tp
->t_closeopts
;
873 strop
= (struct stroptions
*)bp
->b_wptr
;
874 strop
->so_flags
= SO_READOPT
|SO_NDELOFF
;
875 strop
->so_readopt
= RNORM
;
876 bp
->b_wptr
+= sizeof (struct stroptions
);
877 bp
->b_datap
->db_type
= M_SETOPTS
;
880 if (cflag
& (FNDELAY
|FNONBLOCK
)) {
881 freemsg(tp
->t_drainmsg
);
882 } else if ((bp
= tp
->t_drainmsg
) != NULL
) {
886 * If the driver isn't known to have POSIX close semantics,
887 * then we have to emulate this the old way. This is done by
888 * sending down TCSBRK,1 to drain the output and waiting for
891 iocb
= (struct iocblk
*)bp
->b_rptr
;
892 iocb
->ioc_count
= sizeof (int);
893 *(int *)bp
->b_cont
->b_rptr
= 1;
894 bp
->b_cont
->b_wptr
+= sizeof (int);
895 tp
->t_state
|= TS_IOCWAIT
;
896 tp
->t_iocid
= iocb
->ioc_id
;
897 if (!putq(WR(q
), bp
))
901 * If we're not able to receive signals at this point, then
902 * launch a timer. This timer will prevent us from waiting
903 * forever for a signal that won't arrive.
906 if (!ddi_can_receive_sig() && ldterm_drain_limit
!= 0) {
908 cltimer
.id
= qtimeout(q
, drain_timed_out
, &cltimer
,
909 drv_usectohz(ldterm_drain_limit
));
913 * Note that the read side of ldterm and the qtimeout are
914 * protected by D_MTQPAIR, so no additional locking is needed
917 while (tp
->t_state
& TS_IOCWAIT
) {
918 if (qwait_sig(q
) == 0)
922 (void) quntimeout(q
, cltimer
.id
);
926 * From here to the end, the routine does not sleep and does not
927 * reference STREAMS, so it's guaranteed to run to completion.
932 freemsg(tp
->t_message
);
933 freemsg(tp
->t_eucp_mp
);
935 /* Dump the state structure, then unlink it */
936 if (tp
->t_csdata
.locale_name
!= NULL
)
937 kmem_free(tp
->t_csdata
.locale_name
,
938 strlen(tp
->t_csdata
.locale_name
) + 1);
939 kmem_free(tp
, sizeof (ldtermstd_state_t
));
946 * Put procedure for input from driver end of stream (read queue).
949 ldtermrput(queue_t
*q
, mblk_t
*mp
)
951 ldtermstd_state_t
*tp
;
953 queue_t
*wrq
= WR(q
); /* write queue of ldterm mod */
954 queue_t
*nextq
= q
->q_next
; /* queue below us */
957 unsigned char *readp
;
958 unsigned char *writep
;
959 struct termios
*emodes
; /* effective modes set by driver */
962 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
964 * We received our ack from the driver saying there is nothing left to
965 * shovel out, so wake up the close routine.
967 dbtype
= DB_TYPE(mp
);
968 if ((dbtype
== M_IOCACK
|| dbtype
== M_IOCNAK
) &&
969 (tp
->t_state
& (TS_CLOSE
|TS_IOCWAIT
)) == (TS_CLOSE
|TS_IOCWAIT
)) {
970 struct iocblk
*iocp
= (struct iocblk
*)mp
->b_rptr
;
972 if (iocp
->ioc_id
== tp
->t_iocid
) {
973 tp
->t_state
&= ~TS_IOCWAIT
;
986 * Send these up unmolested
998 ldterm_ioctl_reply(q
, mp
);
1004 * Parity errors are sent up as M_BREAKS with single
1005 * character data (formerly handled in the driver)
1007 if (mp
->b_wptr
- mp
->b_rptr
== 1) {
1009 * IGNPAR PARMRK RESULT
1011 * off on 3 byte sequence
1014 if (!(tp
->t_amodes
.c_iflag
& IGNPAR
)) {
1015 mp
->b_wptr
= mp
->b_rptr
;
1016 if (tp
->t_amodes
.c_iflag
& PARMRK
) {
1021 if ((mp
= allocb(3, BPRI_HI
)) == NULL
) {
1023 "ldtermrput: no blocks");
1026 mp
->b_datap
->db_type
= M_DATA
;
1027 *mp
->b_wptr
++ = (uchar_t
)'\377';
1028 *mp
->b_wptr
++ = '\0';
1032 mp
->b_datap
->db_type
= M_DATA
;
1033 *mp
->b_wptr
++ = '\0';
1042 * We look at the apparent modes here instead of the
1043 * effective modes. Effective modes cannot be used if
1044 * IGNBRK, BRINT and PARMRK have been negotiated to
1045 * be handled by the driver. Since M_BREAK should be
1046 * sent upstream only if break processing was not
1047 * already done, it should be ok to use the apparent
1051 if (!(tp
->t_amodes
.c_iflag
& IGNBRK
)) {
1052 if (tp
->t_amodes
.c_iflag
& BRKINT
) {
1053 ldterm_dosig(q
, SIGINT
, '\0', M_PCSIG
, FLUSHRW
);
1055 } else if (tp
->t_amodes
.c_iflag
& PARMRK
) {
1057 * Send '\377','\0', '\0'.
1060 if ((mp
= allocb(3, BPRI_HI
)) == NULL
) {
1062 "ldtermrput: no blocks");
1065 mp
->b_datap
->db_type
= M_DATA
;
1066 *mp
->b_wptr
++ = (uchar_t
)'\377';
1067 *mp
->b_wptr
++ = '\0';
1068 *mp
->b_wptr
++ = '\0';
1072 * Act as if a '\0' came in.
1075 if ((mp
= allocb(1, BPRI_HI
)) == NULL
) {
1077 "ldtermrput: no blocks");
1080 mp
->b_datap
->db_type
= M_DATA
;
1081 *mp
->b_wptr
++ = '\0';
1090 DEBUG3(("ldtermrput: M_CTL received\n"));
1092 * The M_CTL has been standardized to look like an
1096 if ((mp
->b_wptr
- mp
->b_rptr
) != sizeof (struct iocblk
)) {
1098 "Non standard M_CTL received by ldterm module\n"));
1099 /* May be for someone else; pass it on */
1103 qryp
= (struct iocblk
*)mp
->b_rptr
;
1105 switch (qryp
->ioc_cmd
) {
1109 DEBUG3(("ldtermrput: M_CTL Query Reply\n"));
1111 DEBUG3(("No information in Query Message\n"));
1114 if ((mp
->b_cont
->b_wptr
- mp
->b_cont
->b_rptr
) ==
1115 sizeof (struct termios
)) {
1116 DEBUG3(("ldtermrput: M_CTL GrandScheme\n"));
1117 /* elaborate turning off scheme */
1118 emodes
= (struct termios
*)mp
->b_cont
->b_rptr
;
1119 bcopy(emodes
, &tp
->t_dmodes
,
1120 sizeof (struct termios
));
1121 ldterm_adjust_modes(tp
);
1124 DEBUG3(("Incorrect query replysize\n"));
1129 tp
->t_state
|= TS_NOCANON
;
1131 * Note: this is very nasty. It's not clear
1132 * what the right thing to do with a partial
1133 * message is; We throw it out
1135 if (tp
->t_message
!= NULL
) {
1136 freemsg(tp
->t_message
);
1137 tp
->t_message
= NULL
;
1138 tp
->t_endmsg
= NULL
;
1142 if (tp
->t_state
& TS_MEUC
) {
1143 ASSERT(tp
->t_eucp_mp
);
1144 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1152 tp
->t_state
&= ~TS_NOCANON
;
1156 /* no longer any reason to drain from ldterm */
1157 if (ldterm_drain_limit
!= 0) {
1158 freemsg(tp
->t_drainmsg
);
1159 tp
->t_drainmsg
= NULL
;
1164 DEBUG3(("Unknown M_CTL Message\n"));
1167 putnext(q
, mp
); /* In case anyone else has to see it */
1172 * Flush everything we haven't looked at yet.
1175 if ((tp
->t_state
& TS_ISPTSTTY
) && (*mp
->b_rptr
& FLUSHBAND
))
1176 flushband(q
, *(mp
->b_rptr
+ 1), FLUSHDATA
);
1178 flushq(q
, FLUSHDATA
);
1181 * Flush everything we have looked at.
1183 freemsg(tp
->t_message
);
1184 tp
->t_message
= NULL
;
1185 tp
->t_endmsg
= NULL
;
1189 if (tp
->t_state
& TS_MEUC
) { /* EUC multi-byte */
1190 ASSERT(tp
->t_eucp_mp
);
1191 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1193 putnext(q
, mp
); /* pass it on */
1196 * Relieve input flow control
1198 if ((tp
->t_modes
.c_iflag
& IXOFF
) &&
1199 (tp
->t_state
& TS_TBLOCK
) &&
1200 !(tp
->t_state
& TS_IFBLOCK
) && q
->q_count
<= TTXOLO
) {
1201 tp
->t_state
&= ~TS_TBLOCK
;
1202 (void) putnextctl(wrq
, M_STARTI
);
1203 DEBUG1(("M_STARTI down\n"));
1210 (void) drv_setparm(SYSRAWC
, msgdsize(mp
));
1213 * Flow control: send "start input" message if blocked and
1214 * our queue is below its low water mark.
1216 if ((tp
->t_modes
.c_iflag
& IXOFF
) && (tp
->t_state
& TS_TBLOCK
) &&
1217 !(tp
->t_state
& TS_IFBLOCK
) && q
->q_count
<= TTXOLO
) {
1218 tp
->t_state
&= ~TS_TBLOCK
;
1219 (void) putnextctl(wrq
, M_STARTI
);
1220 DEBUG1(("M_STARTI down\n"));
1223 * If somebody below us ("intelligent" communications
1224 * board, pseudo-tty controlled by an editor) is doing
1225 * canonicalization, don't scan it for special characters.
1227 if (tp
->t_state
& TS_NOCANON
) {
1236 if (tp
->t_modes
.c_iflag
& (INLCR
|IGNCR
|ICRNL
|IUCLC
|IXON
) ||
1237 tp
->t_modes
.c_lflag
& (ISIG
|ICANON
)) {
1239 * We're doing some sort of non-trivial
1240 * processing of input; look at every
1243 while (readp
< bp
->b_wptr
) {
1246 if (tp
->t_modes
.c_iflag
& ISTRIP
)
1250 * First, check that this hasn't been
1251 * escaped with the "literal next"
1254 if (tp
->t_state
& TS_PLNCH
) {
1255 tp
->t_state
&= ~TS_PLNCH
;
1256 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1261 * Setting a special character to NUL
1262 * disables it, so if this character
1263 * is NUL, it should not be compared
1264 * with any of the special characters.
1265 * It should, however, restart frozen
1266 * output if IXON and IXANY are set.
1268 if (c
== _POSIX_VDISABLE
) {
1269 if (tp
->t_modes
.c_iflag
& IXON
&&
1270 tp
->t_state
& TS_TTSTOP
&&
1271 tp
->t_modes
.c_lflag
& IEXTEN
&&
1272 tp
->t_modes
.c_iflag
& IXANY
) {
1274 ~(TS_TTSTOP
|TS_OFBLOCK
);
1275 (void) putnextctl(wrq
, M_START
);
1277 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1282 * If stopped, start if you can; if
1283 * running, stop if you must.
1285 if (tp
->t_modes
.c_iflag
& IXON
) {
1286 if (tp
->t_state
& TS_TTSTOP
) {
1288 tp
->t_modes
.c_cc
[VSTART
] ||
1289 (tp
->t_modes
.c_lflag
&
1291 tp
->t_modes
.c_iflag
&
1296 (void) putnextctl(wrq
,
1301 tp
->t_modes
.c_cc
[VSTOP
]) {
1304 (void) putnextctl(wrq
,
1308 if (c
== tp
->t_modes
.c_cc
[VSTOP
] ||
1309 c
== tp
->t_modes
.c_cc
[VSTART
])
1313 * Check for "literal next" character
1314 * and "flush output" character.
1315 * Note that we omit checks for ISIG
1316 * and ICANON, since the IEXTEN
1317 * setting subsumes them.
1319 if (tp
->t_modes
.c_lflag
& IEXTEN
) {
1320 if (c
== tp
->t_modes
.c_cc
[VLNEXT
]) {
1322 * Remember that we saw a
1323 * "literal next" while
1324 * scanning input, but leave
1325 * leave it in the message so
1326 * that the service routine
1329 tp
->t_state
|= TS_PLNCH
;
1330 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1334 if (c
== tp
->t_modes
.c_cc
[VDISCARD
]) {
1335 ldterm_flush_output(c
, wrq
, tp
);
1339 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1342 * Check for signal-generating
1345 if (tp
->t_modes
.c_lflag
& ISIG
) {
1346 if (c
== tp
->t_modes
.c_cc
[VINTR
]) {
1347 ldterm_dosig(q
, SIGINT
, c
,
1351 if (c
== tp
->t_modes
.c_cc
[VQUIT
]) {
1352 ldterm_dosig(q
, SIGQUIT
, c
,
1356 if (c
== tp
->t_modes
.c_cc
[VSWTCH
]) {
1358 * Ancient SXT support; discard
1359 * character without action.
1363 if (c
== tp
->t_modes
.c_cc
[VSUSP
]) {
1364 ldterm_dosig(q
, SIGTSTP
, c
,
1368 if ((tp
->t_modes
.c_lflag
& IEXTEN
) &&
1369 (c
== tp
->t_modes
.c_cc
[VDSUSP
])) {
1370 ldterm_dosig(q
, SIGTSTP
, c
,
1376 * Consumers do not expect the ^T to be
1377 * echoed out when we generate a
1380 if (c
== tp
->t_modes
.c_cc
[VSTATUS
]) {
1381 ldterm_dosig(q
, SIGINFO
, '\0',
1387 * Throw away CR if IGNCR set, or
1388 * turn it into NL if ICRNL set.
1391 if (tp
->t_modes
.c_iflag
& IGNCR
)
1393 if (tp
->t_modes
.c_iflag
& ICRNL
)
1397 * Turn NL into CR if INLCR
1401 tp
->t_modes
.c_iflag
& INLCR
)
1406 * Map upper case input to lower case
1407 * if IUCLC flag set.
1409 if (tp
->t_modes
.c_iflag
& IUCLC
&&
1410 c
>= 'A' && c
<= 'Z')
1414 * Put the possibly-transformed
1415 * character back in the message.
1421 * If we didn't copy some characters because
1422 * we were ignoring them, fix the size of the
1423 * data block by adjusting the write pointer.
1424 * XXX This may result in a zero-length
1425 * block; will this cause anybody gastric
1428 bp
->b_wptr
-= (readp
- writep
);
1431 * We won't be doing anything other than
1432 * possibly stripping the input.
1434 if (tp
->t_modes
.c_iflag
& ISTRIP
) {
1435 while (readp
< bp
->b_wptr
)
1436 *writep
++ = *readp
++ & 0177;
1438 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1441 } while ((bp
= bp
->b_cont
) != NULL
); /* next block, if any */
1444 * Queue the message for service procedure if the
1445 * queue is not empty or canputnext() fails or
1446 * tp->t_state & TS_RESCAN is true.
1449 if (q
->q_first
!= NULL
|| !bcanputnext(q
, mp
->b_band
) ||
1450 (tp
->t_state
& TS_RESCAN
))
1453 (void) ldtermrmsg(q
, mp
);
1456 * Flow control: send "stop input" message if our queue is
1457 * approaching its high-water mark. The message will be
1458 * dropped on the floor in the service procedure, if we
1459 * cannot ship it up and we have had it upto our neck!
1461 * Set QWANTW to ensure that the read queue service procedure
1462 * gets run when nextq empties up again, so that it can
1465 if ((tp
->t_modes
.c_iflag
& IXOFF
) && !(tp
->t_state
& TS_TBLOCK
) &&
1466 q
->q_count
>= TTXOHI
) {
1467 mutex_enter(QLOCK(nextq
));
1468 nextq
->q_flag
|= QWANTW
;
1469 mutex_exit(QLOCK(nextq
));
1470 tp
->t_state
|= TS_TBLOCK
;
1471 (void) putnextctl(wrq
, M_STOPI
);
1472 DEBUG1(("M_STOPI down\n"));
1478 * Line discipline input server processing. Erase/kill and escape
1479 * ('\') processing, gathering into messages, upper/lower case input
1483 ldtermrsrv(queue_t
*q
)
1485 ldtermstd_state_t
*tp
;
1488 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
1490 if (tp
->t_state
& TS_RESCAN
) {
1492 * Canonicalization was turned on or off. Put the
1493 * message being assembled back in the input queue,
1494 * so that we rescan it.
1496 if (tp
->t_message
!= NULL
) {
1497 DEBUG5(("RESCAN WAS SET; put back in q\n"));
1498 if (tp
->t_msglen
!= 0)
1499 (void) putbq(q
, tp
->t_message
);
1501 freemsg(tp
->t_message
);
1502 tp
->t_message
= NULL
;
1503 tp
->t_endmsg
= NULL
;
1506 if (tp
->t_state
& TS_MEUC
) {
1507 ASSERT(tp
->t_eucp_mp
);
1508 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1512 tp
->t_state
&= ~TS_RESCAN
;
1515 while ((mp
= getq(q
)) != NULL
) {
1516 if (!ldtermrmsg(q
, mp
))
1521 * Flow control: send start message if blocked and our queue
1522 * is below its low water mark.
1524 if ((tp
->t_modes
.c_iflag
& IXOFF
) && (tp
->t_state
& TS_TBLOCK
) &&
1525 !(tp
->t_state
& TS_IFBLOCK
) && q
->q_count
<= TTXOLO
) {
1526 tp
->t_state
&= ~TS_TBLOCK
;
1527 (void) putctl(WR(q
), M_STARTI
);
1532 * This routine is called from both ldtermrput and ldtermrsrv to
1533 * do the actual work of dealing with mp. Return 1 on sucesss and
1537 ldtermrmsg(queue_t
*q
, mblk_t
*mp
)
1545 ldtermstd_state_t
*tp
;
1549 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
1551 if (mp
->b_datap
->db_type
<= QPCTL
&& !bcanputnext(q
, mp
->b_band
)) {
1553 * Stream head is flow controlled. If echo is
1554 * turned on, flush the read side or send a
1555 * bell down the line to stop input and
1556 * process the current message.
1557 * Otherwise(putbq) the user will not see any
1558 * response to to the typed input. Typically
1559 * happens if there is no reader process.
1560 * Note that you will loose the data in this
1561 * case if the data is coming too fast. There
1562 * is an assumption here that if ECHO is
1563 * turned on its some user typing the data on
1564 * a terminal and its not network.
1566 if (tp
->t_modes
.c_lflag
& ECHO
) {
1567 if ((tp
->t_modes
.c_iflag
& IMAXBEL
) &&
1568 (tp
->t_modes
.c_lflag
& ICANON
)) {
1570 if (canputnext(WR(q
)))
1571 ldterm_outchar(CTRL('g'), WR(q
), 4, tp
);
1575 (void) putctl1(q
, M_FLUSH
, FLUSHR
);
1578 (void) putbq(q
, mp
);
1580 goto out
; /* read side is blocked */
1583 switch (mp
->b_datap
->db_type
) {
1586 putnext(q
, mp
); /* pass it on */
1591 * Flush everything we haven't looked at yet.
1593 flushq(q
, FLUSHDATA
);
1596 * Flush everything we have looked at.
1598 freemsg(tp
->t_message
);
1599 tp
->t_message
= NULL
;
1600 tp
->t_endmsg
= NULL
;
1603 * XXX should we set read request
1604 * tp->t_rd_request to NULL?
1606 tp
->t_rocount
= 0; /* if it hasn't been typed */
1607 tp
->t_rocol
= 0; /* it hasn't been echoed :-) */
1608 if (tp
->t_state
& TS_MEUC
) {
1609 ASSERT(tp
->t_eucp_mp
);
1610 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1613 * Restart output, since it's probably got
1614 * nowhere to go anyway, and we're probably
1615 * not going to see another ^Q for a while.
1617 if (tp
->t_state
& TS_TTSTOP
) {
1618 tp
->t_state
&= ~(TS_TTSTOP
|TS_OFBLOCK
);
1619 (void) putnextctl(WR(q
), M_START
);
1622 * This message will travel up the read
1623 * queue, flushing as it goes, get turned
1624 * around at the stream head, and travel back
1625 * down the write queue, flushing as it goes.
1627 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
1630 * This message will travel down the write
1631 * queue, flushing as it goes, get turned
1632 * around at the driver, and travel back up
1633 * the read queue, flushing as it goes.
1635 (void) putctl1(WR(q
), M_FLUSH
, FLUSHR
);
1638 * Now that that's done, we send a SIGCONT
1639 * upstream, followed by the M_HANGUP.
1641 /* (void) putnextctl1(q, M_PCSIG, SIGCONT); */
1648 * Augment whatever information the driver is
1649 * returning with the information we supply.
1651 ldterm_ioctl_reply(q
, mp
);
1659 * This is an M_DATA message.
1663 * If somebody below us ("intelligent" communications
1664 * board, pseudo-tty controlled by an editor) is
1665 * doing canonicalization, don't scan it for special
1668 if (tp
->t_state
& TS_NOCANON
) {
1674 if ((bpt
= newmsg(tp
)) != NULL
) {
1678 ASSERT(bp
->b_wptr
>= bp
->b_rptr
);
1679 ebsize
= bp
->b_wptr
- bp
->b_rptr
;
1680 if (ebsize
> EBSIZE
)
1685 * By default, free the message once processed
1690 * update sysinfo canch
1691 * character. The value of
1692 * canch may vary as compared
1696 while (bp
->b_rptr
< bp
->b_wptr
) {
1698 if ((bpt
= ldterm_docanon(c
,
1699 bpt
, ebsize
, q
, tp
, &dofree
)) ==
1704 * Release this block or put back on queue.
1709 (void) putbq(q
, bp
);
1713 bpt
= ldterm_dononcanon(bp
, bpt
, ebsize
, q
, tp
);
1716 "ldtermrsrv: out of blocks");
1720 } while ((bp
= bcont
) != NULL
);
1724 * Send whatever we echoed downstream.
1726 if (tp
->t_echomp
!= NULL
) {
1727 if (canputnext(WR(q
)))
1728 putnext(WR(q
), tp
->t_echomp
);
1730 freemsg(tp
->t_echomp
);
1731 tp
->t_echomp
= NULL
;
1740 * Do canonical mode input; check whether this character is to be
1741 * treated as a special character - if so, check whether it's equal
1742 * to any of the special characters and handle it accordingly.
1743 * Otherwise, just add it to the current line.
1746 ldterm_docanon(uchar_t c
, mblk_t
*bpt
, size_t ebsize
, queue_t
*q
,
1747 ldtermstd_state_t
*tp
, int *dofreep
)
1749 queue_t
*wrq
= WR(q
);
1753 * If the previous character was the "literal next"
1754 * character, treat this character as regular input.
1756 if (tp
->t_state
& TS_SLNCH
)
1760 * Setting a special character to NUL disables it, so if this
1761 * character is NUL, it should not be compared with any of
1762 * the special characters.
1764 if (c
== _POSIX_VDISABLE
) {
1765 tp
->t_state
&= ~TS_QUOT
;
1769 * If this character is the literal next character, echo it
1770 * as '^', backspace over it, and record that fact.
1772 if ((tp
->t_modes
.c_lflag
& IEXTEN
) && c
== tp
->t_modes
.c_cc
[VLNEXT
]) {
1773 if (tp
->t_modes
.c_lflag
& ECHO
)
1774 ldterm_outstring((unsigned char *)"^\b", 2, wrq
,
1776 tp
->t_state
|= TS_SLNCH
;
1780 * Check for the editing character. If the display width of
1781 * the last byte at the canonical buffer is not one and also
1782 * smaller than or equal to UNKNOWN_WIDTH, the character at
1783 * the end of the buffer is a multi-byte and/or multi-column
1786 if (c
== tp
->t_modes
.c_cc
[VERASE
] || c
== tp
->t_modes
.c_cc
[VERASE2
]) {
1787 if (tp
->t_state
& TS_QUOT
) {
1789 * Get rid of the backslash, and put the
1790 * erase character in its place.
1792 ldterm_erase(wrq
, ebsize
, tp
);
1796 if ((tp
->t_state
& TS_MEUC
) && tp
->t_msglen
&&
1797 (*(tp
->t_eucp
- 1) != 1 &&
1798 *(tp
->t_eucp
- 1) <= UNKNOWN_WIDTH
))
1799 ldterm_csi_erase(wrq
, ebsize
, tp
);
1801 ldterm_erase(wrq
, ebsize
, tp
);
1806 if ((tp
->t_modes
.c_lflag
& IEXTEN
) && c
== tp
->t_modes
.c_cc
[VWERASE
]) {
1808 * Do "ASCII word" or "multibyte character token/chunk" erase.
1810 if (tp
->t_state
& TS_MEUC
)
1811 ldterm_csi_werase(wrq
, ebsize
, tp
);
1813 ldterm_werase(wrq
, ebsize
, tp
);
1817 if (c
== tp
->t_modes
.c_cc
[VKILL
]) {
1818 if (tp
->t_state
& TS_QUOT
) {
1820 * Get rid of the backslash, and put the kill
1821 * character in its place.
1823 ldterm_erase(wrq
, ebsize
, tp
);
1827 ldterm_kill(wrq
, ebsize
, tp
);
1832 if ((tp
->t_modes
.c_lflag
& IEXTEN
) && c
== tp
->t_modes
.c_cc
[VREPRINT
]) {
1833 ldterm_reprint(wrq
, ebsize
, tp
);
1837 * If the preceding character was a backslash: if the current
1838 * character is an EOF, get rid of the backslash and treat
1839 * the EOF as data; if we're in XCASE mode and the current
1840 * character is part of a backslash-X escape sequence,
1841 * process it; otherwise, just treat the current character
1844 if (tp
->t_state
& TS_QUOT
) {
1845 tp
->t_state
&= ~TS_QUOT
;
1846 if (c
== tp
->t_modes
.c_cc
[VEOF
]) {
1848 * EOF character. Since it's escaped, get rid
1849 * of the backslash and put the EOF character
1852 ldterm_erase(wrq
, ebsize
, tp
);
1856 * If we're in XCASE mode, and the current
1857 * character is part of a backslash-X
1858 * sequence, get rid of the backslash and
1859 * replace the current character with what
1860 * that sequence maps to.
1862 if ((tp
->t_modes
.c_lflag
& XCASE
) &&
1863 imaptab
[c
] != '\0') {
1864 ldterm_erase(wrq
, ebsize
, tp
);
1871 * Previous character wasn't backslash; check whether
1872 * this was the EOF character.
1874 if (c
== tp
->t_modes
.c_cc
[VEOF
]) {
1876 * EOF character. Don't echo it unless
1877 * ECHOCTL is set, don't stuff it in the
1878 * current line, but send the line up the
1881 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
1882 (tp
->t_modes
.c_lflag
& IEXTEN
) &&
1883 (tp
->t_modes
.c_lflag
& ECHO
)) {
1884 i
= ldterm_echo(c
, wrq
, ebsize
, tp
);
1886 ldterm_outchar('\b', wrq
, ebsize
, tp
);
1890 bpt
->b_datap
->db_type
= M_DATA
;
1891 ldterm_msg_upstream(q
, tp
);
1892 if (!canputnext(q
)) {
1905 * First, make sure we can fit one WHOLE multi-byte char in the
1906 * buffer. This is one place where we have overhead even if
1907 * not in multi-byte mode; the overhead is subtracting
1908 * tp->t_maxeuc from MAX_CANON before checking.
1910 * Allows MAX_CANON bytes in the buffer before throwing awaying
1911 * the the overflow of characters.
1913 if ((tp
->t_msglen
> ((_TTY_BUFSIZ
+ 1) - (int)tp
->t_maxeuc
)) &&
1914 !((tp
->t_state
& TS_MEUC
) && tp
->t_eucleft
)) {
1917 * Byte will cause line to overflow, or the next EUC
1918 * won't fit: Ring the bell or discard all input, and
1919 * don't save the byte away.
1921 if (tp
->t_modes
.c_iflag
& IMAXBEL
) {
1922 if (canputnext(wrq
))
1923 ldterm_outchar(CTRL('g'), wrq
, ebsize
, tp
);
1927 * MAX_CANON processing. free everything in
1928 * the current line and start with the
1929 * current character as the first character.
1931 DEBUG7(("ldterm_docanon: MAX_CANON processing\n"));
1932 freemsg(tp
->t_message
);
1933 tp
->t_message
= NULL
;
1934 tp
->t_endmsg
= NULL
;
1936 tp
->t_rocount
= 0; /* if it hasn't been type */
1937 tp
->t_rocol
= 0; /* it hasn't been echoed :-) */
1938 if (tp
->t_state
& TS_MEUC
) {
1939 ASSERT(tp
->t_eucp_mp
);
1940 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1942 tp
->t_state
&= ~TS_SLNCH
;
1947 * Add the character to the current line.
1949 if (bpt
->b_wptr
>= bpt
->b_datap
->db_lim
) {
1951 * No more room in this mblk; save this one away, and
1952 * allocate a new one.
1954 bpt
->b_datap
->db_type
= M_DATA
;
1955 if ((bpt
= allocb(IBSIZE
, BPRI_MED
)) == NULL
)
1959 * Chain the new one to the end of the old one, and
1960 * mark it as the last block in the current line.
1962 tp
->t_endmsg
->b_cont
= bpt
;
1966 tp
->t_msglen
++; /* message length in BYTES */
1969 * In multi-byte mode, we have to keep track of where we are.
1970 * The first bytes of multi-byte chars get the full count for the
1971 * whole character. We don't do any column calculations
1972 * here, but we need the information for when we do. We could
1973 * come across cases where we are getting garbage on the
1974 * line, but we're in multi-byte mode. In that case, we may
1975 * see ASCII controls come in the middle of what should have been a
1976 * multi-byte character. Call ldterm_eucwarn...eventually, a
1977 * warning message will be printed about it.
1979 if (tp
->t_state
& TS_MEUC
) {
1980 if (tp
->t_eucleft
) { /* if in a multi-byte char already */
1982 *tp
->t_eucp
++ = 0; /* is a subsequent byte */
1983 if (c
< (uchar_t
)0x20)
1985 } else { /* is the first byte of a multi-byte, or is ASCII */
1988 tp
->t_csmethods
.ldterm_dispwidth(c
,
1989 (void *)tp
, tp
->t_modes
.c_lflag
& ECHOCTL
);
1993 tp
->t_csmethods
.ldterm_dispwidth(c
,
1994 (void *)tp
, tp
->t_modes
.c_lflag
& ECHOCTL
);
1996 tp
->t_csmethods
.ldterm_memwidth(c
,
1998 tp
->t_codeset
= ldterm_codeset(
1999 tp
->t_csdata
.codeset_type
, c
);
2004 * AT&T is concerned about the following but we aren't since
2005 * we have already shipped code that works.
2007 * EOL2/XCASE should be conditioned with IEXTEN to be truly
2008 * POSIX conformant. This is going to cause problems for
2009 * pre-SVR4.0 programs that don't know about IEXTEN. Hence
2010 * EOL2/IEXTEN is not conditioned with IEXTEN.
2012 if (!(tp
->t_state
& TS_SLNCH
) &&
2013 (c
== '\n' || (c
!= '\0' && (c
== tp
->t_modes
.c_cc
[VEOL
] ||
2014 (c
== tp
->t_modes
.c_cc
[VEOL2
]))))) {
2016 * || ((tp->t_modes.c_lflag & IEXTEN) && c ==
2017 * tp->t_modes.c_cc[VEOL2]))))) {
2020 * It's a line-termination character; send the line
2023 bpt
->b_datap
->db_type
= M_DATA
;
2024 ldterm_msg_upstream(q
, tp
);
2025 if (tp
->t_state
& TS_MEUC
) {
2026 ASSERT(tp
->t_eucp_mp
);
2027 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
2029 if ((bpt
= newmsg(tp
)) == NULL
)
2033 * Character was escaped with LNEXT.
2035 if (tp
->t_rocount
++ == 0)
2036 tp
->t_rocol
= tp
->t_col
;
2037 tp
->t_state
&= ~(TS_SLNCH
|TS_QUOT
);
2039 * If the current character is a single byte and single
2040 * column character and it is the backslash character and
2041 * IEXTEN, then the state will have TS_QUOT.
2043 if ((c
== '\\') && (tp
->t_modes
.c_lflag
& IEXTEN
) &&
2044 (!(tp
->t_state
& TS_MEUC
) ||
2045 ((tp
->t_state
& TS_MEUC
) && (!tp
->t_eucleft
))))
2046 tp
->t_state
|= TS_QUOT
;
2052 if (tp
->t_state
& TS_ERASE
) {
2053 tp
->t_state
&= ~TS_ERASE
;
2054 if (tp
->t_modes
.c_lflag
& ECHO
)
2055 ldterm_outchar('/', wrq
, ebsize
, tp
);
2057 if (tp
->t_modes
.c_lflag
& ECHO
)
2058 (void) ldterm_echo(c
, wrq
, ebsize
, tp
);
2061 * Echo NL when ECHO turned off, if ECHONL flag is
2064 if (c
== '\n' && (tp
->t_modes
.c_lflag
& ECHONL
))
2065 ldterm_outchar(c
, wrq
, ebsize
, tp
);
2075 ldterm_unget(ldtermstd_state_t
*tp
)
2079 if ((bpt
= tp
->t_endmsg
) == NULL
)
2080 return (-1); /* no buffers */
2081 if (bpt
->b_rptr
== bpt
->b_wptr
)
2082 return (-1); /* zero-length record */
2083 tp
->t_msglen
--; /* one fewer character */
2084 return (*--bpt
->b_wptr
);
2089 ldterm_trim(ldtermstd_state_t
*tp
)
2094 ASSERT(tp
->t_endmsg
);
2097 if (bpt
->b_rptr
== bpt
->b_wptr
) {
2099 * This mblk is now empty. Find the previous mblk;
2100 * throw this one away, unless it's the first one.
2104 while (bp
->b_cont
!= bpt
) {
2110 tp
->t_endmsg
= bp
; /* point to that mblk */
2117 * Rubout one character from the current line being built for tp as
2118 * cleanly as possible. q is the write queue for tp. Most of this
2119 * can't be applied to multi-byte processing. We do our own thing
2120 * for that... See the "ldterm_eucerase" routine. We never call
2121 * ldterm_rubout on a multi-byte or multi-column character.
2124 ldterm_rubout(uchar_t c
, queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2127 static unsigned char crtrubout
[] = "\b \b\b \b";
2128 #define RUBOUT1 &crtrubout[3] /* rub out one position */
2129 #define RUBOUT2 &crtrubout[0] /* rub out two positions */
2131 if (!(tp
->t_modes
.c_lflag
& ECHO
))
2133 if (tp
->t_modes
.c_lflag
& ECHOE
) {
2135 * "CRT rubout"; try erasing it from the screen.
2137 if (tp
->t_rocount
== 0) {
2139 * After the character being erased was
2140 * echoed, some data was written to the
2141 * terminal; we can't erase it cleanly, so we
2142 * just reprint the whole line as if the user
2143 * had typed the reprint character.
2145 ldterm_reprint(q
, ebsize
, tp
);
2149 * XXX what about escaped characters?
2151 switch (typetab
[c
]) {
2154 if ((tp
->t_modes
.c_lflag
& XCASE
) &&
2156 ldterm_outstring(RUBOUT1
, 3, q
, ebsize
,
2158 ldterm_outstring(RUBOUT1
, 3, q
, ebsize
, tp
);
2166 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
2167 (tp
->t_modes
.c_lflag
& IEXTEN
))
2168 ldterm_outstring(RUBOUT2
, 6, q
, ebsize
,
2173 if (tp
->t_rocount
< tp
->t_msglen
) {
2175 * While the tab being erased was
2176 * expanded, some data was written
2177 * to the terminal; we can't erase
2178 * it cleanly, so we just reprint
2179 * the whole line as if the user
2180 * had typed the reprint character.
2182 ldterm_reprint(q
, ebsize
, tp
);
2185 tabcols
= ldterm_tabcols(tp
);
2186 while (--tabcols
>= 0)
2187 ldterm_outchar('\b', q
, ebsize
, tp
);
2191 } else if ((tp
->t_modes
.c_lflag
& ECHOPRT
) &&
2192 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
2194 * "Printing rubout"; echo it between \ and /.
2196 if (!(tp
->t_state
& TS_ERASE
)) {
2197 ldterm_outchar('\\', q
, ebsize
, tp
);
2198 tp
->t_state
|= TS_ERASE
;
2200 (void) ldterm_echo(c
, q
, ebsize
, tp
);
2202 (void) ldterm_echo(tp
->t_modes
.c_cc
[VERASE
], q
, ebsize
, tp
);
2203 tp
->t_rocount
--; /* we "unechoed" this character */
2208 * Find the number of characters the tab we just deleted took up by
2209 * zipping through the current line and recomputing the column
2213 ldterm_tabcols(ldtermstd_state_t
*tp
)
2218 unsigned char *readp
, *endp
;
2222 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
2226 * If we're doing multi-byte stuff, zip through the list of
2227 * widths to figure out where we are (we've kept track in most
2230 if (tp
->t_state
& TS_MEUC
) {
2231 ASSERT(tp
->t_eucp_mp
);
2233 startp
= bp
->b_datap
->db_base
;
2234 readp
= tp
->t_eucp_mp
->b_rptr
;
2237 while (readp
< endp
) {
2239 case EUC_TWIDTH
: /* it's a tab */
2240 col
|= 07; /* bump up */
2243 case EUC_BSWIDTH
: /* backspace */
2247 case EUC_NLWIDTH
: /* newline */
2248 if (tp
->t_modes
.c_oflag
& ONLRET
)
2251 case EUC_CRWIDTH
: /* return */
2254 case UNKNOWN_WIDTH
: /* UTF-8 unknown width */
2255 if (tp
->t_csdata
.codeset_type
!=
2256 LDTERM_CS_TYPE_UTF8
|| errflg
) {
2262 * Collect the current UTF-8 character bytes
2263 * from (possibly multiple) data buffers so
2264 * that we can figure out the display width.
2267 for (i
= 1; (i
< LDTERM_CS_MAX_BYTE_LENGTH
) &&
2268 (*(readp
+ i
) == 0); i
++) {
2270 if (startp
>= bp
->b_datap
->db_lim
) {
2285 /* tp->t_eucp_mp contains wrong info?? */
2289 *readp
= ldterm_utf8_width(u8
, i
);
2300 if (startp
>= bp
->b_datap
->db_lim
) {
2303 startp
= bp
->b_datap
->db_base
;
2306 * This will happen only if
2307 * tp->t_eucp_mp contains wrong
2308 * display width info.
2315 goto eucout
; /* finished! */
2320 while (readp
< bp
->b_wptr
) {
2322 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
2323 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
2324 if (c
<= 037 && c
!= '\t' && c
!= '\n' ||
2331 * Column position calculated here.
2333 switch (typetab
[c
]) {
2336 * Ordinary characters; advance by
2344 * Non-printing characters; nothing
2356 /* Newline; column depends on flags. */
2358 if (tp
->t_modes
.c_oflag
& ONLRET
)
2368 /* vertical motion */
2372 /* carriage return */
2378 } while ((bp
= bp
->b_cont
) != NULL
); /* next block, if any */
2381 * "col" is now the column number before the tab. "tp->t_col"
2382 * is still the column number after the tab, since we haven't
2383 * erased the tab yet. Thus "tp->t_col - col" is the number
2384 * of positions the tab moved.
2387 col
= tp
->t_col
- col
;
2389 col
= 8; /* overflow screw */
2395 * Erase a single character; We ONLY ONLY deal with ASCII or
2396 * single-column single-byte codeset character. For multi-byte characters,
2397 * see "ldterm_csi_erase".
2400 ldterm_erase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2404 if ((c
= ldterm_unget(tp
)) != -1) {
2405 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2407 if (tp
->t_state
& TS_MEUC
)
2414 * Erase an entire word, single-byte EUC only please.
2417 ldterm_werase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2422 * Erase trailing white space, if any.
2424 while ((c
= ldterm_unget(tp
)) == ' ' || c
== '\t') {
2425 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2430 * Erase non-white-space characters, if any.
2432 while (c
!= -1 && c
!= ' ' && c
!= '\t') {
2433 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2435 c
= ldterm_unget(tp
);
2439 * We removed one too many characters; put the last
2442 tp
->t_endmsg
->b_wptr
++; /* put 'c' back */
2449 * ldterm_csi_werase - This is multi-byte equivalent of "word erase".
2450 * "Word erase" only makes sense in languages which space between words,
2451 * and it's presumptuous for us to attempt "word erase" when we don't
2452 * know anything about what's really going on. It makes no sense for
2453 * many languages, as the criteria for defining words and tokens may
2454 * be completely different.
2456 * In the TS_MEUC case (which is how we got here), we define a token to
2457 * be space- or tab-delimited, and erase one of them. It helps to
2458 * have this for command lines, but it's otherwise useless for text
2459 * editing applications; you need more sophistication than we can
2463 ldterm_csi_werase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2468 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
2469 uchar_t u8_2
[LDTERM_CS_MAX_BYTE_LENGTH
];
2472 * ip points to the width of the actual bytes. t_eucp points
2473 * one byte beyond, where the next thing will be inserted.
2475 ip
= tp
->t_eucp
- 1;
2477 * Erase trailing white space, if any.
2479 while ((c
= ldterm_unget(tp
)) == ' ' || c
== '\t') {
2481 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2487 * Erase non-white-space characters, if any. The outer loop
2488 * bops through each byte in the buffer. Multi-byte is removed, as
2489 * is ASCII, one byte at a time. The inner loop (for) is only
2490 * executed for first bytes of multi-byte. The inner loop erases
2491 * the number of columns required for the multi-byte char. We check
2492 * for ASCII first, and ldterm_rubout knows about ASCII.
2495 while (c
!= -1 && c
!= ' ' && c
!= '\t') {
2497 if (len
< LDTERM_CS_MAX_BYTE_LENGTH
) {
2498 u8
[len
++] = (uchar_t
)c
;
2501 * Unlike EUC, except the leading byte, some bytes of
2502 * a non-EUC multi-byte characters are in the ASCII code
2503 * range, esp., 0x41 ~ 0x7a. Thus, we cannot simply check
2505 * Checking the (*ip == 1 || *ip == 2 || *ip > UNKNOWN_WIDTH)
2506 * will ensure that it is a single byte character (even though
2507 * it is on display width not byte length) and can be further
2508 * checked whether it is an ASCII character or not.
2510 * When ECHOCTL is on and 'c' is an ASCII control character,
2513 if ((*ip
== 1 || *ip
== 2 || *ip
> UNKNOWN_WIDTH
) &&
2515 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2518 if (*ip
== UNKNOWN_WIDTH
) {
2519 if (tp
->t_csdata
.codeset_type
==
2520 LDTERM_CS_TYPE_UTF8
) {
2521 for (i
= 0; i
< len
; i
++)
2522 u8_2
[i
] = u8
[len
- i
- 1];
2523 *ip
= ldterm_utf8_width(u8_2
, len
);
2529 * erase for number of columns required for
2530 * this multi-byte character. Hopefully, matches
2533 for (i
= 0; i
< (int)*ip
; i
++)
2534 ldterm_rubout(' ', q
, ebsize
, tp
);
2539 c
= ldterm_unget(tp
);
2543 * We removed one too many characters; put the last
2546 tp
->t_endmsg
->b_wptr
++; /* put 'c' back */
2553 * Kill an entire line, erasing each character one-by-one (if ECHOKE
2554 * is set) or just echoing the kill character, followed by a newline
2555 * (if ECHOK is set). Multi-byte processing is included here.
2559 ldterm_kill(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2564 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
2565 uchar_t u8_2
[LDTERM_CS_MAX_BYTE_LENGTH
];
2567 if ((tp
->t_modes
.c_lflag
& ECHOKE
) &&
2568 (tp
->t_modes
.c_lflag
& IEXTEN
) &&
2569 (tp
->t_msglen
== tp
->t_rocount
)) {
2570 if (tp
->t_state
& TS_MEUC
) {
2571 ip
= tp
->t_eucp
- 1;
2573 * This loop similar to "ldterm_csi_werase" above.
2576 while ((c
= ldterm_unget(tp
)) != (-1)) {
2578 if (len
< LDTERM_CS_MAX_BYTE_LENGTH
) {
2579 u8
[len
++] = (uchar_t
)c
;
2581 if ((*ip
== 1 || *ip
== 2 ||
2582 *ip
> UNKNOWN_WIDTH
) && ISASCII(c
)) {
2583 ldterm_rubout((unsigned char) c
, q
,
2587 if (*ip
== UNKNOWN_WIDTH
) {
2588 if (tp
->t_csdata
.codeset_type
2589 == LDTERM_CS_TYPE_UTF8
) {
2590 for (i
= 0; i
< len
;
2594 *ip
= ldterm_utf8_width(
2600 for (i
= 0; i
< (int)*ip
; i
++)
2601 ldterm_rubout(' ', q
, ebsize
,
2609 while ((c
= ldterm_unget(tp
)) != -1) {
2610 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2615 (void) ldterm_echo(tp
->t_modes
.c_cc
[VKILL
], q
, ebsize
, tp
);
2616 if (tp
->t_modes
.c_lflag
& ECHOK
)
2617 (void) ldterm_echo('\n', q
, ebsize
, tp
);
2618 while (ldterm_unget(tp
) != -1) {
2619 if (tp
->t_state
& TS_MEUC
)
2624 if (tp
->t_state
& TS_MEUC
)
2625 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
2627 tp
->t_state
&= ~(TS_QUOT
|TS_ERASE
|TS_SLNCH
);
2632 * Reprint the current input line. We assume c_cc has already been
2633 * checked. XXX just the current line, not the whole queue? What
2634 * about DEFECHO mode?
2637 ldterm_reprint(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2640 unsigned char *readp
;
2642 if (tp
->t_modes
.c_cc
[VREPRINT
] != (unsigned char) 0)
2643 (void) ldterm_echo(tp
->t_modes
.c_cc
[VREPRINT
], q
, ebsize
, tp
);
2644 ldterm_outchar('\n', q
, ebsize
, tp
);
2649 while (readp
< bp
->b_wptr
)
2650 (void) ldterm_echo(*readp
++, q
, ebsize
, tp
);
2651 } while ((bp
= bp
->b_cont
) != NULL
); /* next block, if any */
2653 tp
->t_state
&= ~TS_ERASE
;
2654 tp
->t_rocount
= tp
->t_msglen
; /* we reechoed the entire line */
2660 * Non canonical processing. Called with q locked from ldtermrsrv.
2664 ldterm_dononcanon(mblk_t
*bp
, mblk_t
*bpt
, size_t ebsize
, queue_t
*q
,
2665 ldtermstd_state_t
*tp
)
2667 queue_t
*wrq
= WR(q
);
2668 unsigned char *rptr
;
2671 size_t bytes_to_move
;
2674 if (tp
->t_modes
.c_lflag
& (ECHO
|ECHONL
|IEXTEN
)) {
2675 unsigned char *wptr
;
2679 * Either we must echo the characters, or we must
2680 * echo NL, or we must check for VLNEXT. Process
2681 * characters one at a time.
2685 while (rptr
< bp
->b_wptr
) {
2688 * If this character is the literal next
2689 * character, echo it as '^' and backspace
2690 * over it if echoing is enabled, indicate
2691 * that the next character is to be treated
2692 * literally, and remove the LNEXT from the
2695 * If the *previous* character was the literal
2696 * next character, don't check whether this
2697 * is a literal next or not.
2699 if ((tp
->t_modes
.c_lflag
& IEXTEN
) &&
2700 !(tp
->t_state
& TS_SLNCH
) &&
2701 c
!= _POSIX_VDISABLE
&&
2702 c
== tp
->t_modes
.c_cc
[VLNEXT
]) {
2703 if (tp
->t_modes
.c_lflag
& ECHO
)
2705 (unsigned char *)"^\b",
2706 2, wrq
, ebsize
, tp
);
2707 tp
->t_state
|= TS_SLNCH
;
2708 continue; /* and ignore it */
2711 * Not a "literal next" character, so it
2712 * should show up as input. If it was
2713 * literal-nexted, turn off the literal-next
2716 tp
->t_state
&= ~TS_SLNCH
;
2718 if (tp
->t_modes
.c_lflag
& ECHO
) {
2720 * Echo the character.
2722 (void) ldterm_echo(c
, wrq
, ebsize
, tp
);
2723 } else if (tp
->t_modes
.c_lflag
& ECHONL
) {
2725 * Echo NL, even though ECHO is not
2729 ldterm_outchar('\n', wrq
, 1, tp
);
2735 * If there are any characters in this buffer, and
2736 * the first of them was literal-nexted, turn off the
2737 * literal-next flag.
2739 if (bp
->b_rptr
!= bp
->b_wptr
)
2740 tp
->t_state
&= ~TS_SLNCH
;
2743 ASSERT(bp
->b_wptr
>= bp
->b_rptr
);
2744 bytes_in_bp
= bp
->b_wptr
- bp
->b_rptr
;
2746 while (bytes_in_bp
!= 0) {
2747 roomleft
= bpt
->b_datap
->db_lim
- bpt
->b_wptr
;
2748 if (roomleft
== 0) {
2750 * No more room in this mblk; save this one
2751 * away, and allocate a new one.
2753 if ((bpt
= allocb(IBSIZE
, BPRI_MED
)) == NULL
) {
2755 DEBUG4(("ldterm_do_noncanon: allcob failed\n"));
2759 * Chain the new one to the end of the old
2760 * one, and mark it as the last block in the
2763 tp
->t_endmsg
->b_cont
= bpt
;
2767 DEBUG5(("roomleft=%d, bytes_in_bp=%d, tp->t_rd_request=%d\n",
2768 roomleft
, bytes_in_bp
, tp
->t_rd_request
));
2770 * if there is a read pending before this data got
2771 * here move bytes according to the minimum of room
2772 * left in this buffer, bytes in the message and byte
2773 * count requested in the read. If there is no read
2774 * pending, move the minimum of the first two
2776 if (tp
->t_rd_request
== 0)
2777 bytes_to_move
= MIN(roomleft
, bytes_in_bp
);
2780 MIN(MIN(roomleft
, bytes_in_bp
), tp
->t_rd_request
);
2781 DEBUG5(("Bytes to move = %lu\n", bytes_to_move
));
2782 if (bytes_to_move
== 0)
2784 bcopy(rptr
, bpt
->b_wptr
, bytes_to_move
);
2785 bpt
->b_wptr
+= bytes_to_move
;
2786 rptr
+= bytes_to_move
;
2787 tp
->t_msglen
+= bytes_to_move
;
2788 bytes_in_bp
-= bytes_to_move
;
2790 if (bytes_in_bp
== 0) {
2791 DEBUG4(("bytes_in_bp is zero\n"));
2794 free_flag
= 1; /* for debugging olny */
2796 DEBUG4(("ldterm_do_noncanon: VMIN = %d, VTIME = %d, msglen = %d, \
2797 tid = %d\n", V_MIN
, V_TIME
, tp
->t_msglen
, tp
->t_vtid
));
2799 * If there is a pending read request at the stream head we
2800 * need to do VMIN/VTIME processing. The four possible cases
2806 * If we can satisfy VMIN, send it up, and start a new
2807 * timer if necessary. These four cases of VMIN/VTIME
2808 * are also dealt with in the write side put routine
2809 * when the M_READ is first seen.
2812 DEBUG4(("Incoming data while M_READ'ing\n"));
2814 * Case 1: Any data will satisfy the read, so send
2817 if (V_MIN
== 0 && V_TIME
> 0) {
2819 vmin_satisfied(q
, tp
, 1);
2822 DEBUG4(("ldterm_do_noncanon called, but no data!\n"));
2825 * Case 2: This should never time out, so
2826 * until there's enough data, do nothing.
2828 } else if (V_MIN
> 0 && V_TIME
== 0) {
2829 if (tp
->t_msglen
>= (int)V_MIN
)
2830 vmin_satisfied(q
, tp
, 1);
2833 * Case 3: If MIN is satisfied, send it up.
2834 * Also, remember to start a new timer *every*
2835 * time we see something if MIN isn't
2838 } else if (V_MIN
> 0 && V_TIME
> 0) {
2839 if (tp
->t_msglen
>= (int)V_MIN
)
2840 vmin_satisfied(q
, tp
, 1);
2844 * Case 4: Not possible. This request
2845 * should always be satisfied from the write
2846 * side, left here for debugging.
2848 } else { /* V_MIN == 0 && V_TIME == 0 */
2849 vmin_satisfied(q
, tp
, 1);
2854 DEBUG4(("CAUTION message block not freed\n"));
2856 return (newmsg(tp
));
2861 * Echo a typed byte to the terminal. Returns the number of bytes
2862 * printed. Bytes of EUC characters drop through the ECHOCTL stuff
2863 * and are just output as themselves.
2866 ldterm_echo(uchar_t c
, queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2870 if (!(tp
->t_modes
.c_lflag
& ECHO
))
2875 * Echo control characters (c <= 37) only if the ECHOCTRL
2876 * flag is set as ^X.
2879 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
2880 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
2881 if (c
<= 037 && c
!= '\t' && c
!= '\n') {
2882 ldterm_outchar('^', q
, ebsize
, tp
);
2884 if (tp
->t_modes
.c_oflag
& OLCUC
)
2888 } else if (c
== 0177) {
2889 ldterm_outchar('^', q
, ebsize
, tp
);
2893 ldterm_outchar(c
, q
, ebsize
, tp
);
2895 /* echo only special control character and the Bell */
2896 } else if ((c
> 037 && c
!= 0177) || c
== '\t' || c
== '\n' ||
2897 c
== '\r' || c
== '\b' || c
== 007 ||
2898 c
== tp
->t_modes
.c_cc
[VKILL
]) {
2899 ldterm_outchar(c
, q
, ebsize
, tp
);
2907 * Put a character on the output queue.
2910 ldterm_outchar(uchar_t c
, queue_t
*q
, size_t bsize
, ldtermstd_state_t
*tp
)
2915 * Don't even look at the characters unless we have something
2916 * useful to do with them.
2918 if ((tp
->t_modes
.c_oflag
& OPOST
) ||
2919 ((tp
->t_modes
.c_lflag
& XCASE
) &&
2920 (tp
->t_modes
.c_lflag
& ICANON
))) {
2923 if ((mp
= allocb(4, BPRI_HI
)) == NULL
) {
2925 "ldterm: (ldterm_outchar) out of blocks");
2929 mp
= ldterm_output_msg(q
, mp
, &tp
->t_echomp
, tp
, bsize
, 1);
2934 if ((curbp
= tp
->t_echomp
) != NULL
) {
2935 while (curbp
->b_cont
!= NULL
)
2936 curbp
= curbp
->b_cont
;
2937 if (curbp
->b_datap
->db_lim
== curbp
->b_wptr
) {
2940 if ((newbp
= allocb(bsize
, BPRI_HI
)) == NULL
) {
2942 "ldterm_outchar: out of blocks");
2945 curbp
->b_cont
= newbp
;
2949 if ((curbp
= allocb(bsize
, BPRI_HI
)) == NULL
) {
2951 "ldterm_outchar: out of blocks");
2954 tp
->t_echomp
= curbp
;
2956 *curbp
->b_wptr
++ = c
;
2962 * Copy a string, of length len, to the output queue.
2965 ldterm_outstring(uchar_t
*cp
, int len
, queue_t
*q
, size_t bsize
,
2966 ldtermstd_state_t
*tp
)
2969 ldterm_outchar(*cp
++, q
, bsize
, tp
);
2976 newmsg(ldtermstd_state_t
*tp
)
2981 * If no current message, allocate a block for it.
2983 if ((bp
= tp
->t_endmsg
) == NULL
) {
2984 if ((bp
= allocb(IBSIZE
, BPRI_MED
)) == NULL
) {
2986 "ldterm: (ldtermrsrv/newmsg) out of blocks");
2997 ldterm_msg_upstream(queue_t
*q
, ldtermstd_state_t
*tp
)
3005 putnext(q
, tp
->t_message
);
3008 * update sysinfo canch character.
3011 (void) drv_setparm(SYSCANC
, s
);
3012 tp
->t_message
= NULL
;
3013 tp
->t_endmsg
= NULL
;
3016 tp
->t_rd_request
= 0;
3017 if (tp
->t_state
& TS_MEUC
) {
3018 ASSERT(tp
->t_eucp_mp
);
3019 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
3020 /* can't reset everything, as we may have other input */
3026 * Re-enable the write-side service procedure. When an allocation
3027 * failure causes write-side processing to stall, we disable the
3028 * write side and arrange to call this function when allocation once
3029 * again becomes possible.
3032 ldterm_wenable(void *addr
)
3035 ldtermstd_state_t
*tp
;
3037 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
3039 * The bufcall is no longer pending.
3048 * Line discipline output queue put procedure. Attempts to process
3049 * the message directly and send it on downstream, queueing it only
3050 * if there's already something pending or if its downstream neighbor
3054 ldtermwput(queue_t
*q
, mblk_t
*mp
)
3056 ldtermstd_state_t
*tp
;
3057 unsigned char type
= mp
->b_datap
->db_type
;
3059 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
3062 * Always process priority messages, regardless of whether or
3063 * not our queue is nonempty.
3065 if (type
>= QPCTL
) {
3070 * Get rid of it, see comment in
3073 if ((tp
->t_state
& TS_FLUSHWAIT
) &&
3074 (*mp
->b_rptr
== FLUSHW
)) {
3075 tp
->t_state
&= ~TS_FLUSHWAIT
;
3080 * This is coming from above, so we only
3081 * handle the write queue here. If FLUSHR is
3082 * set, it will get turned around at the
3083 * driver, and the read procedure will see it
3086 if (*mp
->b_rptr
& FLUSHW
) {
3087 if ((tp
->t_state
& TS_ISPTSTTY
) &&
3088 (*mp
->b_rptr
& FLUSHBAND
))
3089 flushband(q
, *(mp
->b_rptr
+ 1),
3092 flushq(q
, FLUSHDATA
);
3097 * If a timed read is interrupted, there is
3098 * no way to cancel an existing M_READ
3099 * request. We kludge by allowing a flush to
3102 if (tp
->t_state
& TS_MREAD
)
3103 vmin_satisfied(RD(q
), tp
, 0);
3107 DEBUG1(("ldtermwmsg:M_READ RECEIVED\n"));
3109 * Stream head needs data to satisfy timed
3110 * read. Has meaning only if ICANON flag is
3111 * off indicating raw mode
3115 "M_READ: RAW_MODE=%d, CNT=%d, VMIN=%d, VTIME=%d\n",
3116 RAW_MODE
, *(unsigned int *)mp
->b_rptr
, V_MIN
,
3119 tp
->t_rd_request
= *(unsigned int *)mp
->b_rptr
;
3122 if (newmsg(tp
) != NULL
) {
3124 * VMIN/VTIME processing...
3125 * The four possible cases are:
3130 * These four conditions must be dealt
3131 * with on the read side as well in
3132 * ldterm_do_noncanon(). Set TS_MREAD
3133 * so that the read side will know
3134 * there is a pending read request
3135 * waiting at the stream head. If we
3136 * can satisfy MIN do it here, rather
3137 * than on the read side. If we can't,
3138 * start timers if necessary and let
3139 * the other side deal with it.
3141 * We got another M_READ before the
3142 * pending one completed, cancel any
3145 if (tp
->t_state
& TS_MREAD
) {
3146 vmin_satisfied(RD(q
),
3149 tp
->t_state
|= TS_MREAD
;
3151 * Case 1: Any data will
3152 * satisfy read, otherwise
3155 if (V_MIN
== 0 && V_TIME
> 0) {
3157 vmin_satisfied(RD(q
),
3160 vmin_settimer(RD(q
));
3163 * Case 2: If we have enough
3164 * data, send up now.
3165 * Otherwise, the read side
3166 * should wait forever until MIN
3169 } else if (V_MIN
> 0 && V_TIME
== 0) {
3170 if (tp
->t_msglen
>= (int)V_MIN
)
3171 vmin_satisfied(RD(q
),
3175 * Case 3: If we can satisfy
3176 * the read, send it up. If we
3177 * don't have enough data, but
3178 * there is at least one char,
3179 * start a timer. Otherwise,
3180 * let the read side start
3183 } else if (V_MIN
> 0 && V_TIME
> 0) {
3184 if (tp
->t_msglen
>= (int)V_MIN
)
3185 vmin_satisfied(RD(q
),
3187 else if (tp
->t_msglen
)
3188 vmin_settimer(RD(q
));
3190 * Case 4: Read returns
3191 * whatever data is available
3194 } else { /* V_MIN == 0 && V_TIME == 0 */
3195 vmin_satisfied(RD(q
), tp
, 1);
3198 } else /* should do bufcall, really! */
3200 "ldtermwmsg: out of blocks");
3209 /* Pass it through unmolested. */
3216 * If our queue is nonempty or there's a traffic jam
3217 * downstream, this message must get in line.
3219 if (q
->q_first
!= NULL
|| !bcanputnext(q
, mp
->b_band
)) {
3221 * Exception: ioctls, except for those defined to
3222 * take effect after output has drained, should be
3223 * processed immediately.
3225 if (type
== M_IOCTL
) {
3226 struct iocblk
*iocp
;
3228 iocp
= (struct iocblk
*)mp
->b_rptr
;
3229 switch (iocp
->ioc_cmd
) {
3242 * Handle all others immediately.
3245 (void) ldtermwmsg(q
, mp
);
3253 * We can take the fast path through, by simply calling
3254 * ldtermwmsg to dispose of mp.
3256 (void) ldtermwmsg(q
, mp
);
3261 * Line discipline output queue service procedure.
3264 ldtermwsrv(queue_t
*q
)
3269 * We expect this loop to iterate at most once, but must be
3270 * prepared for more in case our upstream neighbor isn't
3271 * paying strict attention to what canput tells it.
3273 while ((mp
= getq(q
)) != NULL
) {
3275 * N.B.: ldtermwput has already handled high-priority
3276 * messages, so we don't have to worry about them
3277 * here. Hence, the putbq call is safe.
3279 if (!bcanputnext(q
, mp
->b_band
)) {
3280 (void) putbq(q
, mp
);
3283 if (!ldtermwmsg(q
, mp
)) {
3285 * Couldn't handle the whole thing; give up
3286 * for now and wait to be rescheduled.
3295 * Process the write-side message denoted by mp. If mp can't be
3296 * processed completely (due to allocation failures), put the
3297 * residual unprocessed part on the front of the write queue, disable
3298 * the queue, and schedule a qbufcall to arrange to complete its
3301 * Return 1 if the message was processed completely and 0 if not.
3303 * This routine is called from both ldtermwput and ldtermwsrv to do the
3304 * actual work of dealing with mp. ldtermwput will have already
3305 * dealt with high priority messages.
3308 ldtermwmsg(queue_t
*q
, mblk_t
*mp
)
3310 ldtermstd_state_t
*tp
;
3311 mblk_t
*residmp
= NULL
;
3314 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
3316 switch (mp
->b_datap
->db_type
) {
3319 ldterm_do_ioctl(q
, mp
);
3326 if ((tp
->t_modes
.c_lflag
& FLUSHO
) &&
3327 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
3328 freemsg(mp
); /* drop on floor */
3333 * Don't even look at the characters unless
3334 * we have something useful to do with them.
3336 if (((tp
->t_modes
.c_oflag
& OPOST
) ||
3337 ((tp
->t_modes
.c_lflag
& XCASE
) &&
3338 (tp
->t_modes
.c_lflag
& ICANON
))) &&
3339 (msgdsize(mp
) || !(tp
->t_state
& TS_ISPTSTTY
))) {
3340 unsigned char band
= mp
->b_band
;
3341 short flag
= mp
->b_flag
;
3343 residmp
= ldterm_output_msg(q
, mp
, &omp
,
3345 if ((mp
= omp
) == NULL
)
3350 /* Update sysinfo outch */
3351 (void) drv_setparm(SYSOUTC
, msgdsize(mp
));
3357 putnext(q
, mp
); /* pass it through unmolested */
3361 if (residmp
== NULL
)
3365 * An allocation failure occurred that prevented the message
3366 * from being completely processed. First, disable our
3367 * queue, since it's pointless to attempt further processing
3368 * until the allocation situation is resolved. (This must
3369 * precede the putbq call below, which would otherwise mark
3370 * the queue to be serviced.)
3374 * Stuff the remnant on our write queue so that we can
3375 * complete it later when times become less lean. Note that
3376 * this sets QFULL, so that our upstream neighbor will be
3377 * blocked by flow control.
3379 (void) putbq(q
, residmp
);
3381 * Schedule a qbufcall to re-enable the queue. The failure
3382 * won't have been for an allocation of more than OBSIZE
3383 * bytes, so don't ask for more than that from bufcall.
3385 size
= msgdsize(residmp
);
3389 qunbufcall(q
, tp
->t_wbufcid
);
3390 tp
->t_wbufcid
= qbufcall(q
, size
, BPRI_MED
, ldterm_wenable
, q
);
3397 * Perform output processing on a message, accumulating the output
3398 * characters in a new message.
3401 ldterm_output_msg(queue_t
*q
, mblk_t
*imp
, mblk_t
**omp
,
3402 ldtermstd_state_t
*tp
, size_t bsize
, int echoing
)
3404 mblk_t
*ibp
; /* block we're examining from input message */
3405 mblk_t
*obp
; /* block we're filling in output message */
3406 mblk_t
*cbp
; /* continuation block */
3407 mblk_t
*oobp
; /* old value of obp; valid if NEW_BLOCK fails */
3408 mblk_t
**contpp
; /* where to stuff ptr to newly-allocated blk */
3413 mblk_t
*bp
; /* block to stuff an M_DELAY message in */
3417 * Allocate a new block into which to put bytes. If we can't,
3418 * we just drop the rest of the message on the floor. If x is
3419 * non-zero, just fall thru; failure requires cleanup before
3423 #define NEW_BLOCK(x) \
3426 if ((obp = allocb(bsize, BPRI_MED)) == NULL) { \
3431 contpp = &obp->b_cont; \
3432 bytes_left = obp->b_datap->db_lim - obp->b_wptr; \
3439 * When we allocate the first block of a message, we should
3440 * stuff the pointer to it in "*omp". All subsequent blocks
3441 * should have the pointer to them stuffed into the "b_cont"
3442 * field of the previous block. "contpp" points to the place
3443 * where we should stuff the pointer.
3445 * If we already have a message we're filling in, continue doing
3448 if ((obp
= *omp
) != NULL
) {
3449 while (obp
->b_cont
!= NULL
)
3451 contpp
= &obp
->b_cont
;
3452 bytes_left
= obp
->b_datap
->db_lim
- obp
->b_wptr
;
3459 while (ibp
->b_rptr
< ibp
->b_wptr
) {
3461 * Make sure there's room for one more
3462 * character. At most, we'll need "t_maxeuc"
3465 if ((bytes_left
< (int)tp
->t_maxeuc
)) {
3470 * If doing XCASE processing (not very
3471 * likely, in this day and age), look at each
3472 * character individually.
3474 if ((tp
->t_modes
.c_lflag
& XCASE
) &&
3475 (tp
->t_modes
.c_lflag
& ICANON
)) {
3479 * We need to make sure that this is not
3480 * a following byte of a multibyte character
3481 * before applying an XCASE processing.
3483 * tp->t_eucign will be 0 if and only
3484 * if the current 'c' is an ASCII character
3485 * and also a byte. Otherwise, it will have
3486 * the byte length of a multibyte character.
3488 if ((tp
->t_state
& TS_MEUC
) &&
3489 tp
->t_eucign
== 0 && NOTASCII(c
)) {
3491 tp
->t_csmethods
.ldterm_memwidth(
3493 tp
->t_scratch_len
= tp
->t_eucign
;
3495 if (tp
->t_csdata
.codeset_type
!=
3496 LDTERM_CS_TYPE_UTF8
) {
3502 tp
->t_modes
.c_lflag
&
3508 * If character is mapped on output,
3509 * put out a backslash followed by
3510 * what it is mapped to.
3512 if (tp
->t_eucign
== 0 && omaptab
[c
] != 0 &&
3513 (!echoing
|| c
!= '\\')) {
3514 /* backslash is an ordinary character */
3516 *obp
->b_wptr
++ = '\\';
3518 if (bytes_left
== 0) {
3523 * Allocation failed, make
3524 * state consistent before
3536 * If no other output processing is
3537 * required, push the character into
3538 * the block and get another.
3540 if (!(tp
->t_modes
.c_oflag
& OPOST
)) {
3541 if (tp
->t_eucign
> 0) {
3551 * OPOST output flag is set. Map
3552 * lower case to upper case if OLCUC
3553 * flag is set and the 'c' is a lowercase
3556 if (tp
->t_eucign
== 0 &&
3557 (tp
->t_modes
.c_oflag
& OLCUC
) &&
3558 c
>= 'a' && c
<= 'z')
3562 * Copy all the ORDINARY characters,
3563 * possibly mapping upper case to
3564 * lower case. We use "movtuc",
3565 * STOPPING when we can't move some
3566 * character. For multi-byte or
3567 * multi-column EUC, we can't depend
3568 * on the regular tables. Rather than
3569 * just drop through to the "big
3570 * switch" for all characters, it
3571 * _might_ be faster to let "movtuc"
3572 * move a bunch of characters.
3573 * Chances are, even in multi-byte
3574 * mode we'll have lots of ASCII
3575 * going through. We check the flag
3576 * once, and call movtuc with the
3577 * appropriate table as an argument.
3579 * "movtuc will work for all codeset
3580 * types since it stops at the beginning
3581 * byte of a multibyte character.
3583 size_t bytes_to_move
;
3586 ASSERT(ibp
->b_wptr
>= ibp
->b_rptr
);
3587 bytes_to_move
= ibp
->b_wptr
- ibp
->b_rptr
;
3588 if (bytes_to_move
> bytes_left
)
3589 bytes_to_move
= bytes_left
;
3590 if (tp
->t_state
& TS_MEUC
) {
3591 bytes_moved
= movtuc(bytes_to_move
,
3592 ibp
->b_rptr
, obp
->b_wptr
,
3593 (tp
->t_modes
.c_oflag
& OLCUC
?
3594 elcuctab
: enotrantab
));
3596 bytes_moved
= movtuc(bytes_to_move
,
3597 ibp
->b_rptr
, obp
->b_wptr
,
3598 (tp
->t_modes
.c_oflag
& OLCUC
?
3599 lcuctab
: notrantab
));
3602 * We're save to just do this column
3603 * calculation, because if TS_MEUC is
3604 * set, we used the proper EUC
3605 * tables, and won't have copied any
3608 tp
->t_col
+= bytes_moved
;
3609 ibp
->b_rptr
+= bytes_moved
;
3610 obp
->b_wptr
+= bytes_moved
;
3611 bytes_left
-= bytes_moved
;
3612 if (ibp
->b_rptr
>= ibp
->b_wptr
)
3613 continue; /* moved all of block */
3614 if (bytes_left
== 0) {
3618 c
= *ibp
->b_rptr
++; /* stopper */
3622 * Again, we need to make sure that this is not
3623 * a following byte of a multibyte character at
3626 * 'tp->t_eucign' will be 0 iff the current 'c' is
3627 * an ASCII character. Otherwise, it will have
3628 * the byte length of a multibyte character.
3629 * We also add the display width to 'tp->t_col' if
3630 * the current codeset is not UTF-8 since this is
3631 * a leading byte of a multibyte character.
3632 * For UTF-8 codeset type, we add the display width
3633 * when we get the last byte of a character.
3635 if ((tp
->t_state
& TS_MEUC
) && tp
->t_eucign
== 0 &&
3637 tp
->t_eucign
= tp
->t_csmethods
.ldterm_memwidth(
3639 tp
->t_scratch_len
= tp
->t_eucign
;
3641 if (tp
->t_csdata
.codeset_type
!=
3642 LDTERM_CS_TYPE_UTF8
) {
3644 tp
->t_csmethods
.ldterm_dispwidth(c
,
3646 tp
->t_modes
.c_lflag
& ECHOCTL
);
3651 * If the driver has requested, don't process
3652 * output flags. However, if we're in
3653 * multi-byte mode, we HAVE to look at
3654 * EVERYTHING going out to maintain column
3655 * position properly. Therefore IF the driver
3656 * says don't AND we're not doing multi-byte,
3657 * then don't do it. Otherwise, do it.
3659 * NOTE: Hardware USUALLY doesn't expand tabs
3660 * properly for multi-byte situations anyway;
3661 * that's a known problem with the 3B2
3662 * "PORTS" board firmware, and any other
3663 * hardware that doesn't ACTUALLY know about
3664 * the current EUC mapping that WE are using
3665 * at this very moment. The problem is that
3666 * memory width is INDEPENDENT of screen
3667 * width - no relation - so WE know how wide
3668 * the characters are, but an off-the-host
3669 * board probably doesn't. So, until we're
3670 * SURE that the hardware below us can
3671 * correctly expand tabs in a
3672 * multi-byte/multi-column EUC situation, we
3676 * Map <CR>to<NL> on output if OCRNL flag
3677 * set. ONLCR processing is not done if OCRNL
3680 if (c
== '\r' && (tp
->t_modes
.c_oflag
& OCRNL
)) {
3686 if (tp
->t_csdata
.codeset_type
== LDTERM_CS_TYPE_EUC
) {
3690 * In other codeset types, we safely assume
3691 * any byte of a multibyte character will have
3692 * 'ORDINARY' type. For ASCII characters, we
3693 * still use the typetab[].
3695 if (tp
->t_eucign
== 0)
3702 * Map <NL> to <CR><NL> on output if ONLCR
3705 if (c
== '\n' && (tp
->t_modes
.c_oflag
& ONLCR
)) {
3706 if (!(tp
->t_state
& TS_TTCR
)) {
3707 tp
->t_state
|= TS_TTCR
;
3709 ctype
= typetab
['\r'];
3712 tp
->t_state
&= ~TS_TTCR
;
3715 * Delay values and column position
3716 * calculated here. For EUC chars in
3717 * multi-byte mode, we use "t_eucign" to help
3718 * calculate columns. When we see the first
3719 * byte of an EUC, we set t_eucign to the
3720 * number of bytes that will FOLLOW it, and
3721 * we add the screen width of the WHOLE EUC
3722 * character to the column position. In
3723 * particular, we can't count SS2 or SS3 as
3724 * printing characters. Remember, folks, the
3725 * screen width and memory width are
3726 * independent - no relation. We could have
3727 * dropped through for ASCII, but we want to
3728 * catch any bad characters (i.e., t_eucign
3729 * set and an ASCII char received) and
3730 * possibly report the garbage situation.
3740 if (tp
->t_state
& TS_MEUC
) {
3745 tp
->t_scratch
[tp
->t_scratch_len
3746 - tp
->t_eucign
] = c
;
3750 if (tp
->t_csdata
.codeset_type
3751 == LDTERM_CS_TYPE_UTF8
&&
3752 tp
->t_eucign
<= 0) {
3759 if (tp
->t_modes
.c_oflag
& OLCUC
)
3769 } else { /* ho hum, ASCII mode... */
3770 if (tp
->t_modes
.c_oflag
& OLCUC
)
3783 * If we're doing ECHOCTL, we've
3784 * already mapped the thing during
3785 * the process of canonising. Don't
3786 * bother here, as it's not one that
3795 * This is probably a backspace
3796 * received, not one that we're
3797 * echoing. Let it go as a
3798 * single-column backspace.
3803 if (tp
->t_modes
.c_oflag
& BSDLY
) {
3804 if (tp
->t_modes
.c_oflag
& OFILL
)
3812 if (tp
->t_modes
.c_oflag
& ONLRET
)
3814 if ((tp
->t_modes
.c_oflag
& NLDLY
) == NL1
)
3822 * Map '\t' to spaces if XTABS flag
3823 * is set. The calculation of
3824 * "t_eucign" has probably insured
3825 * that column will be correct, as we
3826 * bumped t_col by the DISP width,
3827 * not the memory width.
3829 if ((tp
->t_modes
.c_oflag
& TABDLY
) == XTABS
) {
3831 *obp
->b_wptr
++ = ' ';
3834 if ((tp
->t_col
& 07) == 0)
3835 break; /* every 8th */
3839 * expand this tab in
3846 obp
->b_datap
->db_lim
) {
3854 if (tp
->t_modes
.c_oflag
& OFILL
) {
3855 if (tp
->t_modes
.c_oflag
&
3859 switch (tp
->t_modes
.c_oflag
&
3866 count
= 1 + (tp
->t_col
|
3879 if ((tp
->t_modes
.c_oflag
& VTDLY
) &&
3880 !(tp
->t_modes
.c_oflag
& OFILL
))
3888 * Ignore <CR> in column 0 if ONOCR
3891 if (tp
->t_col
== 0 &&
3892 (tp
->t_modes
.c_oflag
& ONOCR
))
3896 switch (tp
->t_modes
.c_oflag
& CRDLY
) {
3899 if (tp
->t_modes
.c_oflag
& OFILL
)
3902 count
= tp
->t_col
% 2;
3906 if (tp
->t_modes
.c_oflag
& OFILL
)
3913 if (tp
->t_modes
.c_oflag
& OFILL
)
3926 if (tp
->t_modes
.c_oflag
& OFILL
) {
3928 if (bytes_left
== 0) {
3932 if (tp
->t_modes
.c_oflag
& OFDEL
)
3933 *obp
->b_wptr
++ = CDEL
;
3935 *obp
->b_wptr
++ = CNUL
;
3937 } while (--count
!= 0);
3939 if ((tp
->t_modes
.c_lflag
& FLUSHO
) &&
3940 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
3948 (void) drv_setparm(SYSOUTC
,
3956 allocb(1, BPRI_MED
)) !=
3958 bp
->b_datap
->db_type
=
3967 * We have to start a new
3968 * message; the delay
3969 * introduces a break between
3979 } while ((ibp
= cbp
) != NULL
); /* next block, if any */
3988 movtuc(size_t size
, unsigned char *from
, unsigned char *origto
,
3989 unsigned char *table
)
3991 unsigned char *to
= origto
;
3994 while (size
!= 0 && (c
= table
[*from
++]) != 0) {
3998 return (to
- origto
);
4002 ldterm_flush_output(uchar_t c
, queue_t
*q
, ldtermstd_state_t
*tp
)
4004 /* Already conditioned with IEXTEN during VDISCARD processing */
4005 if (tp
->t_modes
.c_lflag
& FLUSHO
)
4006 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
4008 flushq(q
, FLUSHDATA
); /* flush our write queue */
4009 /* flush ones below us */
4010 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
4011 if ((tp
->t_echomp
= allocb(EBSIZE
, BPRI_HI
)) != NULL
) {
4012 (void) ldterm_echo(c
, q
, 1, tp
);
4013 if (tp
->t_msglen
!= 0)
4014 ldterm_reprint(q
, EBSIZE
, tp
);
4015 if (tp
->t_echomp
!= NULL
) {
4016 putnext(q
, tp
->t_echomp
);
4017 tp
->t_echomp
= NULL
;
4020 tp
->t_modes
.c_lflag
|= FLUSHO
;
4026 * Signal generated by the reader: M_PCSIG and M_FLUSH messages sent.
4029 ldterm_dosig(queue_t
*q
, int sig
, uchar_t c
, int mtype
, int mode
)
4031 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4035 * c == \0 is brk case; need to flush on BRKINT even if
4038 if ((!(tp
->t_modes
.c_lflag
& NOFLSH
)) || (c
== '\0')) {
4040 if (tp
->t_state
& TS_TTSTOP
) {
4042 (void) putnextctl1(q
, mtype
, sig
);
4045 * Flush read or write side.
4046 * Restart the input or output.
4048 if (mode
& FLUSHR
) {
4049 flushq(q
, FLUSHDATA
);
4050 (void) putnextctl1(WR(q
), M_FLUSH
, mode
);
4051 if (tp
->t_state
& (TS_TBLOCK
|TS_IFBLOCK
)) {
4052 (void) putnextctl(WR(q
), M_STARTI
);
4053 tp
->t_state
&= ~(TS_TBLOCK
|TS_IFBLOCK
);
4056 if (mode
& FLUSHW
) {
4057 flushq(WR(q
), FLUSHDATA
);
4059 * XXX This is extremely gross.
4060 * Since we can't be sure our M_FLUSH
4061 * will have run its course by the
4062 * time we do the echo below, we set
4063 * state and toss it in the write put
4064 * routine to prevent flushing our
4065 * own data. Note that downstream
4066 * modules on the write side will be
4067 * flushed by the M_FLUSH sent above.
4069 tp
->t_state
|= TS_FLUSHWAIT
;
4070 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
4071 if (tp
->t_state
& TS_TTSTOP
) {
4072 (void) putnextctl(WR(q
), M_START
);
4073 tp
->t_state
&= ~(TS_TTSTOP
|TS_OFBLOCK
);
4078 tp
->t_state
&= ~TS_QUOT
;
4080 (void) putnextctl1(q
, mtype
, sig
);
4083 if ((tp
->t_echomp
= allocb(4, BPRI_HI
)) != NULL
) {
4084 if (ldterm_echo(c
, WR(q
), 4, tp
) > 0)
4085 putnext(WR(q
), tp
->t_echomp
);
4087 freemsg(tp
->t_echomp
);
4088 tp
->t_echomp
= NULL
;
4095 * Called when an M_IOCTL message is seen on the write queue; does
4096 * whatever we're supposed to do with it, and either replies
4097 * immediately or passes it to the next module down.
4100 ldterm_do_ioctl(queue_t
*q
, mblk_t
*mp
)
4102 ldtermstd_state_t
*tp
;
4103 struct iocblk
*iocp
;
4104 struct eucioc
*euciocp
; /* needed for EUC ioctls */
4105 ldterm_cs_data_user_t
*csdp
;
4109 uchar_t maxscreenlen
;
4112 iocp
= (struct iocblk
*)mp
->b_rptr
;
4113 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4115 switch (iocp
->ioc_cmd
) {
4122 * Set current parameters and special
4126 struct termios oldmodes
;
4128 error
= miocpullup(mp
, sizeof (struct termios
));
4130 miocnak(q
, mp
, 0, error
);
4134 cb
= (struct termios
*)mp
->b_cont
->b_rptr
;
4136 oldmodes
= tp
->t_amodes
;
4138 if ((tp
->t_amodes
.c_lflag
& PENDIN
) &&
4139 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
4141 * Yuk. The C shell file completion
4142 * code actually uses this "feature",
4143 * so we have to support it.
4145 if (tp
->t_message
!= NULL
) {
4146 tp
->t_state
|= TS_RESCAN
;
4149 tp
->t_amodes
.c_lflag
&= ~PENDIN
;
4151 bcopy(tp
->t_amodes
.c_cc
, tp
->t_modes
.c_cc
, NCCS
);
4154 * ldterm_adjust_modes does not deal with
4157 tp
->t_modes
.c_cflag
= tp
->t_amodes
.c_cflag
;
4159 ldterm_adjust_modes(tp
);
4160 if (chgstropts(&oldmodes
, tp
, RD(q
)) == (-1)) {
4161 miocnak(q
, mp
, 0, EAGAIN
);
4165 * The driver may want to know about the
4166 * following iflags: IGNBRK, BRKINT, IGNPAR,
4167 * PARMRK, INPCK, IXON, IXANY.
4177 * Old-style "ioctl" to set current
4178 * parameters and special characters. Don't
4179 * clear out the unset portions, leave them
4183 struct termios oldmodes
;
4185 error
= miocpullup(mp
, sizeof (struct termio
));
4187 miocnak(q
, mp
, 0, error
);
4191 cb
= (struct termio
*)mp
->b_cont
->b_rptr
;
4193 oldmodes
= tp
->t_amodes
;
4194 tp
->t_amodes
.c_iflag
=
4195 (tp
->t_amodes
.c_iflag
& 0xffff0000 | cb
->c_iflag
);
4196 tp
->t_amodes
.c_oflag
=
4197 (tp
->t_amodes
.c_oflag
& 0xffff0000 | cb
->c_oflag
);
4198 tp
->t_amodes
.c_cflag
=
4199 (tp
->t_amodes
.c_cflag
& 0xffff0000 | cb
->c_cflag
);
4200 tp
->t_amodes
.c_lflag
=
4201 (tp
->t_amodes
.c_lflag
& 0xffff0000 | cb
->c_lflag
);
4203 bcopy(cb
->c_cc
, tp
->t_modes
.c_cc
, NCC
);
4204 /* TCGETS returns amodes, so update that too */
4205 bcopy(cb
->c_cc
, tp
->t_amodes
.c_cc
, NCC
);
4207 /* ldterm_adjust_modes does not deal with cflags */
4209 tp
->t_modes
.c_cflag
= tp
->t_amodes
.c_cflag
;
4211 ldterm_adjust_modes(tp
);
4212 if (chgstropts(&oldmodes
, tp
, RD(q
)) == (-1)) {
4213 miocnak(q
, mp
, 0, EAGAIN
);
4217 * The driver may want to know about the
4218 * following iflags: IGNBRK, BRKINT, IGNPAR,
4219 * PARMRK, INPCK, IXON, IXANY.
4226 * Do the flush on the write queue immediately, and
4227 * queue up any flush on the read queue for the
4228 * service procedure to see. Then turn it into the
4229 * appropriate M_FLUSH message, so that the module
4230 * below us doesn't have to know about TCFLSH.
4232 error
= miocpullup(mp
, sizeof (int));
4234 miocnak(q
, mp
, 0, error
);
4238 ASSERT(mp
->b_datap
!= NULL
);
4239 if (*(int *)mp
->b_cont
->b_rptr
== 0) {
4240 ASSERT(mp
->b_datap
!= NULL
);
4241 (void) putnextctl1(q
, M_FLUSH
, FLUSHR
);
4242 (void) putctl1(RD(q
), M_FLUSH
, FLUSHR
);
4243 } else if (*(int *)mp
->b_cont
->b_rptr
== 1) {
4244 flushq(q
, FLUSHDATA
);
4245 ASSERT(mp
->b_datap
!= NULL
);
4246 tp
->t_state
|= TS_FLUSHWAIT
;
4247 (void) putnextctl1(RD(q
), M_FLUSH
, FLUSHW
);
4248 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
4249 } else if (*(int *)mp
->b_cont
->b_rptr
== 2) {
4250 flushq(q
, FLUSHDATA
);
4251 ASSERT(mp
->b_datap
!= NULL
);
4252 (void) putnextctl1(q
, M_FLUSH
, FLUSHRW
);
4253 tp
->t_state
|= TS_FLUSHWAIT
;
4254 (void) putnextctl1(RD(q
), M_FLUSH
, FLUSHRW
);
4256 miocnak(q
, mp
, 0, EINVAL
);
4259 ASSERT(mp
->b_datap
!= NULL
);
4261 miocack(q
, mp
, 0, 0);
4265 error
= miocpullup(mp
, sizeof (int));
4267 miocnak(q
, mp
, 0, error
);
4271 switch (*(int *)mp
->b_cont
->b_rptr
) {
4273 if (!(tp
->t_state
& TS_TTSTOP
)) {
4274 (void) putnextctl(q
, M_STOP
);
4275 tp
->t_state
|= (TS_TTSTOP
|TS_OFBLOCK
);
4280 if (tp
->t_state
& TS_TTSTOP
) {
4281 (void) putnextctl(q
, M_START
);
4282 tp
->t_state
&= ~(TS_TTSTOP
|TS_OFBLOCK
);
4287 (void) putnextctl(q
, M_STOPI
);
4288 tp
->t_state
|= (TS_TBLOCK
|TS_IFBLOCK
);
4292 (void) putnextctl(q
, M_STARTI
);
4293 tp
->t_state
&= ~(TS_TBLOCK
|TS_IFBLOCK
);
4297 miocnak(q
, mp
, 0, EINVAL
);
4300 ASSERT(mp
->b_datap
!= NULL
);
4302 miocack(q
, mp
, 0, 0);
4305 * TCSBRK is expected to be handled by the driver.
4306 * The reason its left for the driver is that when
4307 * the argument to TCSBRK is zero driver has to drain
4308 * the data and sending a M_IOCACK from LDTERM before
4309 * the driver drains the data is going to cause
4314 * The following are EUC related ioctls. For
4315 * EUC_WSET, we have to pass the information on, even
4316 * though we ACK the call. It's vital in the EUC
4317 * environment that everybody downstream knows about
4318 * the EUC codeset widths currently in use; we
4319 * therefore pass down the information in an M_CTL
4320 * message. It will bottom out in the driver.
4325 /* only needed for EUC_WSET */
4326 struct iocblk
*riocp
;
4328 mblk_t
*dmp
, *dmp_cont
;
4331 * If the user didn't supply any information,
4334 error
= miocpullup(mp
, sizeof (struct eucioc
));
4336 miocnak(q
, mp
, 0, error
);
4340 euciocp
= (struct eucioc
*)mp
->b_cont
->b_rptr
;
4342 * Check here for something reasonable. If
4343 * anything will take more than EUC_MAXW
4344 * columns or more than EUC_MAXW bytes
4345 * following SS2 or SS3, then just reject it
4346 * out of hand. It's not impossible for us to
4347 * do it, it just isn't reasonable. So far,
4348 * in the world, we've seen the absolute max
4349 * columns to be 2 and the max number of
4350 * bytes to be 3. This allows room for some
4351 * expansion of that, but it probably won't
4352 * even be necessary. At the moment, we
4353 * return a "range" error. If you really
4354 * need to, you can push EUC_MAXW up to over
4355 * 200; it doesn't make sense, though, with
4356 * only a CANBSIZ sized input limit (usually
4359 for (i
= 0; i
< 4; i
++) {
4360 if ((euciocp
->eucw
[i
] > EUC_MAXW
) ||
4361 (euciocp
->scrw
[i
] > EUC_MAXW
)) {
4362 miocnak(q
, mp
, 0, ERANGE
);
4367 * Otherwise, save the information in tp,
4368 * force codeset 0 (ASCII) to be one byte,
4371 cp_eucwioc(euciocp
, &tp
->eucwioc
, EUCIN
);
4372 tp
->eucwioc
.eucw
[0] = tp
->eucwioc
.scrw
[0] = 1;
4374 * Now, check out whether we're doing
4375 * multibyte processing. if we are, we need
4376 * to allocate a block to hold the parallel
4377 * array. By convention, we've been passed
4378 * what amounts to a CSWIDTH definition. We
4379 * actually NEED the number of bytes for
4382 tp
->t_maxeuc
= 0; /* reset to say we're NOT */
4384 tp
->t_state
&= ~TS_MEUC
;
4386 * We'll set TS_MEUC if we're doing
4387 * multi-column OR multi- byte OR both. It
4388 * makes things easier... NOTE: If we fail
4389 * to get the buffer we need to hold display
4390 * widths, then DON'T let the TS_MEUC bit get
4393 for (i
= 0; i
< 4; i
++) {
4394 if (tp
->eucwioc
.eucw
[i
] > tp
->t_maxeuc
)
4395 tp
->t_maxeuc
= tp
->eucwioc
.eucw
[i
];
4396 if (tp
->eucwioc
.scrw
[i
] > 1)
4397 tp
->t_state
|= TS_MEUC
;
4399 if ((tp
->t_maxeuc
> 1) || (tp
->t_state
& TS_MEUC
)) {
4400 if (!tp
->t_eucp_mp
) {
4401 if ((tp
->t_eucp_mp
= allocb(_TTY_BUFSIZ
,
4402 BPRI_HI
)) == NULL
) {
4404 tp
->t_state
&= ~TS_MEUC
;
4406 "Can't allocate eucp_mp");
4407 miocnak(q
, mp
, 0, ENOSR
);
4411 * here, if there's junk in
4412 * the canonical buffer, then
4413 * move the eucp pointer past
4414 * it, so we don't run off
4415 * the beginning. This is a
4416 * total botch, but will
4417 * hopefully keep stuff from
4418 * getting too messed up
4419 * until the user flushes
4424 tp
->t_eucp_mp
->b_rptr
;
4425 for (i
= tp
->t_msglen
; i
; i
--)
4429 tp
->t_eucp_mp
->b_rptr
;
4432 /* doing multi-byte handling */
4433 tp
->t_state
|= TS_MEUC
;
4435 } else if (tp
->t_eucp_mp
) {
4436 freemsg(tp
->t_eucp_mp
);
4437 tp
->t_eucp_mp
= NULL
;
4442 * Save the EUC width data we have at
4443 * the t_csdata, set t_csdata.codeset_type to
4444 * EUC one, and, switch the codeset methods at
4447 bzero(&tp
->t_csdata
.eucpc_data
,
4448 (sizeof (ldterm_eucpc_data_t
) *
4449 LDTERM_CS_MAX_CODESETS
));
4450 tp
->t_csdata
.eucpc_data
[0].byte_length
=
4451 tp
->eucwioc
.eucw
[1];
4452 tp
->t_csdata
.eucpc_data
[0].screen_width
=
4453 tp
->eucwioc
.scrw
[1];
4454 tp
->t_csdata
.eucpc_data
[1].byte_length
=
4455 tp
->eucwioc
.eucw
[2];
4456 tp
->t_csdata
.eucpc_data
[1].screen_width
=
4457 tp
->eucwioc
.scrw
[2];
4458 tp
->t_csdata
.eucpc_data
[2].byte_length
=
4459 tp
->eucwioc
.eucw
[3];
4460 tp
->t_csdata
.eucpc_data
[2].screen_width
=
4461 tp
->eucwioc
.scrw
[3];
4462 tp
->t_csdata
.version
= LDTERM_DATA_VERSION
;
4463 tp
->t_csdata
.codeset_type
= LDTERM_CS_TYPE_EUC
;
4465 * We are not using the 'csinfo_num' anyway if the
4466 * current codeset type is EUC. So, set it to
4467 * the maximum possible.
4469 tp
->t_csdata
.csinfo_num
=
4470 LDTERM_CS_TYPE_EUC_MAX_SUBCS
;
4471 if (tp
->t_csdata
.locale_name
!= NULL
) {
4472 kmem_free(tp
->t_csdata
.locale_name
,
4473 strlen(tp
->t_csdata
.locale_name
) + 1);
4474 tp
->t_csdata
.locale_name
= NULL
;
4476 tp
->t_csmethods
= cs_methods
[LDTERM_CS_TYPE_EUC
];
4479 * If we are able to allocate two blocks (the
4480 * iocblk and the associated data), then pass
4481 * it downstream, otherwise we'll need to NAK
4482 * it, and drop whatever we WERE able to
4485 if ((dmp
= mkiocb(EUC_WSET
)) == NULL
) {
4486 miocnak(q
, mp
, 0, ENOSR
);
4489 if ((dmp_cont
= allocb(EUCSIZE
, BPRI_HI
)) == NULL
) {
4491 miocnak(q
, mp
, 0, ENOSR
);
4496 * We got both buffers. Copy out the EUC
4497 * information (as we received it, not what
4498 * we're using!) & pass it on.
4500 bcopy(mp
->b_cont
->b_rptr
, dmp_cont
->b_rptr
, EUCSIZE
);
4501 dmp_cont
->b_wptr
+= EUCSIZE
;
4502 dmp
->b_cont
= dmp_cont
;
4503 dmp
->b_datap
->db_type
= M_CTL
;
4504 dmp_cont
->b_datap
->db_type
= M_DATA
;
4505 riocp
= (struct iocblk
*)dmp
->b_rptr
;
4506 riocp
->ioc_count
= EUCSIZE
;
4510 * Now ACK the ioctl.
4513 miocack(q
, mp
, 0, 0);
4518 error
= miocpullup(mp
, sizeof (struct eucioc
));
4520 miocnak(q
, mp
, 0, error
);
4523 euciocp
= (struct eucioc
*)mp
->b_cont
->b_rptr
;
4524 cp_eucwioc(&tp
->eucwioc
, euciocp
, EUCOUT
);
4526 miocack(q
, mp
, EUCSIZE
, 0);
4530 error
= miocpullup(mp
, sizeof (ldterm_cs_data_user_t
));
4532 miocnak(q
, mp
, 0, error
);
4536 csdp
= (ldterm_cs_data_user_t
*)mp
->b_cont
->b_rptr
;
4538 /* Validate the codeset data provided. */
4539 if (csdp
->version
> LDTERM_DATA_VERSION
||
4540 csdp
->codeset_type
< LDTERM_CS_TYPE_MIN
||
4541 csdp
->codeset_type
> LDTERM_CS_TYPE_MAX
) {
4542 miocnak(q
, mp
, 0, ERANGE
);
4546 if ((csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
&&
4547 csdp
->csinfo_num
> LDTERM_CS_TYPE_EUC_MAX_SUBCS
) ||
4548 (csdp
->codeset_type
== LDTERM_CS_TYPE_PCCS
&&
4549 (csdp
->csinfo_num
< LDTERM_CS_TYPE_PCCS_MIN_SUBCS
||
4550 csdp
->csinfo_num
> LDTERM_CS_TYPE_PCCS_MAX_SUBCS
))) {
4551 miocnak(q
, mp
, 0, ERANGE
);
4555 maxbytelen
= maxscreenlen
= 0;
4556 if (csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
) {
4557 for (i
= 0; i
< LDTERM_CS_TYPE_EUC_MAX_SUBCS
; i
++) {
4558 if (csdp
->eucpc_data
[i
].byte_length
>
4560 csdp
->eucpc_data
[i
].screen_width
>
4562 miocnak(q
, mp
, 0, ERANGE
);
4566 if (csdp
->eucpc_data
[i
].byte_length
>
4569 csdp
->eucpc_data
[i
].byte_length
;
4570 if (csdp
->eucpc_data
[i
].screen_width
>
4573 csdp
->eucpc_data
[i
].screen_width
;
4575 /* POSIX/C locale? */
4576 if (maxbytelen
== 0 && maxscreenlen
== 0)
4577 maxbytelen
= maxscreenlen
= 1;
4578 } else if (csdp
->codeset_type
== LDTERM_CS_TYPE_PCCS
) {
4579 for (i
= 0; i
< LDTERM_CS_MAX_CODESETS
; i
++) {
4580 if (csdp
->eucpc_data
[i
].byte_length
>
4581 LDTERM_CS_MAX_BYTE_LENGTH
) {
4582 miocnak(q
, mp
, 0, ERANGE
);
4585 if (csdp
->eucpc_data
[i
].byte_length
>
4588 csdp
->eucpc_data
[i
].byte_length
;
4589 if (csdp
->eucpc_data
[i
].screen_width
>
4592 csdp
->eucpc_data
[i
].screen_width
;
4594 } else if (csdp
->codeset_type
== LDTERM_CS_TYPE_UTF8
) {
4600 if (csdp
->locale_name
) {
4601 for (i
= 0; i
< MAXNAMELEN
; i
++)
4602 if (csdp
->locale_name
[i
] == '\0')
4605 * We cannot have any string that is not NULL byte
4608 if (i
>= MAXNAMELEN
) {
4609 miocnak(q
, mp
, 0, ERANGE
);
4613 locale_name_sz
= i
+ 1;
4617 * As the final check, if there was invalid codeset_type
4618 * given, or invalid byte_length was specified, it's an error.
4620 if (maxbytelen
<= 0 || maxscreenlen
<= 0) {
4621 miocnak(q
, mp
, 0, ERANGE
);
4625 /* Do the switching. */
4626 tp
->t_maxeuc
= maxbytelen
;
4627 tp
->t_state
&= ~TS_MEUC
;
4628 if (maxbytelen
> 1 || maxscreenlen
> 1) {
4629 if (!tp
->t_eucp_mp
) {
4630 if (!(tp
->t_eucp_mp
= allocb(_TTY_BUFSIZ
,
4633 "Can't allocate eucp_mp");
4634 miocnak(q
, mp
, 0, ENOSR
);
4638 * If there's junk in the canonical buffer,
4639 * then move the eucp pointer past it,
4640 * so we don't run off the beginning. This is
4641 * a total botch, but will hopefully keep
4642 * stuff from getting too messed up until
4643 * the user flushes this line!
4646 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
4647 for (i
= tp
->t_msglen
; i
; i
--)
4650 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
4655 * We only set TS_MEUC for a multibyte/multi-column
4658 tp
->t_state
|= TS_MEUC
;
4660 tp
->t_csdata
.version
= csdp
->version
;
4661 tp
->t_csdata
.codeset_type
= csdp
->codeset_type
;
4662 tp
->t_csdata
.csinfo_num
= csdp
->csinfo_num
;
4663 bcopy(csdp
->eucpc_data
, tp
->t_csdata
.eucpc_data
,
4664 sizeof (ldterm_eucpc_data_t
) *
4665 LDTERM_CS_MAX_CODESETS
);
4666 tp
->t_csmethods
= cs_methods
[csdp
->codeset_type
];
4668 if (csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
) {
4669 tp
->eucwioc
.eucw
[0] = 1;
4670 tp
->eucwioc
.scrw
[0] = 1;
4672 tp
->eucwioc
.eucw
[1] =
4673 csdp
->eucpc_data
[0].byte_length
;
4674 tp
->eucwioc
.scrw
[1] =
4675 csdp
->eucpc_data
[0].screen_width
;
4677 tp
->eucwioc
.eucw
[2] =
4678 csdp
->eucpc_data
[1].byte_length
+ 1;
4679 tp
->eucwioc
.scrw
[2] =
4680 csdp
->eucpc_data
[1].screen_width
;
4682 tp
->eucwioc
.eucw
[3] =
4683 csdp
->eucpc_data
[2].byte_length
+ 1;
4684 tp
->eucwioc
.scrw
[3] =
4685 csdp
->eucpc_data
[2].screen_width
;
4688 * We are not going to use this data
4689 * structure. So, clear it. Also, stty(1) will
4690 * make use of the cleared tp->eucwioc when
4691 * it prints out codeset width setting.
4693 bzero(&tp
->eucwioc
, EUCSIZE
);
4697 * If this codeset is a single byte codeset that
4698 * requires only single display column for all
4699 * characters, we switch to default EUC codeset
4700 * methods and data setting.
4703 if (tp
->t_eucp_mp
) {
4704 freemsg(tp
->t_eucp_mp
);
4705 tp
->t_eucp_mp
= NULL
;
4709 bzero(&tp
->eucwioc
, EUCSIZE
);
4710 tp
->eucwioc
.eucw
[0] = 1;
4711 tp
->eucwioc
.scrw
[0] = 1;
4712 if (tp
->t_csdata
.locale_name
!= NULL
) {
4713 kmem_free(tp
->t_csdata
.locale_name
,
4714 strlen(tp
->t_csdata
.locale_name
) + 1);
4716 tp
->t_csdata
= default_cs_data
;
4717 tp
->t_csmethods
= cs_methods
[LDTERM_CS_TYPE_EUC
];
4720 /* Copy over locale_name. */
4721 if (tp
->t_csdata
.locale_name
!= NULL
) {
4722 kmem_free(tp
->t_csdata
.locale_name
,
4723 strlen(tp
->t_csdata
.locale_name
) + 1);
4725 if (locale_name_sz
> 1) {
4726 tp
->t_csdata
.locale_name
= kmem_alloc(
4727 locale_name_sz
, KM_SLEEP
);
4728 (void) strcpy(tp
->t_csdata
.locale_name
,
4731 tp
->t_csdata
.locale_name
= NULL
;
4735 * Now ACK the ioctl.
4738 miocack(q
, mp
, 0, 0);
4742 error
= miocpullup(mp
, sizeof (ldterm_cs_data_user_t
));
4744 miocnak(q
, mp
, 0, error
);
4748 csdp
= (ldterm_cs_data_user_t
*)mp
->b_cont
->b_rptr
;
4750 csdp
->version
= tp
->t_csdata
.version
;
4751 csdp
->codeset_type
= tp
->t_csdata
.codeset_type
;
4752 csdp
->csinfo_num
= tp
->t_csdata
.csinfo_num
;
4753 csdp
->pad
= tp
->t_csdata
.pad
;
4754 if (tp
->t_csdata
.locale_name
) {
4755 (void) strcpy(csdp
->locale_name
,
4756 tp
->t_csdata
.locale_name
);
4758 csdp
->locale_name
[0] = '\0';
4760 bcopy(tp
->t_csdata
.eucpc_data
, csdp
->eucpc_data
,
4761 sizeof (ldterm_eucpc_data_t
) * LDTERM_CS_MAX_CODESETS
);
4763 * If the codeset is an EUC codeset and if it has 2nd and/or
4764 * 3rd supplementary codesets, we subtract one from each
4765 * byte length of the supplementary codesets. This is
4766 * because single shift characters, SS2 and SS3, are not
4767 * included in the byte lengths in the user space.
4769 if (csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
) {
4770 if (csdp
->eucpc_data
[1].byte_length
)
4771 csdp
->eucpc_data
[1].byte_length
-= 1;
4772 if (csdp
->eucpc_data
[2].byte_length
)
4773 csdp
->eucpc_data
[2].byte_length
-= 1;
4776 miocack(q
, mp
, sizeof (ldterm_cs_data_user_t
), 0);
4780 tp
->t_state
|= TS_ISPTSTTY
;
4790 * Send an M_SETOPTS message upstream if any mode changes are being
4791 * made that affect the stream head options. returns -1 if allocb
4792 * fails, else returns 0.
4795 chgstropts(struct termios
*oldmodep
, ldtermstd_state_t
*tp
, queue_t
*q
)
4797 struct stroptions optbuf
;
4800 optbuf
.so_flags
= 0;
4801 if ((oldmodep
->c_lflag
^ tp
->t_modes
.c_lflag
) & ICANON
) {
4803 * Canonical mode is changing state; switch the
4804 * stream head to message-nondiscard or byte-stream
4805 * mode. Also, rerun the service procedure so it can
4806 * change its mind about whether to send data
4809 if (tp
->t_modes
.c_lflag
& ICANON
) {
4810 DEBUG4(("CHANGING TO CANON MODE\n"));
4811 optbuf
.so_flags
= SO_READOPT
|SO_MREADOFF
;
4812 optbuf
.so_readopt
= RMSGN
;
4815 * if there is a pending raw mode timeout,
4820 * Clear VMIN/VTIME state, cancel timers
4822 vmin_satisfied(q
, tp
, 0);
4824 DEBUG4(("CHANGING TO RAW MODE\n"));
4825 optbuf
.so_flags
= SO_READOPT
|SO_MREADON
;
4826 optbuf
.so_readopt
= RNORM
;
4829 if ((oldmodep
->c_lflag
^ tp
->t_modes
.c_lflag
) & TOSTOP
) {
4831 * The "stop on background write" bit is changing.
4833 if (tp
->t_modes
.c_lflag
& TOSTOP
)
4834 optbuf
.so_flags
|= SO_TOSTOP
;
4836 optbuf
.so_flags
|= SO_TONSTOP
;
4838 if (optbuf
.so_flags
!= 0) {
4839 if ((bp
= allocb(sizeof (struct stroptions
), BPRI_HI
)) ==
4843 *(struct stroptions
*)bp
->b_wptr
= optbuf
;
4844 bp
->b_wptr
+= sizeof (struct stroptions
);
4845 bp
->b_datap
->db_type
= M_SETOPTS
;
4846 DEBUG4(("M_SETOPTS to stream head\n"));
4854 * Called when an M_IOCACK message is seen on the read queue;
4855 * modifies the data being returned, if necessary, and passes the
4859 ldterm_ioctl_reply(queue_t
*q
, mblk_t
*mp
)
4861 ldtermstd_state_t
*tp
;
4862 struct iocblk
*iocp
;
4864 iocp
= (struct iocblk
*)mp
->b_rptr
;
4865 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4867 switch (iocp
->ioc_cmd
) {
4872 * Get current parameters and return them to
4873 * stream head eventually.
4875 struct termios
*cb
=
4876 (struct termios
*)mp
->b_cont
->b_rptr
;
4879 * cflag has cflags sent upstream by the
4882 tcflag_t cflag
= cb
->c_cflag
;
4886 cb
->c_cflag
= cflag
; /* set by driver */
4893 * Old-style "ioctl" to get current
4894 * parameters and return them to stream head
4898 (struct termio
*)mp
->b_cont
->b_rptr
;
4900 cb
->c_iflag
= tp
->t_amodes
.c_iflag
; /* all except the */
4901 cb
->c_oflag
= tp
->t_amodes
.c_oflag
; /* cb->c_cflag */
4902 cb
->c_lflag
= tp
->t_amodes
.c_lflag
;
4904 if (cb
->c_cflag
== 0) /* not set by driver */
4905 cb
->c_cflag
= tp
->t_amodes
.c_cflag
;
4908 bcopy(tp
->t_amodes
.c_cc
, cb
->c_cc
, NCC
);
4917 * A VMIN/VTIME request has been satisfied. Cancel outstanding timers
4918 * if they exist, clear TS_MREAD state, and send upstream. If a NULL
4919 * queue ptr is passed, just reset VMIN/VTIME state.
4922 vmin_satisfied(queue_t
*q
, ldtermstd_state_t
*tp
, int sendup
)
4925 if (tp
->t_vtid
!= 0) {
4926 DEBUG4(("vmin_satisfied: cancelled timer id %d\n", tp
->t_vtid
));
4927 (void) quntimeout(q
, tp
->t_vtid
);
4931 if (tp
->t_msglen
== 0 && V_MIN
) {
4933 DEBUG4(("vmin_satisfied: data swiped, msglen = 0\n"));
4935 if ((!q
->q_first
) ||
4936 (q
->q_first
->b_datap
->db_type
!= M_DATA
) ||
4937 (tp
->t_msglen
>= LDCHUNK
)) {
4938 ldterm_msg_upstream(q
, tp
);
4939 DEBUG4(("vmin_satisfied: delivering data\n"));
4944 DEBUG4(("vmin_satisfied: VMIN/TIME state reset\n"));
4946 tp
->t_state
&= ~TS_MREAD
;
4950 vmin_settimer(queue_t
*q
)
4952 ldtermstd_state_t
*tp
;
4954 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4957 * Don't start any time bombs.
4959 if (tp
->t_state
& TS_CLOSE
)
4963 * tp->t_vtid should NOT be set here unless VMIN > 0 and
4967 if (V_MIN
&& V_TIME
) {
4969 DEBUG4(("vmin_settimer: timer restarted, old tid=%d\n",
4973 DEBUG4(("vmin_settimer: tid = %d was still active!\n",
4976 (void) quntimeout(q
, tp
->t_vtid
);
4979 tp
->t_vtid
= qtimeout(q
, vmin_timed_out
, q
,
4980 (clock_t)(V_TIME
* (hz
/ 10)));
4981 DEBUG4(("vmin_settimer: timer started, tid = %d\n", tp
->t_vtid
));
4986 * BRRrrringgg!! VTIME was satisfied instead of VMIN
4989 vmin_timed_out(void *arg
)
4992 ldtermstd_state_t
*tp
;
4994 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4996 DEBUG4(("vmin_timed_out: tid = %d\n", tp
->t_vtid
));
4997 /* don't call untimeout now that we are in the timeout */
4999 vmin_satisfied(q
, tp
, 1);
5004 * Routine to adjust termios flags to be processed by the line
5005 * discipline. Driver below sends a termios structure, with the flags
5006 * the driver intends to process. XOR'ing the driver sent termios
5007 * structure with current termios structure with the default values
5008 * (or set by ioctls from userland), we come up with a new termios
5009 * structrue, the flags of which will be used by the line discipline
5010 * in processing input and output. On return from this routine, we
5011 * will have the following fields set in tp structure -->
5012 * tp->t_modes: modes the line discipline will process tp->t_amodes:
5013 * modes the user process thinks the line discipline is processing
5017 ldterm_adjust_modes(ldtermstd_state_t
*tp
)
5020 DEBUG6(("original iflag = %o\n", tp
->t_modes
.c_iflag
));
5021 tp
->t_modes
.c_iflag
= tp
->t_amodes
.c_iflag
& ~(tp
->t_dmodes
.c_iflag
);
5022 tp
->t_modes
.c_oflag
= tp
->t_amodes
.c_oflag
& ~(tp
->t_dmodes
.c_oflag
);
5023 tp
->t_modes
.c_lflag
= tp
->t_amodes
.c_lflag
& ~(tp
->t_dmodes
.c_lflag
);
5024 DEBUG6(("driver iflag = %o\n", tp
->t_dmodes
.c_iflag
));
5025 DEBUG6(("apparent iflag = %o\n", tp
->t_amodes
.c_iflag
));
5026 DEBUG6(("effective iflag = %o\n", tp
->t_modes
.c_iflag
));
5028 /* No negotiation of clfags c_cc array special characters */
5030 * Copy from amodes to modes already done by TCSETA/TCSETS
5037 * Erase one multi-byte character. If TS_MEUC is set AND this
5038 * is a multi-byte character, then this should be called instead of
5039 * ldterm_erase. "ldterm_erase" will handle ASCII nicely, thank you.
5041 * We'd better be pointing to the last byte. If we aren't, it will get
5045 ldterm_csi_erase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
5048 uchar_t
*p
, *bottom
;
5049 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
5054 if (tp
->t_eucleft
) {
5055 /* XXX Ick. We're in the middle of an EUC! */
5056 /* What to do now? */
5058 return; /* ignore it??? */
5060 bottom
= tp
->t_eucp_mp
->b_rptr
;
5061 p
= tp
->t_eucp
- 1; /* previous byte */
5064 ung
= 1; /* number of bytes to un-get from buffer */
5066 * go through the buffer until we find the beginning of the
5069 while ((*p
== 0) && (p
> bottom
)) {
5075 * Now, "ung" is the number of bytes to unget from the buffer
5076 * and "*p" is the disp width of it. Fool "ldterm_rubout"
5077 * into thinking we're rubbing out ASCII characters. Do that
5078 * for the display width of the character.
5080 * Also we accumulate bytes of the character so that if the character
5081 * is a UTF-8 character, we will get the display width of the UTF-8
5084 if (ung
>= LDTERM_CS_MAX_BYTE_LENGTH
) {
5085 j
= len
= LDTERM_CS_MAX_BYTE_LENGTH
;
5089 for (i
= 0; i
< ung
; i
++) { /* remove from buf */
5090 if ((c
= ldterm_unget(tp
)) != (-1)) {
5093 u8
[--j
] = (uchar_t
)c
;
5096 if (*p
== UNKNOWN_WIDTH
) {
5097 if (tp
->t_csdata
.codeset_type
== LDTERM_CS_TYPE_UTF8
) {
5098 *p
= ldterm_utf8_width(u8
, len
);
5103 for (i
= 0; i
< (int)*p
; i
++) /* remove from screen */
5104 ldterm_rubout(' ', q
, ebsize
, tp
);
5106 * Adjust the parallel array pointer. Zero out the contents
5107 * of parallel array for this position, just to make sure...
5115 * This is kind of a safety valve. Whenever we see a bad sequence
5116 * come up, we call eucwarn. It just tallies the junk until a
5117 * threshold is reached. Then it prints ONE message on the console
5118 * and not any more. Hopefully, we can catch garbage; maybe it will
5119 * be useful to somebody.
5122 ldterm_eucwarn(ldtermstd_state_t
*tp
)
5126 if ((tp
->t_eucwarn
> EUC_WARNCNT
) && !(tp
->t_state
& TS_WARNED
)) {
5128 "ldterm: tty at addr %p in multi-byte mode --",
5131 "Over %d bad EUC characters this session", EUC_WARNCNT
);
5132 tp
->t_state
|= TS_WARNED
;
5139 * Copy an "eucioc_t" structure. We use the structure with
5140 * incremented values for Codesets 2 & 3. The specification in
5141 * eucioctl is that the sames values as the CSWIDTH definition at
5142 * user level are passed to us. When we copy it "in" to ourselves, we
5143 * do the increment. That allows us to avoid treating each character
5144 * set separately for "t_eucleft" purposes. When we copy it "out" to
5145 * return it to the user, we decrement the values so the user gets
5146 * what it expects, and it matches CSWIDTH in the environment (if
5147 * things are consistent!).
5150 cp_eucwioc(eucioc_t
*from
, eucioc_t
*to
, int dir
)
5152 bcopy(from
, to
, EUCSIZE
);
5153 if (dir
== EUCOUT
) { /* copying out to user */
5158 } else { /* copying in */
5168 * Take the first byte of a multi-byte, or an ASCII char. Return its
5169 * codeset. If it's NOT the first byte of an EUC, then the return
5170 * value may be garbage, as it's probably not SS2 or SS3, and
5171 * therefore must be in codeset 1. Another bizarre catch here is the
5172 * fact that we don't do anything about the "C1" control codes. In
5173 * real life, we should; but nobody's come up with a good way of
5178 ldterm_codeset(uchar_t codeset_type
, uchar_t c
)
5184 if (codeset_type
!= LDTERM_CS_TYPE_EUC
)
5197 /* The following two functions are additional EUC codeset specific methods. */
5199 * ldterm_dispwidth - Take the first byte of an EUC (or ASCII) and
5200 * return the display width. Since this is intended mostly for
5201 * multi-byte handling, it returns EUC_TWIDTH for tabs so they can be
5202 * differentiated from EUC characters (assumption: EUC require fewer
5203 * than 255 columns). Also, if it's a backspace and !flag, it
5204 * returns EUC_BSWIDTH. Newline & CR also depend on flag. This
5205 * routine SHOULD be cleaner than this, but we have the situation
5206 * where we may or may not be counting control characters as having a
5207 * column width. Therefore, the computation of ASCII is pretty messy.
5208 * The caller will be storing the value, and then switching on it
5209 * when it's used. We really should define the EUC_TWIDTH and other
5210 * constants in a header so that the routine could be used in other
5211 * modules in the kernel.
5214 __ldterm_dispwidth_euc(uchar_t c
, void *p
, int mode
)
5216 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5222 return (EUC_TWIDTH
);
5224 return (mode
? 2 : EUC_BSWIDTH
);
5226 return (EUC_NLWIDTH
);
5228 return (mode
? 2 : EUC_CRWIDTH
);
5230 return (mode
? 2 : 0);
5237 return (tp
->eucwioc
.scrw
[2]);
5239 return (tp
->eucwioc
.scrw
[3]);
5241 return (tp
->eucwioc
.scrw
[1]);
5246 * ldterm_memwidth_euc - Take the first byte of an EUC (or an ASCII char)
5247 * and return its memory width. The routine could have been
5248 * implemented to use only the codeset number, but that would require
5249 * the caller to have that value available. Perhaps the user doesn't
5250 * want to make the extra call or keep the value of codeset around.
5251 * Therefore, we use the actual character with which they're
5252 * concerned. This should never be called with anything but the
5253 * first byte of an EUC, otherwise it will return a garbage value.
5256 __ldterm_memwidth_euc(uchar_t c
, void *p
)
5258 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5264 return (tp
->eucwioc
.eucw
[2]);
5266 return (tp
->eucwioc
.eucw
[3]);
5268 return (tp
->eucwioc
.eucw
[1]);
5273 /* The following two functions are PCCS codeset specific methods. */
5275 __ldterm_dispwidth_pccs(uchar_t c
, void *p
, int mode
)
5277 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5284 return (EUC_TWIDTH
);
5286 return (mode
? 2 : EUC_BSWIDTH
);
5288 return (EUC_NLWIDTH
);
5290 return (mode
? 2 : EUC_CRWIDTH
);
5292 return (mode
? 2 : 0);
5298 for (i
= 0; i
< tp
->t_csdata
.csinfo_num
; i
++) {
5299 if (c
>= tp
->t_csdata
.eucpc_data
[i
].msb_start
&&
5300 c
<= tp
->t_csdata
.eucpc_data
[i
].msb_end
)
5301 return (tp
->t_csdata
.eucpc_data
[i
].screen_width
);
5305 * If this leading byte is not in the range list, either provided
5306 * locale data is not sufficient or we encountered an invalid
5307 * character. We return 1 in this case as a fallback value.
5313 __ldterm_memwidth_pccs(uchar_t c
, void *p
)
5315 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5318 for (i
= 0; i
< tp
->t_csdata
.csinfo_num
; i
++) {
5319 if (c
>= tp
->t_csdata
.eucpc_data
[i
].msb_start
&&
5320 c
<= tp
->t_csdata
.eucpc_data
[i
].msb_end
)
5321 return (tp
->t_csdata
.eucpc_data
[i
].byte_length
);
5325 * If this leading byte is not in the range list, either provided
5326 * locale data is not sufficient or we encountered an invalid
5327 * character. We return 1 in this case as a fallback value.
5333 /* The following two functions are UTF-8 codeset specific methods. */
5335 __ldterm_dispwidth_utf8(uchar_t c
, void *p
, int mode
)
5337 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5343 return (EUC_TWIDTH
);
5345 return (mode
? 2 : EUC_BSWIDTH
);
5347 return (EUC_NLWIDTH
);
5349 return (mode
? 2 : EUC_CRWIDTH
);
5351 return (mode
? 2 : 0);
5357 /* This is to silence the lint. */
5358 if (tp
->t_csdata
.codeset_type
!= LDTERM_CS_TYPE_UTF8
)
5362 * If it is a valid leading byte of a UTF-8 character, we set
5363 * the width as 'UNKNOWN_WIDTH' for now. We need to have all
5364 * the bytes to figure out the display width.
5366 if (c
>= (uchar_t
)0xc0 && c
<= (uchar_t
)0xfd)
5367 return (UNKNOWN_WIDTH
);
5370 * If it is an invalid leading byte, we just do our best by
5371 * giving the display width of 1.
5378 __ldterm_memwidth_utf8(uchar_t c
, void *p
)
5380 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5384 * If the codeset type doesn't match, we treat them as
5385 * an illegal character and return 1.
5387 if (tp
->t_csdata
.codeset_type
!= LDTERM_CS_TYPE_UTF8
)
5390 len
= u8_number_of_bytes
[c
];
5393 * If this is a start of an illegal character, we treat
5394 * such as an 1 byte character and screen out.
5396 return ((len
<= 0) ? 1 : len
);
5400 ldterm_utf8_width(uchar_t
*u8
, int length
)
5409 j
= u8_number_of_bytes
[u8
[0]] - 1;
5412 * If the UTF-8 character is out of UTF-16 code range, or,
5413 * if it is either an ASCII character or an invalid leading byte for
5414 * a UTF-8 character, return 1.
5416 if (length
> 4 || j
<= 0)
5419 intcode
= u8
[0] & u8_masks_tbl
[j
];
5420 for (i
= 1; j
> 0; j
--, i
++) {
5422 * The following additional checking is needed to conform to
5423 * the "UTF-8 Corrigendum" introduced at the Unicode 3.1 and
5424 * then updated one more time at the Unicode 3.2.
5427 if (u8
[i
] < u8_valid_min_2nd_byte
[u8
[0]] ||
5428 u8
[i
] > u8_valid_max_2nd_byte
[u8
[0]])
5430 } else if (u8
[i
] < (uchar_t
)LDTERM_CS_TYPE_UTF8_MIN_BYTE
||
5431 u8
[i
] > (uchar_t
)LDTERM_CS_TYPE_UTF8_MAX_BYTE
)
5435 * All subsequent bytes of UTF-8 character has the following
5440 * hence left shift six bits to make space and then get
5441 * six bits from the new byte.
5443 intcode
= (intcode
<< LDTERM_CS_TYPE_UTF8_SHIFT_BITS
) |
5444 (u8
[i
] & LDTERM_CS_TYPE_UTF8_BIT_MASK
);
5448 if (intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P00
) {
5449 /* Basic Multilingual Plane. */
5454 i
= ldterm_ucode
[0][i
].u0
;
5457 i
= ldterm_ucode
[0][i
].u1
;
5460 i
= ldterm_ucode
[0][i
].u2
;
5463 i
= ldterm_ucode
[0][i
].u3
;
5466 } else if (intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P01
) {
5467 /* Secondary Multilingual Plane. */
5468 intcode
= intcode
& (uint_t
)0xffff;
5473 i
= ldterm_ucode
[1][i
].u0
;
5476 i
= ldterm_ucode
[1][i
].u1
;
5479 i
= ldterm_ucode
[1][i
].u2
;
5482 i
= ldterm_ucode
[1][i
].u3
;
5485 } else if ((intcode
>= LDTERM_CS_TYPE_UTF8_MIN_CJKEXTB
&&
5486 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_CJKEXTB
) ||
5487 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_CJKCOMP
&&
5488 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_CJKCOMP
) ||
5489 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_P15
&&
5490 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P15
) ||
5491 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_P16
&&
5492 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P16
)) {
5494 * Supplementary Plane for CJK Ideographs and
5495 * Private Use Planes.
5498 } else if ((intcode
>= LDTERM_CS_TYPE_UTF8_MIN_P14
&&
5499 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P14
) ||
5500 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_VARSEL
&&
5501 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_VARSEL
)) {
5503 * Some Special Purpose Plane characters:
5504 * These are like control characters and not printable.
5510 * We return the display width of 1 for all character code points
5511 * that we didn't catch from the above logic and also for combining
5512 * and conjoining characters with width value of zero.
5514 * In particular, the reason why we are returning 1 for combining
5515 * and conjoining characters is because the GUI-based terminal
5516 * emulators are not yet capable of properly handling such characters
5517 * and in most of the cases, they just treat such characters as if
5518 * they occupy a display cell. If the terminal emulators are capable of
5519 * handling the characters correctly, then, this logic of returning
5520 * 1 should be revisited and changed. See CR 6660526 for more
5523 return ((i
== 0) ? '\1' : (uchar_t
)i
);