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_eucp_mp
= NULL
;
732 tp
->t_eucwarn
= 0; /* no bad chars seen yet */
734 tp
->t_csdata
= default_cs_data
;
735 tp
->t_csmethods
= cs_methods
[LDTERM_CS_TYPE_EUC
];
740 * Find out if the module below us does canonicalization; if
741 * so, we won't do it ourselves.
744 if ((qryp
= open_ioctl(q
, MC_CANONQUERY
)) == NULL
)
748 * Reformulate as an M_CTL message. The actual data will
749 * be in the b_cont field.
751 qryp
->b_datap
->db_type
= M_CTL
;
755 /* allocate a TCSBRK ioctl in case we'll need it on close */
756 if ((qryp
= open_ioctl(q
, TCSBRK
)) == NULL
)
758 tp
->t_drainmsg
= qryp
;
759 if ((bp
= open_mblk(q
, sizeof (int))) == NULL
)
764 * Find out if the underlying driver supports proper POSIX close
765 * semantics. If not, we'll have to approximate it using TCSBRK. If
766 * it does, it will respond with MC_HAS_POSIX, and we'll catch that in
767 * the ldtermrput routine.
769 * When the ldterm_drain_limit tunable is set to zero, we behave the
770 * same as old ldterm: don't send this new message, and always use
771 * TCSBRK during close.
773 if (ldterm_drain_limit
!= 0) {
774 if ((qryp
= open_ioctl(q
, MC_POSIXQUERY
)) == NULL
)
776 qryp
->b_datap
->db_type
= M_CTL
;
780 /* prepare to clear the water marks on close */
781 if ((bp
= open_mblk(q
, sizeof (struct stroptions
))) == NULL
)
783 tp
->t_closeopts
= bp
;
786 * Set the high-water and low-water marks on the stream head
787 * to values appropriate for a terminal. Also set the "vmin"
788 * and "vtime" values to 1 and 0, turn on message-nondiscard
789 * mode (as we're in ICANON mode), and turn on "old-style
792 if ((bp
= open_mblk(q
, sizeof (struct stroptions
))) == NULL
)
794 strop
= (struct stroptions
*)bp
->b_wptr
;
795 strop
->so_flags
= SO_READOPT
|SO_HIWAT
|SO_LOWAT
|SO_NDELON
|SO_ISTTY
;
796 strop
->so_readopt
= RMSGN
;
797 strop
->so_hiwat
= _TTY_BUFSIZ
;
798 strop
->so_lowat
= LOWAT
;
799 bp
->b_wptr
+= sizeof (struct stroptions
);
800 bp
->b_datap
->db_type
= M_SETOPTS
;
803 return (0); /* this can become a controlling TTY */
809 freemsg(tp
->t_closeopts
);
810 freemsg(tp
->t_drainmsg
);
811 /* Dump the state structure */
812 kmem_free(tp
, sizeof (ldtermstd_state_t
));
818 ldtermstd_state_t
*tp
;
822 drain_timed_out(void *arg
)
824 struct close_timer
*ctp
= arg
;
827 ctp
->tp
->t_state
&= ~TS_IOCWAIT
;
832 ldtermclose(queue_t
*q
, int cflag
, cred_t
*crp
)
834 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)q
->q_ptr
;
835 struct stroptions
*strop
;
837 struct close_timer cltimer
;
840 * If we have an outstanding vmin timeout, cancel it.
842 tp
->t_state
|= TS_CLOSE
;
844 (void) quntimeout(q
, tp
->t_vtid
);
848 * Cancel outstanding qbufcall request.
850 if (tp
->t_wbufcid
!= 0)
851 qunbufcall(q
, tp
->t_wbufcid
);
854 * Reset the high-water and low-water marks on the stream
855 * head (?), turn on byte-stream mode, and turn off
856 * "old-style NODELAY" mode.
858 bp
= tp
->t_closeopts
;
859 strop
= (struct stroptions
*)bp
->b_wptr
;
860 strop
->so_flags
= SO_READOPT
|SO_NDELOFF
;
861 strop
->so_readopt
= RNORM
;
862 bp
->b_wptr
+= sizeof (struct stroptions
);
863 bp
->b_datap
->db_type
= M_SETOPTS
;
866 if (cflag
& (FNDELAY
|FNONBLOCK
)) {
867 freemsg(tp
->t_drainmsg
);
868 } else if ((bp
= tp
->t_drainmsg
) != NULL
) {
872 * If the driver isn't known to have POSIX close semantics,
873 * then we have to emulate this the old way. This is done by
874 * sending down TCSBRK,1 to drain the output and waiting for
877 iocb
= (struct iocblk
*)bp
->b_rptr
;
878 iocb
->ioc_count
= sizeof (int);
879 *(int *)bp
->b_cont
->b_rptr
= 1;
880 bp
->b_cont
->b_wptr
+= sizeof (int);
881 tp
->t_state
|= TS_IOCWAIT
;
882 tp
->t_iocid
= iocb
->ioc_id
;
883 if (!putq(WR(q
), bp
))
887 * If we're not able to receive signals at this point, then
888 * launch a timer. This timer will prevent us from waiting
889 * forever for a signal that won't arrive.
892 if (!ddi_can_receive_sig() && ldterm_drain_limit
!= 0) {
894 cltimer
.id
= qtimeout(q
, drain_timed_out
, &cltimer
,
895 drv_usectohz(ldterm_drain_limit
));
899 * Note that the read side of ldterm and the qtimeout are
900 * protected by D_MTQPAIR, so no additional locking is needed
903 while (tp
->t_state
& TS_IOCWAIT
) {
904 if (qwait_sig(q
) == 0)
908 (void) quntimeout(q
, cltimer
.id
);
912 * From here to the end, the routine does not sleep and does not
913 * reference STREAMS, so it's guaranteed to run to completion.
918 freemsg(tp
->t_message
);
919 freemsg(tp
->t_eucp_mp
);
921 /* Dump the state structure, then unlink it */
922 if (tp
->t_csdata
.locale_name
!= NULL
)
923 kmem_free(tp
->t_csdata
.locale_name
,
924 strlen(tp
->t_csdata
.locale_name
) + 1);
925 kmem_free(tp
, sizeof (ldtermstd_state_t
));
932 * Put procedure for input from driver end of stream (read queue).
935 ldtermrput(queue_t
*q
, mblk_t
*mp
)
937 ldtermstd_state_t
*tp
;
939 queue_t
*wrq
= WR(q
); /* write queue of ldterm mod */
940 queue_t
*nextq
= q
->q_next
; /* queue below us */
943 unsigned char *readp
;
944 unsigned char *writep
;
945 struct termios
*emodes
; /* effective modes set by driver */
948 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
950 * We received our ack from the driver saying there is nothing left to
951 * shovel out, so wake up the close routine.
953 dbtype
= DB_TYPE(mp
);
954 if ((dbtype
== M_IOCACK
|| dbtype
== M_IOCNAK
) &&
955 (tp
->t_state
& (TS_CLOSE
|TS_IOCWAIT
)) == (TS_CLOSE
|TS_IOCWAIT
)) {
956 struct iocblk
*iocp
= (struct iocblk
*)mp
->b_rptr
;
958 if (iocp
->ioc_id
== tp
->t_iocid
) {
959 tp
->t_state
&= ~TS_IOCWAIT
;
972 * Send these up unmolested
984 ldterm_ioctl_reply(q
, mp
);
990 * Parity errors are sent up as M_BREAKS with single
991 * character data (formerly handled in the driver)
993 if (mp
->b_wptr
- mp
->b_rptr
== 1) {
995 * IGNPAR PARMRK RESULT
997 * off on 3 byte sequence
1000 if (!(tp
->t_amodes
.c_iflag
& IGNPAR
)) {
1001 mp
->b_wptr
= mp
->b_rptr
;
1002 if (tp
->t_amodes
.c_iflag
& PARMRK
) {
1007 if ((mp
= allocb(3, BPRI_HI
)) == NULL
) {
1009 "ldtermrput: no blocks");
1012 mp
->b_datap
->db_type
= M_DATA
;
1013 *mp
->b_wptr
++ = (uchar_t
)'\377';
1014 *mp
->b_wptr
++ = '\0';
1018 mp
->b_datap
->db_type
= M_DATA
;
1019 *mp
->b_wptr
++ = '\0';
1028 * We look at the apparent modes here instead of the
1029 * effective modes. Effective modes cannot be used if
1030 * IGNBRK, BRINT and PARMRK have been negotiated to
1031 * be handled by the driver. Since M_BREAK should be
1032 * sent upstream only if break processing was not
1033 * already done, it should be ok to use the apparent
1037 if (!(tp
->t_amodes
.c_iflag
& IGNBRK
)) {
1038 if (tp
->t_amodes
.c_iflag
& BRKINT
) {
1039 ldterm_dosig(q
, SIGINT
, '\0', M_PCSIG
, FLUSHRW
);
1041 } else if (tp
->t_amodes
.c_iflag
& PARMRK
) {
1043 * Send '\377','\0', '\0'.
1046 if ((mp
= allocb(3, BPRI_HI
)) == NULL
) {
1048 "ldtermrput: no blocks");
1051 mp
->b_datap
->db_type
= M_DATA
;
1052 *mp
->b_wptr
++ = (uchar_t
)'\377';
1053 *mp
->b_wptr
++ = '\0';
1054 *mp
->b_wptr
++ = '\0';
1058 * Act as if a '\0' came in.
1061 if ((mp
= allocb(1, BPRI_HI
)) == NULL
) {
1063 "ldtermrput: no blocks");
1066 mp
->b_datap
->db_type
= M_DATA
;
1067 *mp
->b_wptr
++ = '\0';
1076 DEBUG3(("ldtermrput: M_CTL received\n"));
1078 * The M_CTL has been standardized to look like an
1082 if ((mp
->b_wptr
- mp
->b_rptr
) != sizeof (struct iocblk
)) {
1084 "Non standard M_CTL received by ldterm module\n"));
1085 /* May be for someone else; pass it on */
1089 qryp
= (struct iocblk
*)mp
->b_rptr
;
1091 switch (qryp
->ioc_cmd
) {
1095 DEBUG3(("ldtermrput: M_CTL Query Reply\n"));
1097 DEBUG3(("No information in Query Message\n"));
1100 if ((mp
->b_cont
->b_wptr
- mp
->b_cont
->b_rptr
) ==
1101 sizeof (struct termios
)) {
1102 DEBUG3(("ldtermrput: M_CTL GrandScheme\n"));
1103 /* elaborate turning off scheme */
1104 emodes
= (struct termios
*)mp
->b_cont
->b_rptr
;
1105 bcopy(emodes
, &tp
->t_dmodes
,
1106 sizeof (struct termios
));
1107 ldterm_adjust_modes(tp
);
1110 DEBUG3(("Incorrect query replysize\n"));
1115 tp
->t_state
|= TS_NOCANON
;
1117 * Note: this is very nasty. It's not clear
1118 * what the right thing to do with a partial
1119 * message is; We throw it out
1121 if (tp
->t_message
!= NULL
) {
1122 freemsg(tp
->t_message
);
1123 tp
->t_message
= NULL
;
1124 tp
->t_endmsg
= NULL
;
1128 if (tp
->t_state
& TS_MEUC
) {
1129 ASSERT(tp
->t_eucp_mp
);
1130 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1138 tp
->t_state
&= ~TS_NOCANON
;
1142 /* no longer any reason to drain from ldterm */
1143 if (ldterm_drain_limit
!= 0) {
1144 freemsg(tp
->t_drainmsg
);
1145 tp
->t_drainmsg
= NULL
;
1150 DEBUG3(("Unknown M_CTL Message\n"));
1153 putnext(q
, mp
); /* In case anyone else has to see it */
1158 * Flush everything we haven't looked at yet.
1161 if ((tp
->t_state
& TS_ISPTSTTY
) && (*mp
->b_rptr
& FLUSHBAND
))
1162 flushband(q
, *(mp
->b_rptr
+ 1), FLUSHDATA
);
1164 flushq(q
, FLUSHDATA
);
1167 * Flush everything we have looked at.
1169 freemsg(tp
->t_message
);
1170 tp
->t_message
= NULL
;
1171 tp
->t_endmsg
= NULL
;
1175 if (tp
->t_state
& TS_MEUC
) { /* EUC multi-byte */
1176 ASSERT(tp
->t_eucp_mp
);
1177 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1179 putnext(q
, mp
); /* pass it on */
1182 * Relieve input flow control
1184 if ((tp
->t_modes
.c_iflag
& IXOFF
) &&
1185 (tp
->t_state
& TS_TBLOCK
) &&
1186 !(tp
->t_state
& TS_IFBLOCK
) && q
->q_count
<= TTXOLO
) {
1187 tp
->t_state
&= ~TS_TBLOCK
;
1188 (void) putnextctl(wrq
, M_STARTI
);
1189 DEBUG1(("M_STARTI down\n"));
1196 (void) drv_setparm(SYSRAWC
, msgdsize(mp
));
1199 * Flow control: send "start input" message if blocked and
1200 * our queue is below its low water mark.
1202 if ((tp
->t_modes
.c_iflag
& IXOFF
) && (tp
->t_state
& TS_TBLOCK
) &&
1203 !(tp
->t_state
& TS_IFBLOCK
) && q
->q_count
<= TTXOLO
) {
1204 tp
->t_state
&= ~TS_TBLOCK
;
1205 (void) putnextctl(wrq
, M_STARTI
);
1206 DEBUG1(("M_STARTI down\n"));
1209 * If somebody below us ("intelligent" communications
1210 * board, pseudo-tty controlled by an editor) is doing
1211 * canonicalization, don't scan it for special characters.
1213 if (tp
->t_state
& TS_NOCANON
) {
1222 if (tp
->t_modes
.c_iflag
& (INLCR
|IGNCR
|ICRNL
|IUCLC
|IXON
) ||
1223 tp
->t_modes
.c_lflag
& (ISIG
|ICANON
)) {
1225 * We're doing some sort of non-trivial
1226 * processing of input; look at every
1229 while (readp
< bp
->b_wptr
) {
1232 if (tp
->t_modes
.c_iflag
& ISTRIP
)
1236 * First, check that this hasn't been
1237 * escaped with the "literal next"
1240 if (tp
->t_state
& TS_PLNCH
) {
1241 tp
->t_state
&= ~TS_PLNCH
;
1242 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1247 * Setting a special character to NUL
1248 * disables it, so if this character
1249 * is NUL, it should not be compared
1250 * with any of the special characters.
1251 * It should, however, restart frozen
1252 * output if IXON and IXANY are set.
1254 if (c
== _POSIX_VDISABLE
) {
1255 if (tp
->t_modes
.c_iflag
& IXON
&&
1256 tp
->t_state
& TS_TTSTOP
&&
1257 tp
->t_modes
.c_lflag
& IEXTEN
&&
1258 tp
->t_modes
.c_iflag
& IXANY
) {
1260 ~(TS_TTSTOP
|TS_OFBLOCK
);
1261 (void) putnextctl(wrq
, M_START
);
1263 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1268 * If stopped, start if you can; if
1269 * running, stop if you must.
1271 if (tp
->t_modes
.c_iflag
& IXON
) {
1272 if (tp
->t_state
& TS_TTSTOP
) {
1274 tp
->t_modes
.c_cc
[VSTART
] ||
1275 (tp
->t_modes
.c_lflag
&
1277 tp
->t_modes
.c_iflag
&
1282 (void) putnextctl(wrq
,
1287 tp
->t_modes
.c_cc
[VSTOP
]) {
1290 (void) putnextctl(wrq
,
1294 if (c
== tp
->t_modes
.c_cc
[VSTOP
] ||
1295 c
== tp
->t_modes
.c_cc
[VSTART
])
1299 * Check for "literal next" character
1300 * and "flush output" character.
1301 * Note that we omit checks for ISIG
1302 * and ICANON, since the IEXTEN
1303 * setting subsumes them.
1305 if (tp
->t_modes
.c_lflag
& IEXTEN
) {
1306 if (c
== tp
->t_modes
.c_cc
[VLNEXT
]) {
1308 * Remember that we saw a
1309 * "literal next" while
1310 * scanning input, but leave
1311 * leave it in the message so
1312 * that the service routine
1315 tp
->t_state
|= TS_PLNCH
;
1316 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1320 if (c
== tp
->t_modes
.c_cc
[VDISCARD
]) {
1321 ldterm_flush_output(c
, wrq
, tp
);
1325 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1328 * Check for signal-generating
1331 if (tp
->t_modes
.c_lflag
& ISIG
) {
1332 if (c
== tp
->t_modes
.c_cc
[VINTR
]) {
1333 ldterm_dosig(q
, SIGINT
, c
,
1337 if (c
== tp
->t_modes
.c_cc
[VQUIT
]) {
1338 ldterm_dosig(q
, SIGQUIT
, c
,
1342 if (c
== tp
->t_modes
.c_cc
[VSWTCH
]) {
1344 * Ancient SXT support; discard
1345 * character without action.
1349 if (c
== tp
->t_modes
.c_cc
[VSUSP
]) {
1350 ldterm_dosig(q
, SIGTSTP
, c
,
1354 if ((tp
->t_modes
.c_lflag
& IEXTEN
) &&
1355 (c
== tp
->t_modes
.c_cc
[VDSUSP
])) {
1356 ldterm_dosig(q
, SIGTSTP
, c
,
1362 * Consumers do not expect the ^T to be
1363 * echoed out when we generate a
1366 if (c
== tp
->t_modes
.c_cc
[VSTATUS
]) {
1367 ldterm_dosig(q
, SIGINFO
, '\0',
1373 * Throw away CR if IGNCR set, or
1374 * turn it into NL if ICRNL set.
1377 if (tp
->t_modes
.c_iflag
& IGNCR
)
1379 if (tp
->t_modes
.c_iflag
& ICRNL
)
1383 * Turn NL into CR if INLCR
1387 tp
->t_modes
.c_iflag
& INLCR
)
1392 * Map upper case input to lower case
1393 * if IUCLC flag set.
1395 if (tp
->t_modes
.c_iflag
& IUCLC
&&
1396 c
>= 'A' && c
<= 'Z')
1400 * Put the possibly-transformed
1401 * character back in the message.
1407 * If we didn't copy some characters because
1408 * we were ignoring them, fix the size of the
1409 * data block by adjusting the write pointer.
1410 * XXX This may result in a zero-length
1411 * block; will this cause anybody gastric
1414 bp
->b_wptr
-= (readp
- writep
);
1417 * We won't be doing anything other than
1418 * possibly stripping the input.
1420 if (tp
->t_modes
.c_iflag
& ISTRIP
) {
1421 while (readp
< bp
->b_wptr
)
1422 *writep
++ = *readp
++ & 0177;
1424 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
1427 } while ((bp
= bp
->b_cont
) != NULL
); /* next block, if any */
1430 * Queue the message for service procedure if the
1431 * queue is not empty or canputnext() fails or
1432 * tp->t_state & TS_RESCAN is true.
1435 if (q
->q_first
!= NULL
|| !bcanputnext(q
, mp
->b_band
) ||
1436 (tp
->t_state
& TS_RESCAN
))
1439 (void) ldtermrmsg(q
, mp
);
1442 * Flow control: send "stop input" message if our queue is
1443 * approaching its high-water mark. The message will be
1444 * dropped on the floor in the service procedure, if we
1445 * cannot ship it up and we have had it upto our neck!
1447 * Set QWANTW to ensure that the read queue service procedure
1448 * gets run when nextq empties up again, so that it can
1451 if ((tp
->t_modes
.c_iflag
& IXOFF
) && !(tp
->t_state
& TS_TBLOCK
) &&
1452 q
->q_count
>= TTXOHI
) {
1453 mutex_enter(QLOCK(nextq
));
1454 nextq
->q_flag
|= QWANTW
;
1455 mutex_exit(QLOCK(nextq
));
1456 tp
->t_state
|= TS_TBLOCK
;
1457 (void) putnextctl(wrq
, M_STOPI
);
1458 DEBUG1(("M_STOPI down\n"));
1464 * Line discipline input server processing. Erase/kill and escape
1465 * ('\') processing, gathering into messages, upper/lower case input
1469 ldtermrsrv(queue_t
*q
)
1471 ldtermstd_state_t
*tp
;
1474 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
1476 if (tp
->t_state
& TS_RESCAN
) {
1478 * Canonicalization was turned on or off. Put the
1479 * message being assembled back in the input queue,
1480 * so that we rescan it.
1482 if (tp
->t_message
!= NULL
) {
1483 DEBUG5(("RESCAN WAS SET; put back in q\n"));
1484 if (tp
->t_msglen
!= 0)
1485 (void) putbq(q
, tp
->t_message
);
1487 freemsg(tp
->t_message
);
1488 tp
->t_message
= NULL
;
1489 tp
->t_endmsg
= NULL
;
1492 if (tp
->t_state
& TS_MEUC
) {
1493 ASSERT(tp
->t_eucp_mp
);
1494 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1498 tp
->t_state
&= ~TS_RESCAN
;
1501 while ((mp
= getq(q
)) != NULL
) {
1502 if (!ldtermrmsg(q
, mp
))
1507 * Flow control: send start message if blocked and our queue
1508 * is below its low water mark.
1510 if ((tp
->t_modes
.c_iflag
& IXOFF
) && (tp
->t_state
& TS_TBLOCK
) &&
1511 !(tp
->t_state
& TS_IFBLOCK
) && q
->q_count
<= TTXOLO
) {
1512 tp
->t_state
&= ~TS_TBLOCK
;
1513 (void) putctl(WR(q
), M_STARTI
);
1518 * This routine is called from both ldtermrput and ldtermrsrv to
1519 * do the actual work of dealing with mp. Return 1 on sucesss and
1523 ldtermrmsg(queue_t
*q
, mblk_t
*mp
)
1531 ldtermstd_state_t
*tp
;
1535 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
1537 if (mp
->b_datap
->db_type
<= QPCTL
&& !bcanputnext(q
, mp
->b_band
)) {
1539 * Stream head is flow controlled. If echo is
1540 * turned on, flush the read side or send a
1541 * bell down the line to stop input and
1542 * process the current message.
1543 * Otherwise(putbq) the user will not see any
1544 * response to to the typed input. Typically
1545 * happens if there is no reader process.
1546 * Note that you will loose the data in this
1547 * case if the data is coming too fast. There
1548 * is an assumption here that if ECHO is
1549 * turned on its some user typing the data on
1550 * a terminal and its not network.
1552 if (tp
->t_modes
.c_lflag
& ECHO
) {
1553 if ((tp
->t_modes
.c_iflag
& IMAXBEL
) &&
1554 (tp
->t_modes
.c_lflag
& ICANON
)) {
1556 if (canputnext(WR(q
)))
1557 ldterm_outchar(CTRL('g'), WR(q
), 4, tp
);
1561 (void) putctl1(q
, M_FLUSH
, FLUSHR
);
1564 (void) putbq(q
, mp
);
1566 goto out
; /* read side is blocked */
1569 switch (mp
->b_datap
->db_type
) {
1572 putnext(q
, mp
); /* pass it on */
1577 * Flush everything we haven't looked at yet.
1579 flushq(q
, FLUSHDATA
);
1582 * Flush everything we have looked at.
1584 freemsg(tp
->t_message
);
1585 tp
->t_message
= NULL
;
1586 tp
->t_endmsg
= NULL
;
1589 * XXX should we set read request
1590 * tp->t_rd_request to NULL?
1592 tp
->t_rocount
= 0; /* if it hasn't been typed */
1593 tp
->t_rocol
= 0; /* it hasn't been echoed :-) */
1594 if (tp
->t_state
& TS_MEUC
) {
1595 ASSERT(tp
->t_eucp_mp
);
1596 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1599 * Restart output, since it's probably got
1600 * nowhere to go anyway, and we're probably
1601 * not going to see another ^Q for a while.
1603 if (tp
->t_state
& TS_TTSTOP
) {
1604 tp
->t_state
&= ~(TS_TTSTOP
|TS_OFBLOCK
);
1605 (void) putnextctl(WR(q
), M_START
);
1608 * This message will travel up the read
1609 * queue, flushing as it goes, get turned
1610 * around at the stream head, and travel back
1611 * down the write queue, flushing as it goes.
1613 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
1616 * This message will travel down the write
1617 * queue, flushing as it goes, get turned
1618 * around at the driver, and travel back up
1619 * the read queue, flushing as it goes.
1621 (void) putctl1(WR(q
), M_FLUSH
, FLUSHR
);
1624 * Now that that's done, we send a SIGCONT
1625 * upstream, followed by the M_HANGUP.
1627 /* (void) putnextctl1(q, M_PCSIG, SIGCONT); */
1634 * Augment whatever information the driver is
1635 * returning with the information we supply.
1637 ldterm_ioctl_reply(q
, mp
);
1645 * This is an M_DATA message.
1649 * If somebody below us ("intelligent" communications
1650 * board, pseudo-tty controlled by an editor) is
1651 * doing canonicalization, don't scan it for special
1654 if (tp
->t_state
& TS_NOCANON
) {
1660 if ((bpt
= newmsg(tp
)) != NULL
) {
1664 ASSERT(bp
->b_wptr
>= bp
->b_rptr
);
1665 ebsize
= bp
->b_wptr
- bp
->b_rptr
;
1666 if (ebsize
> EBSIZE
)
1671 * By default, free the message once processed
1676 * update sysinfo canch
1677 * character. The value of
1678 * canch may vary as compared
1682 while (bp
->b_rptr
< bp
->b_wptr
) {
1684 if ((bpt
= ldterm_docanon(c
,
1685 bpt
, ebsize
, q
, tp
, &dofree
)) ==
1690 * Release this block or put back on queue.
1695 (void) putbq(q
, bp
);
1699 bpt
= ldterm_dononcanon(bp
, bpt
, ebsize
, q
, tp
);
1702 "ldtermrsrv: out of blocks");
1706 } while ((bp
= bcont
) != NULL
);
1710 * Send whatever we echoed downstream.
1712 if (tp
->t_echomp
!= NULL
) {
1713 if (canputnext(WR(q
)))
1714 putnext(WR(q
), tp
->t_echomp
);
1716 freemsg(tp
->t_echomp
);
1717 tp
->t_echomp
= NULL
;
1726 * Do canonical mode input; check whether this character is to be
1727 * treated as a special character - if so, check whether it's equal
1728 * to any of the special characters and handle it accordingly.
1729 * Otherwise, just add it to the current line.
1732 ldterm_docanon(uchar_t c
, mblk_t
*bpt
, size_t ebsize
, queue_t
*q
,
1733 ldtermstd_state_t
*tp
, int *dofreep
)
1735 queue_t
*wrq
= WR(q
);
1739 * If the previous character was the "literal next"
1740 * character, treat this character as regular input.
1742 if (tp
->t_state
& TS_SLNCH
)
1746 * Setting a special character to NUL disables it, so if this
1747 * character is NUL, it should not be compared with any of
1748 * the special characters.
1750 if (c
== _POSIX_VDISABLE
) {
1751 tp
->t_state
&= ~TS_QUOT
;
1755 * If this character is the literal next character, echo it
1756 * as '^', backspace over it, and record that fact.
1758 if ((tp
->t_modes
.c_lflag
& IEXTEN
) && c
== tp
->t_modes
.c_cc
[VLNEXT
]) {
1759 if (tp
->t_modes
.c_lflag
& ECHO
)
1760 ldterm_outstring((unsigned char *)"^\b", 2, wrq
,
1762 tp
->t_state
|= TS_SLNCH
;
1766 * Check for the editing character. If the display width of
1767 * the last byte at the canonical buffer is not one and also
1768 * smaller than or equal to UNKNOWN_WIDTH, the character at
1769 * the end of the buffer is a multi-byte and/or multi-column
1772 if (c
== tp
->t_modes
.c_cc
[VERASE
] || c
== tp
->t_modes
.c_cc
[VERASE2
]) {
1773 if (tp
->t_state
& TS_QUOT
) {
1775 * Get rid of the backslash, and put the
1776 * erase character in its place.
1778 ldterm_erase(wrq
, ebsize
, tp
);
1782 if ((tp
->t_state
& TS_MEUC
) && tp
->t_msglen
&&
1783 (*(tp
->t_eucp
- 1) != 1 &&
1784 *(tp
->t_eucp
- 1) <= UNKNOWN_WIDTH
))
1785 ldterm_csi_erase(wrq
, ebsize
, tp
);
1787 ldterm_erase(wrq
, ebsize
, tp
);
1792 if ((tp
->t_modes
.c_lflag
& IEXTEN
) && c
== tp
->t_modes
.c_cc
[VWERASE
]) {
1794 * Do "ASCII word" or "multibyte character token/chunk" erase.
1796 if (tp
->t_state
& TS_MEUC
)
1797 ldterm_csi_werase(wrq
, ebsize
, tp
);
1799 ldterm_werase(wrq
, ebsize
, tp
);
1803 if (c
== tp
->t_modes
.c_cc
[VKILL
]) {
1804 if (tp
->t_state
& TS_QUOT
) {
1806 * Get rid of the backslash, and put the kill
1807 * character in its place.
1809 ldterm_erase(wrq
, ebsize
, tp
);
1813 ldterm_kill(wrq
, ebsize
, tp
);
1818 if ((tp
->t_modes
.c_lflag
& IEXTEN
) && c
== tp
->t_modes
.c_cc
[VREPRINT
]) {
1819 ldterm_reprint(wrq
, ebsize
, tp
);
1823 * If the preceding character was a backslash: if the current
1824 * character is an EOF, get rid of the backslash and treat
1825 * the EOF as data; if we're in XCASE mode and the current
1826 * character is part of a backslash-X escape sequence,
1827 * process it; otherwise, just treat the current character
1830 if (tp
->t_state
& TS_QUOT
) {
1831 tp
->t_state
&= ~TS_QUOT
;
1832 if (c
== tp
->t_modes
.c_cc
[VEOF
]) {
1834 * EOF character. Since it's escaped, get rid
1835 * of the backslash and put the EOF character
1838 ldterm_erase(wrq
, ebsize
, tp
);
1842 * If we're in XCASE mode, and the current
1843 * character is part of a backslash-X
1844 * sequence, get rid of the backslash and
1845 * replace the current character with what
1846 * that sequence maps to.
1848 if ((tp
->t_modes
.c_lflag
& XCASE
) &&
1849 imaptab
[c
] != '\0') {
1850 ldterm_erase(wrq
, ebsize
, tp
);
1857 * Previous character wasn't backslash; check whether
1858 * this was the EOF character.
1860 if (c
== tp
->t_modes
.c_cc
[VEOF
]) {
1862 * EOF character. Don't echo it unless
1863 * ECHOCTL is set, don't stuff it in the
1864 * current line, but send the line up the
1867 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
1868 (tp
->t_modes
.c_lflag
& IEXTEN
) &&
1869 (tp
->t_modes
.c_lflag
& ECHO
)) {
1870 i
= ldterm_echo(c
, wrq
, ebsize
, tp
);
1872 ldterm_outchar('\b', wrq
, ebsize
, tp
);
1876 bpt
->b_datap
->db_type
= M_DATA
;
1877 ldterm_msg_upstream(q
, tp
);
1878 if (!canputnext(q
)) {
1891 * First, make sure we can fit one WHOLE multi-byte char in the
1892 * buffer. This is one place where we have overhead even if
1893 * not in multi-byte mode; the overhead is subtracting
1894 * tp->t_maxeuc from MAX_CANON before checking.
1896 * Allows MAX_CANON bytes in the buffer before throwing awaying
1897 * the the overflow of characters.
1899 if ((tp
->t_msglen
> ((_TTY_BUFSIZ
+ 1) - (int)tp
->t_maxeuc
)) &&
1900 !((tp
->t_state
& TS_MEUC
) && tp
->t_eucleft
)) {
1903 * Byte will cause line to overflow, or the next EUC
1904 * won't fit: Ring the bell or discard all input, and
1905 * don't save the byte away.
1907 if (tp
->t_modes
.c_iflag
& IMAXBEL
) {
1908 if (canputnext(wrq
))
1909 ldterm_outchar(CTRL('g'), wrq
, ebsize
, tp
);
1913 * MAX_CANON processing. free everything in
1914 * the current line and start with the
1915 * current character as the first character.
1917 DEBUG7(("ldterm_docanon: MAX_CANON processing\n"));
1918 freemsg(tp
->t_message
);
1919 tp
->t_message
= NULL
;
1920 tp
->t_endmsg
= NULL
;
1922 tp
->t_rocount
= 0; /* if it hasn't been type */
1923 tp
->t_rocol
= 0; /* it hasn't been echoed :-) */
1924 if (tp
->t_state
& TS_MEUC
) {
1925 ASSERT(tp
->t_eucp_mp
);
1926 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
1928 tp
->t_state
&= ~TS_SLNCH
;
1933 * Add the character to the current line.
1935 if (bpt
->b_wptr
>= bpt
->b_datap
->db_lim
) {
1937 * No more room in this mblk; save this one away, and
1938 * allocate a new one.
1940 bpt
->b_datap
->db_type
= M_DATA
;
1941 if ((bpt
= allocb(IBSIZE
, BPRI_MED
)) == NULL
)
1945 * Chain the new one to the end of the old one, and
1946 * mark it as the last block in the current line.
1948 tp
->t_endmsg
->b_cont
= bpt
;
1952 tp
->t_msglen
++; /* message length in BYTES */
1955 * In multi-byte mode, we have to keep track of where we are.
1956 * The first bytes of multi-byte chars get the full count for the
1957 * whole character. We don't do any column calculations
1958 * here, but we need the information for when we do. We could
1959 * come across cases where we are getting garbage on the
1960 * line, but we're in multi-byte mode. In that case, we may
1961 * see ASCII controls come in the middle of what should have been a
1962 * multi-byte character. Call ldterm_eucwarn...eventually, a
1963 * warning message will be printed about it.
1965 if (tp
->t_state
& TS_MEUC
) {
1966 if (tp
->t_eucleft
) { /* if in a multi-byte char already */
1968 *tp
->t_eucp
++ = 0; /* is a subsequent byte */
1969 if (c
< (uchar_t
)0x20)
1971 } else { /* is the first byte of a multi-byte, or is ASCII */
1974 tp
->t_csmethods
.ldterm_dispwidth(c
,
1975 (void *)tp
, tp
->t_modes
.c_lflag
& ECHOCTL
);
1979 tp
->t_csmethods
.ldterm_dispwidth(c
,
1980 (void *)tp
, tp
->t_modes
.c_lflag
& ECHOCTL
);
1982 tp
->t_csmethods
.ldterm_memwidth(c
,
1984 tp
->t_codeset
= ldterm_codeset(
1985 tp
->t_csdata
.codeset_type
, c
);
1990 * AT&T is concerned about the following but we aren't since
1991 * we have already shipped code that works.
1993 * EOL2/XCASE should be conditioned with IEXTEN to be truly
1994 * POSIX conformant. This is going to cause problems for
1995 * pre-SVR4.0 programs that don't know about IEXTEN. Hence
1996 * EOL2/IEXTEN is not conditioned with IEXTEN.
1998 if (!(tp
->t_state
& TS_SLNCH
) &&
1999 (c
== '\n' || (c
!= '\0' && (c
== tp
->t_modes
.c_cc
[VEOL
] ||
2000 (c
== tp
->t_modes
.c_cc
[VEOL2
]))))) {
2002 * || ((tp->t_modes.c_lflag & IEXTEN) && c ==
2003 * tp->t_modes.c_cc[VEOL2]))))) {
2006 * It's a line-termination character; send the line
2009 bpt
->b_datap
->db_type
= M_DATA
;
2010 ldterm_msg_upstream(q
, tp
);
2011 if (tp
->t_state
& TS_MEUC
) {
2012 ASSERT(tp
->t_eucp_mp
);
2013 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
2015 if ((bpt
= newmsg(tp
)) == NULL
)
2019 * Character was escaped with LNEXT.
2021 if (tp
->t_rocount
++ == 0)
2022 tp
->t_rocol
= tp
->t_col
;
2023 tp
->t_state
&= ~(TS_SLNCH
|TS_QUOT
);
2025 * If the current character is a single byte and single
2026 * column character and it is the backslash character and
2027 * IEXTEN, then the state will have TS_QUOT.
2029 if ((c
== '\\') && (tp
->t_modes
.c_lflag
& IEXTEN
) &&
2030 (!(tp
->t_state
& TS_MEUC
) ||
2031 ((tp
->t_state
& TS_MEUC
) && (!tp
->t_eucleft
))))
2032 tp
->t_state
|= TS_QUOT
;
2038 if (tp
->t_state
& TS_ERASE
) {
2039 tp
->t_state
&= ~TS_ERASE
;
2040 if (tp
->t_modes
.c_lflag
& ECHO
)
2041 ldterm_outchar('/', wrq
, ebsize
, tp
);
2043 if (tp
->t_modes
.c_lflag
& ECHO
)
2044 (void) ldterm_echo(c
, wrq
, ebsize
, tp
);
2047 * Echo NL when ECHO turned off, if ECHONL flag is
2050 if (c
== '\n' && (tp
->t_modes
.c_lflag
& ECHONL
))
2051 ldterm_outchar(c
, wrq
, ebsize
, tp
);
2061 ldterm_unget(ldtermstd_state_t
*tp
)
2065 if ((bpt
= tp
->t_endmsg
) == NULL
)
2066 return (-1); /* no buffers */
2067 if (bpt
->b_rptr
== bpt
->b_wptr
)
2068 return (-1); /* zero-length record */
2069 tp
->t_msglen
--; /* one fewer character */
2070 return (*--bpt
->b_wptr
);
2075 ldterm_trim(ldtermstd_state_t
*tp
)
2080 ASSERT(tp
->t_endmsg
);
2083 if (bpt
->b_rptr
== bpt
->b_wptr
) {
2085 * This mblk is now empty. Find the previous mblk;
2086 * throw this one away, unless it's the first one.
2090 while (bp
->b_cont
!= bpt
) {
2096 tp
->t_endmsg
= bp
; /* point to that mblk */
2103 * Rubout one character from the current line being built for tp as
2104 * cleanly as possible. q is the write queue for tp. Most of this
2105 * can't be applied to multi-byte processing. We do our own thing
2106 * for that... See the "ldterm_eucerase" routine. We never call
2107 * ldterm_rubout on a multi-byte or multi-column character.
2110 ldterm_rubout(uchar_t c
, queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2113 static unsigned char crtrubout
[] = "\b \b\b \b";
2114 #define RUBOUT1 &crtrubout[3] /* rub out one position */
2115 #define RUBOUT2 &crtrubout[0] /* rub out two positions */
2117 if (!(tp
->t_modes
.c_lflag
& ECHO
))
2119 if (tp
->t_modes
.c_lflag
& ECHOE
) {
2121 * "CRT rubout"; try erasing it from the screen.
2123 if (tp
->t_rocount
== 0) {
2125 * After the character being erased was
2126 * echoed, some data was written to the
2127 * terminal; we can't erase it cleanly, so we
2128 * just reprint the whole line as if the user
2129 * had typed the reprint character.
2131 ldterm_reprint(q
, ebsize
, tp
);
2135 * XXX what about escaped characters?
2137 switch (typetab
[c
]) {
2140 if ((tp
->t_modes
.c_lflag
& XCASE
) &&
2142 ldterm_outstring(RUBOUT1
, 3, q
, ebsize
,
2144 ldterm_outstring(RUBOUT1
, 3, q
, ebsize
, tp
);
2152 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
2153 (tp
->t_modes
.c_lflag
& IEXTEN
))
2154 ldterm_outstring(RUBOUT2
, 6, q
, ebsize
,
2159 if (tp
->t_rocount
< tp
->t_msglen
) {
2161 * While the tab being erased was
2162 * expanded, some data was written
2163 * to the terminal; we can't erase
2164 * it cleanly, so we just reprint
2165 * the whole line as if the user
2166 * had typed the reprint character.
2168 ldterm_reprint(q
, ebsize
, tp
);
2171 tabcols
= ldterm_tabcols(tp
);
2172 while (--tabcols
>= 0)
2173 ldterm_outchar('\b', q
, ebsize
, tp
);
2177 } else if ((tp
->t_modes
.c_lflag
& ECHOPRT
) &&
2178 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
2180 * "Printing rubout"; echo it between \ and /.
2182 if (!(tp
->t_state
& TS_ERASE
)) {
2183 ldterm_outchar('\\', q
, ebsize
, tp
);
2184 tp
->t_state
|= TS_ERASE
;
2186 (void) ldterm_echo(c
, q
, ebsize
, tp
);
2188 (void) ldterm_echo(tp
->t_modes
.c_cc
[VERASE
], q
, ebsize
, tp
);
2189 tp
->t_rocount
--; /* we "unechoed" this character */
2194 * Find the number of characters the tab we just deleted took up by
2195 * zipping through the current line and recomputing the column
2199 ldterm_tabcols(ldtermstd_state_t
*tp
)
2204 unsigned char *readp
, *endp
;
2208 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
2212 * If we're doing multi-byte stuff, zip through the list of
2213 * widths to figure out where we are (we've kept track in most
2216 if (tp
->t_state
& TS_MEUC
) {
2217 ASSERT(tp
->t_eucp_mp
);
2219 startp
= bp
->b_datap
->db_base
;
2220 readp
= tp
->t_eucp_mp
->b_rptr
;
2223 while (readp
< endp
) {
2225 case EUC_TWIDTH
: /* it's a tab */
2226 col
|= 07; /* bump up */
2229 case EUC_BSWIDTH
: /* backspace */
2233 case EUC_NLWIDTH
: /* newline */
2234 if (tp
->t_modes
.c_oflag
& ONLRET
)
2237 case EUC_CRWIDTH
: /* return */
2240 case UNKNOWN_WIDTH
: /* UTF-8 unknown width */
2241 if (tp
->t_csdata
.codeset_type
!=
2242 LDTERM_CS_TYPE_UTF8
|| errflg
) {
2248 * Collect the current UTF-8 character bytes
2249 * from (possibly multiple) data buffers so
2250 * that we can figure out the display width.
2253 for (i
= 1; (i
< LDTERM_CS_MAX_BYTE_LENGTH
) &&
2254 (*(readp
+ i
) == 0); i
++) {
2256 if (startp
>= bp
->b_datap
->db_lim
) {
2271 /* tp->t_eucp_mp contains wrong info?? */
2275 *readp
= ldterm_utf8_width(u8
, i
);
2286 if (startp
>= bp
->b_datap
->db_lim
) {
2289 startp
= bp
->b_datap
->db_base
;
2292 * This will happen only if
2293 * tp->t_eucp_mp contains wrong
2294 * display width info.
2301 goto eucout
; /* finished! */
2306 while (readp
< bp
->b_wptr
) {
2308 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
2309 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
2310 if (c
<= 037 && c
!= '\t' && c
!= '\n' ||
2317 * Column position calculated here.
2319 switch (typetab
[c
]) {
2322 * Ordinary characters; advance by
2330 * Non-printing characters; nothing
2342 /* Newline; column depends on flags. */
2344 if (tp
->t_modes
.c_oflag
& ONLRET
)
2354 /* vertical motion */
2358 /* carriage return */
2364 } while ((bp
= bp
->b_cont
) != NULL
); /* next block, if any */
2367 * "col" is now the column number before the tab. "tp->t_col"
2368 * is still the column number after the tab, since we haven't
2369 * erased the tab yet. Thus "tp->t_col - col" is the number
2370 * of positions the tab moved.
2373 col
= tp
->t_col
- col
;
2375 col
= 8; /* overflow screw */
2381 * Erase a single character; We ONLY ONLY deal with ASCII or
2382 * single-column single-byte codeset character. For multi-byte characters,
2383 * see "ldterm_csi_erase".
2386 ldterm_erase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2390 if ((c
= ldterm_unget(tp
)) != -1) {
2391 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2393 if (tp
->t_state
& TS_MEUC
)
2400 * Erase an entire word, single-byte EUC only please.
2403 ldterm_werase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2408 * Erase trailing white space, if any.
2410 while ((c
= ldterm_unget(tp
)) == ' ' || c
== '\t') {
2411 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2416 * Erase non-white-space characters, if any.
2418 while (c
!= -1 && c
!= ' ' && c
!= '\t') {
2419 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2421 c
= ldterm_unget(tp
);
2425 * We removed one too many characters; put the last
2428 tp
->t_endmsg
->b_wptr
++; /* put 'c' back */
2435 * ldterm_csi_werase - This is multi-byte equivalent of "word erase".
2436 * "Word erase" only makes sense in languages which space between words,
2437 * and it's presumptuous for us to attempt "word erase" when we don't
2438 * know anything about what's really going on. It makes no sense for
2439 * many languages, as the criteria for defining words and tokens may
2440 * be completely different.
2442 * In the TS_MEUC case (which is how we got here), we define a token to
2443 * be space- or tab-delimited, and erase one of them. It helps to
2444 * have this for command lines, but it's otherwise useless for text
2445 * editing applications; you need more sophistication than we can
2449 ldterm_csi_werase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2454 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
2455 uchar_t u8_2
[LDTERM_CS_MAX_BYTE_LENGTH
];
2458 * ip points to the width of the actual bytes. t_eucp points
2459 * one byte beyond, where the next thing will be inserted.
2461 ip
= tp
->t_eucp
- 1;
2463 * Erase trailing white space, if any.
2465 while ((c
= ldterm_unget(tp
)) == ' ' || c
== '\t') {
2467 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2473 * Erase non-white-space characters, if any. The outer loop
2474 * bops through each byte in the buffer. Multi-byte is removed, as
2475 * is ASCII, one byte at a time. The inner loop (for) is only
2476 * executed for first bytes of multi-byte. The inner loop erases
2477 * the number of columns required for the multi-byte char. We check
2478 * for ASCII first, and ldterm_rubout knows about ASCII.
2481 while (c
!= -1 && c
!= ' ' && c
!= '\t') {
2483 if (len
< LDTERM_CS_MAX_BYTE_LENGTH
) {
2484 u8
[len
++] = (uchar_t
)c
;
2487 * Unlike EUC, except the leading byte, some bytes of
2488 * a non-EUC multi-byte characters are in the ASCII code
2489 * range, esp., 0x41 ~ 0x7a. Thus, we cannot simply check
2491 * Checking the (*ip == 1 || *ip == 2 || *ip > UNKNOWN_WIDTH)
2492 * will ensure that it is a single byte character (even though
2493 * it is on display width not byte length) and can be further
2494 * checked whether it is an ASCII character or not.
2496 * When ECHOCTL is on and 'c' is an ASCII control character,
2499 if ((*ip
== 1 || *ip
== 2 || *ip
> UNKNOWN_WIDTH
) &&
2501 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2504 if (*ip
== UNKNOWN_WIDTH
) {
2505 if (tp
->t_csdata
.codeset_type
==
2506 LDTERM_CS_TYPE_UTF8
) {
2507 for (i
= 0; i
< len
; i
++)
2508 u8_2
[i
] = u8
[len
- i
- 1];
2509 *ip
= ldterm_utf8_width(u8_2
, len
);
2515 * erase for number of columns required for
2516 * this multi-byte character. Hopefully, matches
2519 for (i
= 0; i
< (int)*ip
; i
++)
2520 ldterm_rubout(' ', q
, ebsize
, tp
);
2525 c
= ldterm_unget(tp
);
2529 * We removed one too many characters; put the last
2532 tp
->t_endmsg
->b_wptr
++; /* put 'c' back */
2539 * Kill an entire line, erasing each character one-by-one (if ECHOKE
2540 * is set) or just echoing the kill character, followed by a newline
2541 * (if ECHOK is set). Multi-byte processing is included here.
2545 ldterm_kill(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2550 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
2551 uchar_t u8_2
[LDTERM_CS_MAX_BYTE_LENGTH
];
2553 if ((tp
->t_modes
.c_lflag
& ECHOKE
) &&
2554 (tp
->t_modes
.c_lflag
& IEXTEN
) &&
2555 (tp
->t_msglen
== tp
->t_rocount
)) {
2556 if (tp
->t_state
& TS_MEUC
) {
2557 ip
= tp
->t_eucp
- 1;
2559 * This loop similar to "ldterm_csi_werase" above.
2562 while ((c
= ldterm_unget(tp
)) != (-1)) {
2564 if (len
< LDTERM_CS_MAX_BYTE_LENGTH
) {
2565 u8
[len
++] = (uchar_t
)c
;
2567 if ((*ip
== 1 || *ip
== 2 ||
2568 *ip
> UNKNOWN_WIDTH
) && ISASCII(c
)) {
2569 ldterm_rubout((unsigned char) c
, q
,
2573 if (*ip
== UNKNOWN_WIDTH
) {
2574 if (tp
->t_csdata
.codeset_type
2575 == LDTERM_CS_TYPE_UTF8
) {
2576 for (i
= 0; i
< len
;
2580 *ip
= ldterm_utf8_width(
2586 for (i
= 0; i
< (int)*ip
; i
++)
2587 ldterm_rubout(' ', q
, ebsize
,
2595 while ((c
= ldterm_unget(tp
)) != -1) {
2596 ldterm_rubout((unsigned char) c
, q
, ebsize
, tp
);
2601 (void) ldterm_echo(tp
->t_modes
.c_cc
[VKILL
], q
, ebsize
, tp
);
2602 if (tp
->t_modes
.c_lflag
& ECHOK
)
2603 (void) ldterm_echo('\n', q
, ebsize
, tp
);
2604 while (ldterm_unget(tp
) != -1) {
2605 if (tp
->t_state
& TS_MEUC
)
2610 if (tp
->t_state
& TS_MEUC
)
2611 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
2613 tp
->t_state
&= ~(TS_QUOT
|TS_ERASE
|TS_SLNCH
);
2618 * Reprint the current input line. We assume c_cc has already been
2619 * checked. XXX just the current line, not the whole queue? What
2620 * about DEFECHO mode?
2623 ldterm_reprint(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2626 unsigned char *readp
;
2628 if (tp
->t_modes
.c_cc
[VREPRINT
] != (unsigned char) 0)
2629 (void) ldterm_echo(tp
->t_modes
.c_cc
[VREPRINT
], q
, ebsize
, tp
);
2630 ldterm_outchar('\n', q
, ebsize
, tp
);
2635 while (readp
< bp
->b_wptr
)
2636 (void) ldterm_echo(*readp
++, q
, ebsize
, tp
);
2637 } while ((bp
= bp
->b_cont
) != NULL
); /* next block, if any */
2639 tp
->t_state
&= ~TS_ERASE
;
2640 tp
->t_rocount
= tp
->t_msglen
; /* we reechoed the entire line */
2646 * Non canonical processing. Called with q locked from ldtermrsrv.
2650 ldterm_dononcanon(mblk_t
*bp
, mblk_t
*bpt
, size_t ebsize
, queue_t
*q
,
2651 ldtermstd_state_t
*tp
)
2653 queue_t
*wrq
= WR(q
);
2654 unsigned char *rptr
;
2657 size_t bytes_to_move
;
2660 if (tp
->t_modes
.c_lflag
& (ECHO
|ECHONL
|IEXTEN
)) {
2661 unsigned char *wptr
;
2665 * Either we must echo the characters, or we must
2666 * echo NL, or we must check for VLNEXT. Process
2667 * characters one at a time.
2671 while (rptr
< bp
->b_wptr
) {
2674 * If this character is the literal next
2675 * character, echo it as '^' and backspace
2676 * over it if echoing is enabled, indicate
2677 * that the next character is to be treated
2678 * literally, and remove the LNEXT from the
2681 * If the *previous* character was the literal
2682 * next character, don't check whether this
2683 * is a literal next or not.
2685 if ((tp
->t_modes
.c_lflag
& IEXTEN
) &&
2686 !(tp
->t_state
& TS_SLNCH
) &&
2687 c
!= _POSIX_VDISABLE
&&
2688 c
== tp
->t_modes
.c_cc
[VLNEXT
]) {
2689 if (tp
->t_modes
.c_lflag
& ECHO
)
2691 (unsigned char *)"^\b",
2692 2, wrq
, ebsize
, tp
);
2693 tp
->t_state
|= TS_SLNCH
;
2694 continue; /* and ignore it */
2697 * Not a "literal next" character, so it
2698 * should show up as input. If it was
2699 * literal-nexted, turn off the literal-next
2702 tp
->t_state
&= ~TS_SLNCH
;
2704 if (tp
->t_modes
.c_lflag
& ECHO
) {
2706 * Echo the character.
2708 (void) ldterm_echo(c
, wrq
, ebsize
, tp
);
2709 } else if (tp
->t_modes
.c_lflag
& ECHONL
) {
2711 * Echo NL, even though ECHO is not
2715 ldterm_outchar('\n', wrq
, 1, tp
);
2721 * If there are any characters in this buffer, and
2722 * the first of them was literal-nexted, turn off the
2723 * literal-next flag.
2725 if (bp
->b_rptr
!= bp
->b_wptr
)
2726 tp
->t_state
&= ~TS_SLNCH
;
2729 ASSERT(bp
->b_wptr
>= bp
->b_rptr
);
2730 bytes_in_bp
= bp
->b_wptr
- bp
->b_rptr
;
2732 while (bytes_in_bp
!= 0) {
2733 roomleft
= bpt
->b_datap
->db_lim
- bpt
->b_wptr
;
2734 if (roomleft
== 0) {
2736 * No more room in this mblk; save this one
2737 * away, and allocate a new one.
2739 if ((bpt
= allocb(IBSIZE
, BPRI_MED
)) == NULL
) {
2741 DEBUG4(("ldterm_do_noncanon: allcob failed\n"));
2745 * Chain the new one to the end of the old
2746 * one, and mark it as the last block in the
2749 tp
->t_endmsg
->b_cont
= bpt
;
2753 DEBUG5(("roomleft=%d, bytes_in_bp=%d, tp->t_rd_request=%d\n",
2754 roomleft
, bytes_in_bp
, tp
->t_rd_request
));
2756 * if there is a read pending before this data got
2757 * here move bytes according to the minimum of room
2758 * left in this buffer, bytes in the message and byte
2759 * count requested in the read. If there is no read
2760 * pending, move the minimum of the first two
2762 if (tp
->t_rd_request
== 0)
2763 bytes_to_move
= MIN(roomleft
, bytes_in_bp
);
2766 MIN(MIN(roomleft
, bytes_in_bp
), tp
->t_rd_request
);
2767 DEBUG5(("Bytes to move = %lu\n", bytes_to_move
));
2768 if (bytes_to_move
== 0)
2770 bcopy(rptr
, bpt
->b_wptr
, bytes_to_move
);
2771 bpt
->b_wptr
+= bytes_to_move
;
2772 rptr
+= bytes_to_move
;
2773 tp
->t_msglen
+= bytes_to_move
;
2774 bytes_in_bp
-= bytes_to_move
;
2776 if (bytes_in_bp
== 0) {
2777 DEBUG4(("bytes_in_bp is zero\n"));
2780 free_flag
= 1; /* for debugging olny */
2782 DEBUG4(("ldterm_do_noncanon: VMIN = %d, VTIME = %d, msglen = %d, \
2783 tid = %d\n", V_MIN
, V_TIME
, tp
->t_msglen
, tp
->t_vtid
));
2785 * If there is a pending read request at the stream head we
2786 * need to do VMIN/VTIME processing. The four possible cases
2792 * If we can satisfy VMIN, send it up, and start a new
2793 * timer if necessary. These four cases of VMIN/VTIME
2794 * are also dealt with in the write side put routine
2795 * when the M_READ is first seen.
2798 DEBUG4(("Incoming data while M_READ'ing\n"));
2800 * Case 1: Any data will satisfy the read, so send
2803 if (V_MIN
== 0 && V_TIME
> 0) {
2805 vmin_satisfied(q
, tp
, 1);
2808 DEBUG4(("ldterm_do_noncanon called, but no data!\n"));
2811 * Case 2: This should never time out, so
2812 * until there's enough data, do nothing.
2814 } else if (V_MIN
> 0 && V_TIME
== 0) {
2815 if (tp
->t_msglen
>= (int)V_MIN
)
2816 vmin_satisfied(q
, tp
, 1);
2819 * Case 3: If MIN is satisfied, send it up.
2820 * Also, remember to start a new timer *every*
2821 * time we see something if MIN isn't
2824 } else if (V_MIN
> 0 && V_TIME
> 0) {
2825 if (tp
->t_msglen
>= (int)V_MIN
)
2826 vmin_satisfied(q
, tp
, 1);
2830 * Case 4: Not possible. This request
2831 * should always be satisfied from the write
2832 * side, left here for debugging.
2834 } else { /* V_MIN == 0 && V_TIME == 0 */
2835 vmin_satisfied(q
, tp
, 1);
2840 DEBUG4(("CAUTION message block not freed\n"));
2842 return (newmsg(tp
));
2847 * Echo a typed byte to the terminal. Returns the number of bytes
2848 * printed. Bytes of EUC characters drop through the ECHOCTL stuff
2849 * and are just output as themselves.
2852 ldterm_echo(uchar_t c
, queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
2856 if (!(tp
->t_modes
.c_lflag
& ECHO
))
2861 * Echo control characters (c <= 37) only if the ECHOCTRL
2862 * flag is set as ^X.
2865 if ((tp
->t_modes
.c_lflag
& ECHOCTL
) &&
2866 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
2867 if (c
<= 037 && c
!= '\t' && c
!= '\n') {
2868 ldterm_outchar('^', q
, ebsize
, tp
);
2870 if (tp
->t_modes
.c_oflag
& OLCUC
)
2874 } else if (c
== 0177) {
2875 ldterm_outchar('^', q
, ebsize
, tp
);
2879 ldterm_outchar(c
, q
, ebsize
, tp
);
2881 /* echo only special control character and the Bell */
2882 } else if ((c
> 037 && c
!= 0177) || c
== '\t' || c
== '\n' ||
2883 c
== '\r' || c
== '\b' || c
== 007 ||
2884 c
== tp
->t_modes
.c_cc
[VKILL
]) {
2885 ldterm_outchar(c
, q
, ebsize
, tp
);
2893 * Put a character on the output queue.
2896 ldterm_outchar(uchar_t c
, queue_t
*q
, size_t bsize
, ldtermstd_state_t
*tp
)
2901 * Don't even look at the characters unless we have something
2902 * useful to do with them.
2904 if ((tp
->t_modes
.c_oflag
& OPOST
) ||
2905 ((tp
->t_modes
.c_lflag
& XCASE
) &&
2906 (tp
->t_modes
.c_lflag
& ICANON
))) {
2909 if ((mp
= allocb(4, BPRI_HI
)) == NULL
) {
2911 "ldterm: (ldterm_outchar) out of blocks");
2915 mp
= ldterm_output_msg(q
, mp
, &tp
->t_echomp
, tp
, bsize
, 1);
2920 if ((curbp
= tp
->t_echomp
) != NULL
) {
2921 while (curbp
->b_cont
!= NULL
)
2922 curbp
= curbp
->b_cont
;
2923 if (curbp
->b_datap
->db_lim
== curbp
->b_wptr
) {
2926 if ((newbp
= allocb(bsize
, BPRI_HI
)) == NULL
) {
2928 "ldterm_outchar: out of blocks");
2931 curbp
->b_cont
= newbp
;
2935 if ((curbp
= allocb(bsize
, BPRI_HI
)) == NULL
) {
2937 "ldterm_outchar: out of blocks");
2940 tp
->t_echomp
= curbp
;
2942 *curbp
->b_wptr
++ = c
;
2948 * Copy a string, of length len, to the output queue.
2951 ldterm_outstring(uchar_t
*cp
, int len
, queue_t
*q
, size_t bsize
,
2952 ldtermstd_state_t
*tp
)
2955 ldterm_outchar(*cp
++, q
, bsize
, tp
);
2962 newmsg(ldtermstd_state_t
*tp
)
2967 * If no current message, allocate a block for it.
2969 if ((bp
= tp
->t_endmsg
) == NULL
) {
2970 if ((bp
= allocb(IBSIZE
, BPRI_MED
)) == NULL
) {
2972 "ldterm: (ldtermrsrv/newmsg) out of blocks");
2983 ldterm_msg_upstream(queue_t
*q
, ldtermstd_state_t
*tp
)
2991 putnext(q
, tp
->t_message
);
2994 * update sysinfo canch character.
2997 (void) drv_setparm(SYSCANC
, s
);
2998 tp
->t_message
= NULL
;
2999 tp
->t_endmsg
= NULL
;
3002 tp
->t_rd_request
= 0;
3003 if (tp
->t_state
& TS_MEUC
) {
3004 ASSERT(tp
->t_eucp_mp
);
3005 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
3006 /* can't reset everything, as we may have other input */
3012 * Re-enable the write-side service procedure. When an allocation
3013 * failure causes write-side processing to stall, we disable the
3014 * write side and arrange to call this function when allocation once
3015 * again becomes possible.
3018 ldterm_wenable(void *addr
)
3021 ldtermstd_state_t
*tp
;
3023 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
3025 * The bufcall is no longer pending.
3034 * Line discipline output queue put procedure. Attempts to process
3035 * the message directly and send it on downstream, queueing it only
3036 * if there's already something pending or if its downstream neighbor
3040 ldtermwput(queue_t
*q
, mblk_t
*mp
)
3042 ldtermstd_state_t
*tp
;
3043 unsigned char type
= mp
->b_datap
->db_type
;
3045 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
3048 * Always process priority messages, regardless of whether or
3049 * not our queue is nonempty.
3051 if (type
>= QPCTL
) {
3056 * Get rid of it, see comment in
3059 if ((tp
->t_state
& TS_FLUSHWAIT
) &&
3060 (*mp
->b_rptr
== FLUSHW
)) {
3061 tp
->t_state
&= ~TS_FLUSHWAIT
;
3066 * This is coming from above, so we only
3067 * handle the write queue here. If FLUSHR is
3068 * set, it will get turned around at the
3069 * driver, and the read procedure will see it
3072 if (*mp
->b_rptr
& FLUSHW
) {
3073 if ((tp
->t_state
& TS_ISPTSTTY
) &&
3074 (*mp
->b_rptr
& FLUSHBAND
))
3075 flushband(q
, *(mp
->b_rptr
+ 1),
3078 flushq(q
, FLUSHDATA
);
3083 * If a timed read is interrupted, there is
3084 * no way to cancel an existing M_READ
3085 * request. We kludge by allowing a flush to
3088 if (tp
->t_state
& TS_MREAD
)
3089 vmin_satisfied(RD(q
), tp
, 0);
3093 DEBUG1(("ldtermwmsg:M_READ RECEIVED\n"));
3095 * Stream head needs data to satisfy timed
3096 * read. Has meaning only if ICANON flag is
3097 * off indicating raw mode
3101 "M_READ: RAW_MODE=%d, CNT=%d, VMIN=%d, VTIME=%d\n",
3102 RAW_MODE
, *(unsigned int *)mp
->b_rptr
, V_MIN
,
3105 tp
->t_rd_request
= *(unsigned int *)mp
->b_rptr
;
3108 if (newmsg(tp
) != NULL
) {
3110 * VMIN/VTIME processing...
3111 * The four possible cases are:
3116 * These four conditions must be dealt
3117 * with on the read side as well in
3118 * ldterm_do_noncanon(). Set TS_MREAD
3119 * so that the read side will know
3120 * there is a pending read request
3121 * waiting at the stream head. If we
3122 * can satisfy MIN do it here, rather
3123 * than on the read side. If we can't,
3124 * start timers if necessary and let
3125 * the other side deal with it.
3127 * We got another M_READ before the
3128 * pending one completed, cancel any
3131 if (tp
->t_state
& TS_MREAD
) {
3132 vmin_satisfied(RD(q
),
3135 tp
->t_state
|= TS_MREAD
;
3137 * Case 1: Any data will
3138 * satisfy read, otherwise
3141 if (V_MIN
== 0 && V_TIME
> 0) {
3143 vmin_satisfied(RD(q
),
3146 vmin_settimer(RD(q
));
3149 * Case 2: If we have enough
3150 * data, send up now.
3151 * Otherwise, the read side
3152 * should wait forever until MIN
3155 } else if (V_MIN
> 0 && V_TIME
== 0) {
3156 if (tp
->t_msglen
>= (int)V_MIN
)
3157 vmin_satisfied(RD(q
),
3161 * Case 3: If we can satisfy
3162 * the read, send it up. If we
3163 * don't have enough data, but
3164 * there is at least one char,
3165 * start a timer. Otherwise,
3166 * let the read side start
3169 } else if (V_MIN
> 0 && V_TIME
> 0) {
3170 if (tp
->t_msglen
>= (int)V_MIN
)
3171 vmin_satisfied(RD(q
),
3173 else if (tp
->t_msglen
)
3174 vmin_settimer(RD(q
));
3176 * Case 4: Read returns
3177 * whatever data is available
3180 } else { /* V_MIN == 0 && V_TIME == 0 */
3181 vmin_satisfied(RD(q
), tp
, 1);
3184 } else /* should do bufcall, really! */
3186 "ldtermwmsg: out of blocks");
3195 /* Pass it through unmolested. */
3202 * If our queue is nonempty or there's a traffic jam
3203 * downstream, this message must get in line.
3205 if (q
->q_first
!= NULL
|| !bcanputnext(q
, mp
->b_band
)) {
3207 * Exception: ioctls, except for those defined to
3208 * take effect after output has drained, should be
3209 * processed immediately.
3211 if (type
== M_IOCTL
) {
3212 struct iocblk
*iocp
;
3214 iocp
= (struct iocblk
*)mp
->b_rptr
;
3215 switch (iocp
->ioc_cmd
) {
3228 * Handle all others immediately.
3231 (void) ldtermwmsg(q
, mp
);
3239 * We can take the fast path through, by simply calling
3240 * ldtermwmsg to dispose of mp.
3242 (void) ldtermwmsg(q
, mp
);
3247 * Line discipline output queue service procedure.
3250 ldtermwsrv(queue_t
*q
)
3255 * We expect this loop to iterate at most once, but must be
3256 * prepared for more in case our upstream neighbor isn't
3257 * paying strict attention to what canput tells it.
3259 while ((mp
= getq(q
)) != NULL
) {
3261 * N.B.: ldtermwput has already handled high-priority
3262 * messages, so we don't have to worry about them
3263 * here. Hence, the putbq call is safe.
3265 if (!bcanputnext(q
, mp
->b_band
)) {
3266 (void) putbq(q
, mp
);
3269 if (!ldtermwmsg(q
, mp
)) {
3271 * Couldn't handle the whole thing; give up
3272 * for now and wait to be rescheduled.
3281 * Process the write-side message denoted by mp. If mp can't be
3282 * processed completely (due to allocation failures), put the
3283 * residual unprocessed part on the front of the write queue, disable
3284 * the queue, and schedule a qbufcall to arrange to complete its
3287 * Return 1 if the message was processed completely and 0 if not.
3289 * This routine is called from both ldtermwput and ldtermwsrv to do the
3290 * actual work of dealing with mp. ldtermwput will have already
3291 * dealt with high priority messages.
3294 ldtermwmsg(queue_t
*q
, mblk_t
*mp
)
3296 ldtermstd_state_t
*tp
;
3297 mblk_t
*residmp
= NULL
;
3300 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
3302 switch (mp
->b_datap
->db_type
) {
3305 ldterm_do_ioctl(q
, mp
);
3312 if ((tp
->t_modes
.c_lflag
& FLUSHO
) &&
3313 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
3314 freemsg(mp
); /* drop on floor */
3319 * Don't even look at the characters unless
3320 * we have something useful to do with them.
3322 if (((tp
->t_modes
.c_oflag
& OPOST
) ||
3323 ((tp
->t_modes
.c_lflag
& XCASE
) &&
3324 (tp
->t_modes
.c_lflag
& ICANON
))) &&
3325 (msgdsize(mp
) || !(tp
->t_state
& TS_ISPTSTTY
))) {
3326 unsigned char band
= mp
->b_band
;
3327 short flag
= mp
->b_flag
;
3329 residmp
= ldterm_output_msg(q
, mp
, &omp
,
3331 if ((mp
= omp
) == NULL
)
3336 /* Update sysinfo outch */
3337 (void) drv_setparm(SYSOUTC
, msgdsize(mp
));
3343 putnext(q
, mp
); /* pass it through unmolested */
3347 if (residmp
== NULL
)
3351 * An allocation failure occurred that prevented the message
3352 * from being completely processed. First, disable our
3353 * queue, since it's pointless to attempt further processing
3354 * until the allocation situation is resolved. (This must
3355 * precede the putbq call below, which would otherwise mark
3356 * the queue to be serviced.)
3360 * Stuff the remnant on our write queue so that we can
3361 * complete it later when times become less lean. Note that
3362 * this sets QFULL, so that our upstream neighbor will be
3363 * blocked by flow control.
3365 (void) putbq(q
, residmp
);
3367 * Schedule a qbufcall to re-enable the queue. The failure
3368 * won't have been for an allocation of more than OBSIZE
3369 * bytes, so don't ask for more than that from bufcall.
3371 size
= msgdsize(residmp
);
3375 qunbufcall(q
, tp
->t_wbufcid
);
3376 tp
->t_wbufcid
= qbufcall(q
, size
, BPRI_MED
, ldterm_wenable
, q
);
3383 * Perform output processing on a message, accumulating the output
3384 * characters in a new message.
3387 ldterm_output_msg(queue_t
*q
, mblk_t
*imp
, mblk_t
**omp
,
3388 ldtermstd_state_t
*tp
, size_t bsize
, int echoing
)
3390 mblk_t
*ibp
; /* block we're examining from input message */
3391 mblk_t
*obp
; /* block we're filling in output message */
3392 mblk_t
*cbp
; /* continuation block */
3393 mblk_t
*oobp
; /* old value of obp; valid if NEW_BLOCK fails */
3394 mblk_t
**contpp
; /* where to stuff ptr to newly-allocated blk */
3399 mblk_t
*bp
; /* block to stuff an M_DELAY message in */
3403 * Allocate a new block into which to put bytes. If we can't,
3404 * we just drop the rest of the message on the floor. If x is
3405 * non-zero, just fall thru; failure requires cleanup before
3409 #define NEW_BLOCK(x) \
3412 if ((obp = allocb(bsize, BPRI_MED)) == NULL) { \
3417 contpp = &obp->b_cont; \
3418 bytes_left = obp->b_datap->db_lim - obp->b_wptr; \
3425 * When we allocate the first block of a message, we should
3426 * stuff the pointer to it in "*omp". All subsequent blocks
3427 * should have the pointer to them stuffed into the "b_cont"
3428 * field of the previous block. "contpp" points to the place
3429 * where we should stuff the pointer.
3431 * If we already have a message we're filling in, continue doing
3434 if ((obp
= *omp
) != NULL
) {
3435 while (obp
->b_cont
!= NULL
)
3437 contpp
= &obp
->b_cont
;
3438 bytes_left
= obp
->b_datap
->db_lim
- obp
->b_wptr
;
3445 while (ibp
->b_rptr
< ibp
->b_wptr
) {
3447 * Make sure there's room for one more
3448 * character. At most, we'll need "t_maxeuc"
3451 if ((bytes_left
< (int)tp
->t_maxeuc
)) {
3456 * If doing XCASE processing (not very
3457 * likely, in this day and age), look at each
3458 * character individually.
3460 if ((tp
->t_modes
.c_lflag
& XCASE
) &&
3461 (tp
->t_modes
.c_lflag
& ICANON
)) {
3465 * We need to make sure that this is not
3466 * a following byte of a multibyte character
3467 * before applying an XCASE processing.
3469 * tp->t_eucign will be 0 if and only
3470 * if the current 'c' is an ASCII character
3471 * and also a byte. Otherwise, it will have
3472 * the byte length of a multibyte character.
3474 if ((tp
->t_state
& TS_MEUC
) &&
3475 tp
->t_eucign
== 0 && NOTASCII(c
)) {
3477 tp
->t_csmethods
.ldterm_memwidth(
3479 tp
->t_scratch_len
= tp
->t_eucign
;
3481 if (tp
->t_csdata
.codeset_type
!=
3482 LDTERM_CS_TYPE_UTF8
) {
3488 tp
->t_modes
.c_lflag
&
3494 * If character is mapped on output,
3495 * put out a backslash followed by
3496 * what it is mapped to.
3498 if (tp
->t_eucign
== 0 && omaptab
[c
] != 0 &&
3499 (!echoing
|| c
!= '\\')) {
3500 /* backslash is an ordinary character */
3502 *obp
->b_wptr
++ = '\\';
3504 if (bytes_left
== 0) {
3509 * Allocation failed, make
3510 * state consistent before
3522 * If no other output processing is
3523 * required, push the character into
3524 * the block and get another.
3526 if (!(tp
->t_modes
.c_oflag
& OPOST
)) {
3527 if (tp
->t_eucign
> 0) {
3537 * OPOST output flag is set. Map
3538 * lower case to upper case if OLCUC
3539 * flag is set and the 'c' is a lowercase
3542 if (tp
->t_eucign
== 0 &&
3543 (tp
->t_modes
.c_oflag
& OLCUC
) &&
3544 c
>= 'a' && c
<= 'z')
3548 * Copy all the ORDINARY characters,
3549 * possibly mapping upper case to
3550 * lower case. We use "movtuc",
3551 * STOPPING when we can't move some
3552 * character. For multi-byte or
3553 * multi-column EUC, we can't depend
3554 * on the regular tables. Rather than
3555 * just drop through to the "big
3556 * switch" for all characters, it
3557 * _might_ be faster to let "movtuc"
3558 * move a bunch of characters.
3559 * Chances are, even in multi-byte
3560 * mode we'll have lots of ASCII
3561 * going through. We check the flag
3562 * once, and call movtuc with the
3563 * appropriate table as an argument.
3565 * "movtuc will work for all codeset
3566 * types since it stops at the beginning
3567 * byte of a multibyte character.
3569 size_t bytes_to_move
;
3572 ASSERT(ibp
->b_wptr
>= ibp
->b_rptr
);
3573 bytes_to_move
= ibp
->b_wptr
- ibp
->b_rptr
;
3574 if (bytes_to_move
> bytes_left
)
3575 bytes_to_move
= bytes_left
;
3576 if (tp
->t_state
& TS_MEUC
) {
3577 bytes_moved
= movtuc(bytes_to_move
,
3578 ibp
->b_rptr
, obp
->b_wptr
,
3579 (tp
->t_modes
.c_oflag
& OLCUC
?
3580 elcuctab
: enotrantab
));
3582 bytes_moved
= movtuc(bytes_to_move
,
3583 ibp
->b_rptr
, obp
->b_wptr
,
3584 (tp
->t_modes
.c_oflag
& OLCUC
?
3585 lcuctab
: notrantab
));
3588 * We're save to just do this column
3589 * calculation, because if TS_MEUC is
3590 * set, we used the proper EUC
3591 * tables, and won't have copied any
3594 tp
->t_col
+= bytes_moved
;
3595 ibp
->b_rptr
+= bytes_moved
;
3596 obp
->b_wptr
+= bytes_moved
;
3597 bytes_left
-= bytes_moved
;
3598 if (ibp
->b_rptr
>= ibp
->b_wptr
)
3599 continue; /* moved all of block */
3600 if (bytes_left
== 0) {
3604 c
= *ibp
->b_rptr
++; /* stopper */
3608 * Again, we need to make sure that this is not
3609 * a following byte of a multibyte character at
3612 * 'tp->t_eucign' will be 0 iff the current 'c' is
3613 * an ASCII character. Otherwise, it will have
3614 * the byte length of a multibyte character.
3615 * We also add the display width to 'tp->t_col' if
3616 * the current codeset is not UTF-8 since this is
3617 * a leading byte of a multibyte character.
3618 * For UTF-8 codeset type, we add the display width
3619 * when we get the last byte of a character.
3621 if ((tp
->t_state
& TS_MEUC
) && tp
->t_eucign
== 0 &&
3623 tp
->t_eucign
= tp
->t_csmethods
.ldterm_memwidth(
3625 tp
->t_scratch_len
= tp
->t_eucign
;
3627 if (tp
->t_csdata
.codeset_type
!=
3628 LDTERM_CS_TYPE_UTF8
) {
3630 tp
->t_csmethods
.ldterm_dispwidth(c
,
3632 tp
->t_modes
.c_lflag
& ECHOCTL
);
3637 * If the driver has requested, don't process
3638 * output flags. However, if we're in
3639 * multi-byte mode, we HAVE to look at
3640 * EVERYTHING going out to maintain column
3641 * position properly. Therefore IF the driver
3642 * says don't AND we're not doing multi-byte,
3643 * then don't do it. Otherwise, do it.
3645 * NOTE: Hardware USUALLY doesn't expand tabs
3646 * properly for multi-byte situations anyway;
3647 * that's a known problem with the 3B2
3648 * "PORTS" board firmware, and any other
3649 * hardware that doesn't ACTUALLY know about
3650 * the current EUC mapping that WE are using
3651 * at this very moment. The problem is that
3652 * memory width is INDEPENDENT of screen
3653 * width - no relation - so WE know how wide
3654 * the characters are, but an off-the-host
3655 * board probably doesn't. So, until we're
3656 * SURE that the hardware below us can
3657 * correctly expand tabs in a
3658 * multi-byte/multi-column EUC situation, we
3662 * Map <CR>to<NL> on output if OCRNL flag
3663 * set. ONLCR processing is not done if OCRNL
3666 if (c
== '\r' && (tp
->t_modes
.c_oflag
& OCRNL
)) {
3672 if (tp
->t_csdata
.codeset_type
== LDTERM_CS_TYPE_EUC
) {
3676 * In other codeset types, we safely assume
3677 * any byte of a multibyte character will have
3678 * 'ORDINARY' type. For ASCII characters, we
3679 * still use the typetab[].
3681 if (tp
->t_eucign
== 0)
3688 * Map <NL> to <CR><NL> on output if ONLCR
3691 if (c
== '\n' && (tp
->t_modes
.c_oflag
& ONLCR
)) {
3692 if (!(tp
->t_state
& TS_TTCR
)) {
3693 tp
->t_state
|= TS_TTCR
;
3695 ctype
= typetab
['\r'];
3698 tp
->t_state
&= ~TS_TTCR
;
3701 * Delay values and column position
3702 * calculated here. For EUC chars in
3703 * multi-byte mode, we use "t_eucign" to help
3704 * calculate columns. When we see the first
3705 * byte of an EUC, we set t_eucign to the
3706 * number of bytes that will FOLLOW it, and
3707 * we add the screen width of the WHOLE EUC
3708 * character to the column position. In
3709 * particular, we can't count SS2 or SS3 as
3710 * printing characters. Remember, folks, the
3711 * screen width and memory width are
3712 * independent - no relation. We could have
3713 * dropped through for ASCII, but we want to
3714 * catch any bad characters (i.e., t_eucign
3715 * set and an ASCII char received) and
3716 * possibly report the garbage situation.
3726 if (tp
->t_state
& TS_MEUC
) {
3731 tp
->t_scratch
[tp
->t_scratch_len
3732 - tp
->t_eucign
] = c
;
3736 if (tp
->t_csdata
.codeset_type
3737 == LDTERM_CS_TYPE_UTF8
&&
3738 tp
->t_eucign
<= 0) {
3745 if (tp
->t_modes
.c_oflag
& OLCUC
)
3755 } else { /* ho hum, ASCII mode... */
3756 if (tp
->t_modes
.c_oflag
& OLCUC
)
3769 * If we're doing ECHOCTL, we've
3770 * already mapped the thing during
3771 * the process of canonising. Don't
3772 * bother here, as it's not one that
3781 * This is probably a backspace
3782 * received, not one that we're
3783 * echoing. Let it go as a
3784 * single-column backspace.
3789 if (tp
->t_modes
.c_oflag
& BSDLY
) {
3790 if (tp
->t_modes
.c_oflag
& OFILL
)
3798 if (tp
->t_modes
.c_oflag
& ONLRET
)
3800 if ((tp
->t_modes
.c_oflag
& NLDLY
) == NL1
)
3808 * Map '\t' to spaces if XTABS flag
3809 * is set. The calculation of
3810 * "t_eucign" has probably insured
3811 * that column will be correct, as we
3812 * bumped t_col by the DISP width,
3813 * not the memory width.
3815 if ((tp
->t_modes
.c_oflag
& TABDLY
) == XTABS
) {
3817 *obp
->b_wptr
++ = ' ';
3820 if ((tp
->t_col
& 07) == 0)
3821 break; /* every 8th */
3825 * expand this tab in
3832 obp
->b_datap
->db_lim
) {
3840 if (tp
->t_modes
.c_oflag
& OFILL
) {
3841 if (tp
->t_modes
.c_oflag
&
3845 switch (tp
->t_modes
.c_oflag
&
3852 count
= 1 + (tp
->t_col
|
3865 if ((tp
->t_modes
.c_oflag
& VTDLY
) &&
3866 !(tp
->t_modes
.c_oflag
& OFILL
))
3874 * Ignore <CR> in column 0 if ONOCR
3877 if (tp
->t_col
== 0 &&
3878 (tp
->t_modes
.c_oflag
& ONOCR
))
3882 switch (tp
->t_modes
.c_oflag
& CRDLY
) {
3885 if (tp
->t_modes
.c_oflag
& OFILL
)
3888 count
= tp
->t_col
% 2;
3892 if (tp
->t_modes
.c_oflag
& OFILL
)
3899 if (tp
->t_modes
.c_oflag
& OFILL
)
3912 if (tp
->t_modes
.c_oflag
& OFILL
) {
3914 if (bytes_left
== 0) {
3918 if (tp
->t_modes
.c_oflag
& OFDEL
)
3919 *obp
->b_wptr
++ = CDEL
;
3921 *obp
->b_wptr
++ = CNUL
;
3923 } while (--count
!= 0);
3925 if ((tp
->t_modes
.c_lflag
& FLUSHO
) &&
3926 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
3934 (void) drv_setparm(SYSOUTC
,
3942 allocb(1, BPRI_MED
)) !=
3944 bp
->b_datap
->db_type
=
3953 * We have to start a new
3954 * message; the delay
3955 * introduces a break between
3965 } while ((ibp
= cbp
) != NULL
); /* next block, if any */
3973 #if !defined(__sparc)
3975 movtuc(size_t size
, unsigned char *from
, unsigned char *origto
,
3976 unsigned char *table
)
3978 unsigned char *to
= origto
;
3981 while (size
!= 0 && (c
= table
[*from
++]) != 0) {
3985 return (to
- origto
);
3990 ldterm_flush_output(uchar_t c
, queue_t
*q
, ldtermstd_state_t
*tp
)
3992 /* Already conditioned with IEXTEN during VDISCARD processing */
3993 if (tp
->t_modes
.c_lflag
& FLUSHO
)
3994 tp
->t_modes
.c_lflag
&= ~FLUSHO
;
3996 flushq(q
, FLUSHDATA
); /* flush our write queue */
3997 /* flush ones below us */
3998 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
3999 if ((tp
->t_echomp
= allocb(EBSIZE
, BPRI_HI
)) != NULL
) {
4000 (void) ldterm_echo(c
, q
, 1, tp
);
4001 if (tp
->t_msglen
!= 0)
4002 ldterm_reprint(q
, EBSIZE
, tp
);
4003 if (tp
->t_echomp
!= NULL
) {
4004 putnext(q
, tp
->t_echomp
);
4005 tp
->t_echomp
= NULL
;
4008 tp
->t_modes
.c_lflag
|= FLUSHO
;
4014 * Signal generated by the reader: M_PCSIG and M_FLUSH messages sent.
4017 ldterm_dosig(queue_t
*q
, int sig
, uchar_t c
, int mtype
, int mode
)
4019 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4023 * c == \0 is brk case; need to flush on BRKINT even if
4026 if ((!(tp
->t_modes
.c_lflag
& NOFLSH
)) || (c
== '\0')) {
4028 if (tp
->t_state
& TS_TTSTOP
) {
4030 (void) putnextctl1(q
, mtype
, sig
);
4033 * Flush read or write side.
4034 * Restart the input or output.
4036 if (mode
& FLUSHR
) {
4037 flushq(q
, FLUSHDATA
);
4038 (void) putnextctl1(WR(q
), M_FLUSH
, mode
);
4039 if (tp
->t_state
& (TS_TBLOCK
|TS_IFBLOCK
)) {
4040 (void) putnextctl(WR(q
), M_STARTI
);
4041 tp
->t_state
&= ~(TS_TBLOCK
|TS_IFBLOCK
);
4044 if (mode
& FLUSHW
) {
4045 flushq(WR(q
), FLUSHDATA
);
4047 * XXX This is extremely gross.
4048 * Since we can't be sure our M_FLUSH
4049 * will have run its course by the
4050 * time we do the echo below, we set
4051 * state and toss it in the write put
4052 * routine to prevent flushing our
4053 * own data. Note that downstream
4054 * modules on the write side will be
4055 * flushed by the M_FLUSH sent above.
4057 tp
->t_state
|= TS_FLUSHWAIT
;
4058 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
4059 if (tp
->t_state
& TS_TTSTOP
) {
4060 (void) putnextctl(WR(q
), M_START
);
4061 tp
->t_state
&= ~(TS_TTSTOP
|TS_OFBLOCK
);
4066 tp
->t_state
&= ~TS_QUOT
;
4068 (void) putnextctl1(q
, mtype
, sig
);
4071 if ((tp
->t_echomp
= allocb(4, BPRI_HI
)) != NULL
) {
4072 if (ldterm_echo(c
, WR(q
), 4, tp
) > 0)
4073 putnext(WR(q
), tp
->t_echomp
);
4075 freemsg(tp
->t_echomp
);
4076 tp
->t_echomp
= NULL
;
4083 * Called when an M_IOCTL message is seen on the write queue; does
4084 * whatever we're supposed to do with it, and either replies
4085 * immediately or passes it to the next module down.
4088 ldterm_do_ioctl(queue_t
*q
, mblk_t
*mp
)
4090 ldtermstd_state_t
*tp
;
4091 struct iocblk
*iocp
;
4092 struct eucioc
*euciocp
; /* needed for EUC ioctls */
4093 ldterm_cs_data_user_t
*csdp
;
4097 uchar_t maxscreenlen
;
4100 iocp
= (struct iocblk
*)mp
->b_rptr
;
4101 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4103 switch (iocp
->ioc_cmd
) {
4110 * Set current parameters and special
4114 struct termios oldmodes
;
4116 error
= miocpullup(mp
, sizeof (struct termios
));
4118 miocnak(q
, mp
, 0, error
);
4122 cb
= (struct termios
*)mp
->b_cont
->b_rptr
;
4124 oldmodes
= tp
->t_amodes
;
4126 if ((tp
->t_amodes
.c_lflag
& PENDIN
) &&
4127 (tp
->t_modes
.c_lflag
& IEXTEN
)) {
4129 * Yuk. The C shell file completion
4130 * code actually uses this "feature",
4131 * so we have to support it.
4133 if (tp
->t_message
!= NULL
) {
4134 tp
->t_state
|= TS_RESCAN
;
4137 tp
->t_amodes
.c_lflag
&= ~PENDIN
;
4139 bcopy(tp
->t_amodes
.c_cc
, tp
->t_modes
.c_cc
, NCCS
);
4142 * ldterm_adjust_modes does not deal with
4145 tp
->t_modes
.c_cflag
= tp
->t_amodes
.c_cflag
;
4147 ldterm_adjust_modes(tp
);
4148 if (chgstropts(&oldmodes
, tp
, RD(q
)) == (-1)) {
4149 miocnak(q
, mp
, 0, EAGAIN
);
4153 * The driver may want to know about the
4154 * following iflags: IGNBRK, BRKINT, IGNPAR,
4155 * PARMRK, INPCK, IXON, IXANY.
4165 * Old-style "ioctl" to set current
4166 * parameters and special characters. Don't
4167 * clear out the unset portions, leave them
4171 struct termios oldmodes
;
4173 error
= miocpullup(mp
, sizeof (struct termio
));
4175 miocnak(q
, mp
, 0, error
);
4179 cb
= (struct termio
*)mp
->b_cont
->b_rptr
;
4181 oldmodes
= tp
->t_amodes
;
4182 tp
->t_amodes
.c_iflag
=
4183 (tp
->t_amodes
.c_iflag
& 0xffff0000 | cb
->c_iflag
);
4184 tp
->t_amodes
.c_oflag
=
4185 (tp
->t_amodes
.c_oflag
& 0xffff0000 | cb
->c_oflag
);
4186 tp
->t_amodes
.c_cflag
=
4187 (tp
->t_amodes
.c_cflag
& 0xffff0000 | cb
->c_cflag
);
4188 tp
->t_amodes
.c_lflag
=
4189 (tp
->t_amodes
.c_lflag
& 0xffff0000 | cb
->c_lflag
);
4191 bcopy(cb
->c_cc
, tp
->t_modes
.c_cc
, NCC
);
4192 /* TCGETS returns amodes, so update that too */
4193 bcopy(cb
->c_cc
, tp
->t_amodes
.c_cc
, NCC
);
4195 /* ldterm_adjust_modes does not deal with cflags */
4197 tp
->t_modes
.c_cflag
= tp
->t_amodes
.c_cflag
;
4199 ldterm_adjust_modes(tp
);
4200 if (chgstropts(&oldmodes
, tp
, RD(q
)) == (-1)) {
4201 miocnak(q
, mp
, 0, EAGAIN
);
4205 * The driver may want to know about the
4206 * following iflags: IGNBRK, BRKINT, IGNPAR,
4207 * PARMRK, INPCK, IXON, IXANY.
4214 * Do the flush on the write queue immediately, and
4215 * queue up any flush on the read queue for the
4216 * service procedure to see. Then turn it into the
4217 * appropriate M_FLUSH message, so that the module
4218 * below us doesn't have to know about TCFLSH.
4220 error
= miocpullup(mp
, sizeof (int));
4222 miocnak(q
, mp
, 0, error
);
4226 ASSERT(mp
->b_datap
!= NULL
);
4227 if (*(int *)mp
->b_cont
->b_rptr
== 0) {
4228 ASSERT(mp
->b_datap
!= NULL
);
4229 (void) putnextctl1(q
, M_FLUSH
, FLUSHR
);
4230 (void) putctl1(RD(q
), M_FLUSH
, FLUSHR
);
4231 } else if (*(int *)mp
->b_cont
->b_rptr
== 1) {
4232 flushq(q
, FLUSHDATA
);
4233 ASSERT(mp
->b_datap
!= NULL
);
4234 tp
->t_state
|= TS_FLUSHWAIT
;
4235 (void) putnextctl1(RD(q
), M_FLUSH
, FLUSHW
);
4236 (void) putnextctl1(q
, M_FLUSH
, FLUSHW
);
4237 } else if (*(int *)mp
->b_cont
->b_rptr
== 2) {
4238 flushq(q
, FLUSHDATA
);
4239 ASSERT(mp
->b_datap
!= NULL
);
4240 (void) putnextctl1(q
, M_FLUSH
, FLUSHRW
);
4241 tp
->t_state
|= TS_FLUSHWAIT
;
4242 (void) putnextctl1(RD(q
), M_FLUSH
, FLUSHRW
);
4244 miocnak(q
, mp
, 0, EINVAL
);
4247 ASSERT(mp
->b_datap
!= NULL
);
4249 miocack(q
, mp
, 0, 0);
4253 error
= miocpullup(mp
, sizeof (int));
4255 miocnak(q
, mp
, 0, error
);
4259 switch (*(int *)mp
->b_cont
->b_rptr
) {
4261 if (!(tp
->t_state
& TS_TTSTOP
)) {
4262 (void) putnextctl(q
, M_STOP
);
4263 tp
->t_state
|= (TS_TTSTOP
|TS_OFBLOCK
);
4268 if (tp
->t_state
& TS_TTSTOP
) {
4269 (void) putnextctl(q
, M_START
);
4270 tp
->t_state
&= ~(TS_TTSTOP
|TS_OFBLOCK
);
4275 (void) putnextctl(q
, M_STOPI
);
4276 tp
->t_state
|= (TS_TBLOCK
|TS_IFBLOCK
);
4280 (void) putnextctl(q
, M_STARTI
);
4281 tp
->t_state
&= ~(TS_TBLOCK
|TS_IFBLOCK
);
4285 miocnak(q
, mp
, 0, EINVAL
);
4288 ASSERT(mp
->b_datap
!= NULL
);
4290 miocack(q
, mp
, 0, 0);
4293 * TCSBRK is expected to be handled by the driver.
4294 * The reason its left for the driver is that when
4295 * the argument to TCSBRK is zero driver has to drain
4296 * the data and sending a M_IOCACK from LDTERM before
4297 * the driver drains the data is going to cause
4302 * The following are EUC related ioctls. For
4303 * EUC_WSET, we have to pass the information on, even
4304 * though we ACK the call. It's vital in the EUC
4305 * environment that everybody downstream knows about
4306 * the EUC codeset widths currently in use; we
4307 * therefore pass down the information in an M_CTL
4308 * message. It will bottom out in the driver.
4313 /* only needed for EUC_WSET */
4314 struct iocblk
*riocp
;
4316 mblk_t
*dmp
, *dmp_cont
;
4319 * If the user didn't supply any information,
4322 error
= miocpullup(mp
, sizeof (struct eucioc
));
4324 miocnak(q
, mp
, 0, error
);
4328 euciocp
= (struct eucioc
*)mp
->b_cont
->b_rptr
;
4330 * Check here for something reasonable. If
4331 * anything will take more than EUC_MAXW
4332 * columns or more than EUC_MAXW bytes
4333 * following SS2 or SS3, then just reject it
4334 * out of hand. It's not impossible for us to
4335 * do it, it just isn't reasonable. So far,
4336 * in the world, we've seen the absolute max
4337 * columns to be 2 and the max number of
4338 * bytes to be 3. This allows room for some
4339 * expansion of that, but it probably won't
4340 * even be necessary. At the moment, we
4341 * return a "range" error. If you really
4342 * need to, you can push EUC_MAXW up to over
4343 * 200; it doesn't make sense, though, with
4344 * only a CANBSIZ sized input limit (usually
4347 for (i
= 0; i
< 4; i
++) {
4348 if ((euciocp
->eucw
[i
] > EUC_MAXW
) ||
4349 (euciocp
->scrw
[i
] > EUC_MAXW
)) {
4350 miocnak(q
, mp
, 0, ERANGE
);
4355 * Otherwise, save the information in tp,
4356 * force codeset 0 (ASCII) to be one byte,
4359 cp_eucwioc(euciocp
, &tp
->eucwioc
, EUCIN
);
4360 tp
->eucwioc
.eucw
[0] = tp
->eucwioc
.scrw
[0] = 1;
4362 * Now, check out whether we're doing
4363 * multibyte processing. if we are, we need
4364 * to allocate a block to hold the parallel
4365 * array. By convention, we've been passed
4366 * what amounts to a CSWIDTH definition. We
4367 * actually NEED the number of bytes for
4370 tp
->t_maxeuc
= 0; /* reset to say we're NOT */
4372 tp
->t_state
&= ~TS_MEUC
;
4374 * We'll set TS_MEUC if we're doing
4375 * multi-column OR multi- byte OR both. It
4376 * makes things easier... NOTE: If we fail
4377 * to get the buffer we need to hold display
4378 * widths, then DON'T let the TS_MEUC bit get
4381 for (i
= 0; i
< 4; i
++) {
4382 if (tp
->eucwioc
.eucw
[i
] > tp
->t_maxeuc
)
4383 tp
->t_maxeuc
= tp
->eucwioc
.eucw
[i
];
4384 if (tp
->eucwioc
.scrw
[i
] > 1)
4385 tp
->t_state
|= TS_MEUC
;
4387 if ((tp
->t_maxeuc
> 1) || (tp
->t_state
& TS_MEUC
)) {
4388 if (!tp
->t_eucp_mp
) {
4389 if ((tp
->t_eucp_mp
= allocb(_TTY_BUFSIZ
,
4390 BPRI_HI
)) == NULL
) {
4392 tp
->t_state
&= ~TS_MEUC
;
4394 "Can't allocate eucp_mp");
4395 miocnak(q
, mp
, 0, ENOSR
);
4399 * here, if there's junk in
4400 * the canonical buffer, then
4401 * move the eucp pointer past
4402 * it, so we don't run off
4403 * the beginning. This is a
4404 * total botch, but will
4405 * hopefully keep stuff from
4406 * getting too messed up
4407 * until the user flushes
4412 tp
->t_eucp_mp
->b_rptr
;
4413 for (i
= tp
->t_msglen
; i
; i
--)
4417 tp
->t_eucp_mp
->b_rptr
;
4420 /* doing multi-byte handling */
4421 tp
->t_state
|= TS_MEUC
;
4423 } else if (tp
->t_eucp_mp
) {
4424 freemsg(tp
->t_eucp_mp
);
4425 tp
->t_eucp_mp
= NULL
;
4430 * Save the EUC width data we have at
4431 * the t_csdata, set t_csdata.codeset_type to
4432 * EUC one, and, switch the codeset methods at
4435 bzero(&tp
->t_csdata
.eucpc_data
,
4436 (sizeof (ldterm_eucpc_data_t
) *
4437 LDTERM_CS_MAX_CODESETS
));
4438 tp
->t_csdata
.eucpc_data
[0].byte_length
=
4439 tp
->eucwioc
.eucw
[1];
4440 tp
->t_csdata
.eucpc_data
[0].screen_width
=
4441 tp
->eucwioc
.scrw
[1];
4442 tp
->t_csdata
.eucpc_data
[1].byte_length
=
4443 tp
->eucwioc
.eucw
[2];
4444 tp
->t_csdata
.eucpc_data
[1].screen_width
=
4445 tp
->eucwioc
.scrw
[2];
4446 tp
->t_csdata
.eucpc_data
[2].byte_length
=
4447 tp
->eucwioc
.eucw
[3];
4448 tp
->t_csdata
.eucpc_data
[2].screen_width
=
4449 tp
->eucwioc
.scrw
[3];
4450 tp
->t_csdata
.version
= LDTERM_DATA_VERSION
;
4451 tp
->t_csdata
.codeset_type
= LDTERM_CS_TYPE_EUC
;
4453 * We are not using the 'csinfo_num' anyway if the
4454 * current codeset type is EUC. So, set it to
4455 * the maximum possible.
4457 tp
->t_csdata
.csinfo_num
=
4458 LDTERM_CS_TYPE_EUC_MAX_SUBCS
;
4459 if (tp
->t_csdata
.locale_name
!= (char *)NULL
) {
4460 kmem_free(tp
->t_csdata
.locale_name
,
4461 strlen(tp
->t_csdata
.locale_name
) + 1);
4462 tp
->t_csdata
.locale_name
= (char *)NULL
;
4464 tp
->t_csmethods
= cs_methods
[LDTERM_CS_TYPE_EUC
];
4467 * If we are able to allocate two blocks (the
4468 * iocblk and the associated data), then pass
4469 * it downstream, otherwise we'll need to NAK
4470 * it, and drop whatever we WERE able to
4473 if ((dmp
= mkiocb(EUC_WSET
)) == NULL
) {
4474 miocnak(q
, mp
, 0, ENOSR
);
4477 if ((dmp_cont
= allocb(EUCSIZE
, BPRI_HI
)) == NULL
) {
4479 miocnak(q
, mp
, 0, ENOSR
);
4484 * We got both buffers. Copy out the EUC
4485 * information (as we received it, not what
4486 * we're using!) & pass it on.
4488 bcopy(mp
->b_cont
->b_rptr
, dmp_cont
->b_rptr
, EUCSIZE
);
4489 dmp_cont
->b_wptr
+= EUCSIZE
;
4490 dmp
->b_cont
= dmp_cont
;
4491 dmp
->b_datap
->db_type
= M_CTL
;
4492 dmp_cont
->b_datap
->db_type
= M_DATA
;
4493 riocp
= (struct iocblk
*)dmp
->b_rptr
;
4494 riocp
->ioc_count
= EUCSIZE
;
4498 * Now ACK the ioctl.
4501 miocack(q
, mp
, 0, 0);
4506 error
= miocpullup(mp
, sizeof (struct eucioc
));
4508 miocnak(q
, mp
, 0, error
);
4511 euciocp
= (struct eucioc
*)mp
->b_cont
->b_rptr
;
4512 cp_eucwioc(&tp
->eucwioc
, euciocp
, EUCOUT
);
4514 miocack(q
, mp
, EUCSIZE
, 0);
4518 error
= miocpullup(mp
, sizeof (ldterm_cs_data_user_t
));
4520 miocnak(q
, mp
, 0, error
);
4524 csdp
= (ldterm_cs_data_user_t
*)mp
->b_cont
->b_rptr
;
4526 /* Validate the codeset data provided. */
4527 if (csdp
->version
> LDTERM_DATA_VERSION
||
4528 csdp
->codeset_type
< LDTERM_CS_TYPE_MIN
||
4529 csdp
->codeset_type
> LDTERM_CS_TYPE_MAX
) {
4530 miocnak(q
, mp
, 0, ERANGE
);
4534 if ((csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
&&
4535 csdp
->csinfo_num
> LDTERM_CS_TYPE_EUC_MAX_SUBCS
) ||
4536 (csdp
->codeset_type
== LDTERM_CS_TYPE_PCCS
&&
4537 (csdp
->csinfo_num
< LDTERM_CS_TYPE_PCCS_MIN_SUBCS
||
4538 csdp
->csinfo_num
> LDTERM_CS_TYPE_PCCS_MAX_SUBCS
))) {
4539 miocnak(q
, mp
, 0, ERANGE
);
4543 maxbytelen
= maxscreenlen
= 0;
4544 if (csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
) {
4545 for (i
= 0; i
< LDTERM_CS_TYPE_EUC_MAX_SUBCS
; i
++) {
4546 if (csdp
->eucpc_data
[i
].byte_length
>
4548 csdp
->eucpc_data
[i
].screen_width
>
4550 miocnak(q
, mp
, 0, ERANGE
);
4554 if (csdp
->eucpc_data
[i
].byte_length
>
4557 csdp
->eucpc_data
[i
].byte_length
;
4558 if (csdp
->eucpc_data
[i
].screen_width
>
4561 csdp
->eucpc_data
[i
].screen_width
;
4563 /* POSIX/C locale? */
4564 if (maxbytelen
== 0 && maxscreenlen
== 0)
4565 maxbytelen
= maxscreenlen
= 1;
4566 } else if (csdp
->codeset_type
== LDTERM_CS_TYPE_PCCS
) {
4567 for (i
= 0; i
< LDTERM_CS_MAX_CODESETS
; i
++) {
4568 if (csdp
->eucpc_data
[i
].byte_length
>
4569 LDTERM_CS_MAX_BYTE_LENGTH
) {
4570 miocnak(q
, mp
, 0, ERANGE
);
4573 if (csdp
->eucpc_data
[i
].byte_length
>
4576 csdp
->eucpc_data
[i
].byte_length
;
4577 if (csdp
->eucpc_data
[i
].screen_width
>
4580 csdp
->eucpc_data
[i
].screen_width
;
4582 } else if (csdp
->codeset_type
== LDTERM_CS_TYPE_UTF8
) {
4588 if (csdp
->locale_name
) {
4589 for (i
= 0; i
< MAXNAMELEN
; i
++)
4590 if (csdp
->locale_name
[i
] == '\0')
4593 * We cannot have any string that is not NULL byte
4596 if (i
>= MAXNAMELEN
) {
4597 miocnak(q
, mp
, 0, ERANGE
);
4601 locale_name_sz
= i
+ 1;
4605 * As the final check, if there was invalid codeset_type
4606 * given, or invalid byte_length was specified, it's an error.
4608 if (maxbytelen
<= 0 || maxscreenlen
<= 0) {
4609 miocnak(q
, mp
, 0, ERANGE
);
4613 /* Do the switching. */
4614 tp
->t_maxeuc
= maxbytelen
;
4615 tp
->t_state
&= ~TS_MEUC
;
4616 if (maxbytelen
> 1 || maxscreenlen
> 1) {
4617 if (!tp
->t_eucp_mp
) {
4618 if (!(tp
->t_eucp_mp
= allocb(_TTY_BUFSIZ
,
4621 "Can't allocate eucp_mp");
4622 miocnak(q
, mp
, 0, ENOSR
);
4626 * If there's junk in the canonical buffer,
4627 * then move the eucp pointer past it,
4628 * so we don't run off the beginning. This is
4629 * a total botch, but will hopefully keep
4630 * stuff from getting too messed up until
4631 * the user flushes this line!
4634 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
4635 for (i
= tp
->t_msglen
; i
; i
--)
4638 tp
->t_eucp
= tp
->t_eucp_mp
->b_rptr
;
4643 * We only set TS_MEUC for a multibyte/multi-column
4646 tp
->t_state
|= TS_MEUC
;
4648 tp
->t_csdata
.version
= csdp
->version
;
4649 tp
->t_csdata
.codeset_type
= csdp
->codeset_type
;
4650 tp
->t_csdata
.csinfo_num
= csdp
->csinfo_num
;
4651 bcopy(csdp
->eucpc_data
, tp
->t_csdata
.eucpc_data
,
4652 sizeof (ldterm_eucpc_data_t
) *
4653 LDTERM_CS_MAX_CODESETS
);
4654 tp
->t_csmethods
= cs_methods
[csdp
->codeset_type
];
4656 if (csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
) {
4657 tp
->eucwioc
.eucw
[0] = 1;
4658 tp
->eucwioc
.scrw
[0] = 1;
4660 tp
->eucwioc
.eucw
[1] =
4661 csdp
->eucpc_data
[0].byte_length
;
4662 tp
->eucwioc
.scrw
[1] =
4663 csdp
->eucpc_data
[0].screen_width
;
4665 tp
->eucwioc
.eucw
[2] =
4666 csdp
->eucpc_data
[1].byte_length
+ 1;
4667 tp
->eucwioc
.scrw
[2] =
4668 csdp
->eucpc_data
[1].screen_width
;
4670 tp
->eucwioc
.eucw
[3] =
4671 csdp
->eucpc_data
[2].byte_length
+ 1;
4672 tp
->eucwioc
.scrw
[3] =
4673 csdp
->eucpc_data
[2].screen_width
;
4676 * We are not going to use this data
4677 * structure. So, clear it. Also, stty(1) will
4678 * make use of the cleared tp->eucwioc when
4679 * it prints out codeset width setting.
4681 bzero(&tp
->eucwioc
, EUCSIZE
);
4685 * If this codeset is a single byte codeset that
4686 * requires only single display column for all
4687 * characters, we switch to default EUC codeset
4688 * methods and data setting.
4691 if (tp
->t_eucp_mp
) {
4692 freemsg(tp
->t_eucp_mp
);
4693 tp
->t_eucp_mp
= NULL
;
4697 bzero(&tp
->eucwioc
, EUCSIZE
);
4698 tp
->eucwioc
.eucw
[0] = 1;
4699 tp
->eucwioc
.scrw
[0] = 1;
4700 if (tp
->t_csdata
.locale_name
!= (char *)NULL
) {
4701 kmem_free(tp
->t_csdata
.locale_name
,
4702 strlen(tp
->t_csdata
.locale_name
) + 1);
4704 tp
->t_csdata
= default_cs_data
;
4705 tp
->t_csmethods
= cs_methods
[LDTERM_CS_TYPE_EUC
];
4708 /* Copy over locale_name. */
4709 if (tp
->t_csdata
.locale_name
!= (char *)NULL
) {
4710 kmem_free(tp
->t_csdata
.locale_name
,
4711 strlen(tp
->t_csdata
.locale_name
) + 1);
4713 if (locale_name_sz
> 1) {
4714 tp
->t_csdata
.locale_name
= (char *)kmem_alloc(
4715 locale_name_sz
, KM_SLEEP
);
4716 (void) strcpy(tp
->t_csdata
.locale_name
,
4719 tp
->t_csdata
.locale_name
= (char *)NULL
;
4723 * Now ACK the ioctl.
4726 miocack(q
, mp
, 0, 0);
4730 error
= miocpullup(mp
, sizeof (ldterm_cs_data_user_t
));
4732 miocnak(q
, mp
, 0, error
);
4736 csdp
= (ldterm_cs_data_user_t
*)mp
->b_cont
->b_rptr
;
4738 csdp
->version
= tp
->t_csdata
.version
;
4739 csdp
->codeset_type
= tp
->t_csdata
.codeset_type
;
4740 csdp
->csinfo_num
= tp
->t_csdata
.csinfo_num
;
4741 csdp
->pad
= tp
->t_csdata
.pad
;
4742 if (tp
->t_csdata
.locale_name
) {
4743 (void) strcpy(csdp
->locale_name
,
4744 tp
->t_csdata
.locale_name
);
4746 csdp
->locale_name
[0] = '\0';
4748 bcopy(tp
->t_csdata
.eucpc_data
, csdp
->eucpc_data
,
4749 sizeof (ldterm_eucpc_data_t
) * LDTERM_CS_MAX_CODESETS
);
4751 * If the codeset is an EUC codeset and if it has 2nd and/or
4752 * 3rd supplementary codesets, we subtract one from each
4753 * byte length of the supplementary codesets. This is
4754 * because single shift characters, SS2 and SS3, are not
4755 * included in the byte lengths in the user space.
4757 if (csdp
->codeset_type
== LDTERM_CS_TYPE_EUC
) {
4758 if (csdp
->eucpc_data
[1].byte_length
)
4759 csdp
->eucpc_data
[1].byte_length
-= 1;
4760 if (csdp
->eucpc_data
[2].byte_length
)
4761 csdp
->eucpc_data
[2].byte_length
-= 1;
4764 miocack(q
, mp
, sizeof (ldterm_cs_data_user_t
), 0);
4768 tp
->t_state
|= TS_ISPTSTTY
;
4778 * Send an M_SETOPTS message upstream if any mode changes are being
4779 * made that affect the stream head options. returns -1 if allocb
4780 * fails, else returns 0.
4783 chgstropts(struct termios
*oldmodep
, ldtermstd_state_t
*tp
, queue_t
*q
)
4785 struct stroptions optbuf
;
4788 optbuf
.so_flags
= 0;
4789 if ((oldmodep
->c_lflag
^ tp
->t_modes
.c_lflag
) & ICANON
) {
4791 * Canonical mode is changing state; switch the
4792 * stream head to message-nondiscard or byte-stream
4793 * mode. Also, rerun the service procedure so it can
4794 * change its mind about whether to send data
4797 if (tp
->t_modes
.c_lflag
& ICANON
) {
4798 DEBUG4(("CHANGING TO CANON MODE\n"));
4799 optbuf
.so_flags
= SO_READOPT
|SO_MREADOFF
;
4800 optbuf
.so_readopt
= RMSGN
;
4803 * if there is a pending raw mode timeout,
4808 * Clear VMIN/VTIME state, cancel timers
4810 vmin_satisfied(q
, tp
, 0);
4812 DEBUG4(("CHANGING TO RAW MODE\n"));
4813 optbuf
.so_flags
= SO_READOPT
|SO_MREADON
;
4814 optbuf
.so_readopt
= RNORM
;
4817 if ((oldmodep
->c_lflag
^ tp
->t_modes
.c_lflag
) & TOSTOP
) {
4819 * The "stop on background write" bit is changing.
4821 if (tp
->t_modes
.c_lflag
& TOSTOP
)
4822 optbuf
.so_flags
|= SO_TOSTOP
;
4824 optbuf
.so_flags
|= SO_TONSTOP
;
4826 if (optbuf
.so_flags
!= 0) {
4827 if ((bp
= allocb(sizeof (struct stroptions
), BPRI_HI
)) ==
4831 *(struct stroptions
*)bp
->b_wptr
= optbuf
;
4832 bp
->b_wptr
+= sizeof (struct stroptions
);
4833 bp
->b_datap
->db_type
= M_SETOPTS
;
4834 DEBUG4(("M_SETOPTS to stream head\n"));
4842 * Called when an M_IOCACK message is seen on the read queue;
4843 * modifies the data being returned, if necessary, and passes the
4847 ldterm_ioctl_reply(queue_t
*q
, mblk_t
*mp
)
4849 ldtermstd_state_t
*tp
;
4850 struct iocblk
*iocp
;
4852 iocp
= (struct iocblk
*)mp
->b_rptr
;
4853 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4855 switch (iocp
->ioc_cmd
) {
4860 * Get current parameters and return them to
4861 * stream head eventually.
4863 struct termios
*cb
=
4864 (struct termios
*)mp
->b_cont
->b_rptr
;
4867 * cflag has cflags sent upstream by the
4870 tcflag_t cflag
= cb
->c_cflag
;
4874 cb
->c_cflag
= cflag
; /* set by driver */
4881 * Old-style "ioctl" to get current
4882 * parameters and return them to stream head
4886 (struct termio
*)mp
->b_cont
->b_rptr
;
4888 cb
->c_iflag
= tp
->t_amodes
.c_iflag
; /* all except the */
4889 cb
->c_oflag
= tp
->t_amodes
.c_oflag
; /* cb->c_cflag */
4890 cb
->c_lflag
= tp
->t_amodes
.c_lflag
;
4892 if (cb
->c_cflag
== 0) /* not set by driver */
4893 cb
->c_cflag
= tp
->t_amodes
.c_cflag
;
4896 bcopy(tp
->t_amodes
.c_cc
, cb
->c_cc
, NCC
);
4905 * A VMIN/VTIME request has been satisfied. Cancel outstanding timers
4906 * if they exist, clear TS_MREAD state, and send upstream. If a NULL
4907 * queue ptr is passed, just reset VMIN/VTIME state.
4910 vmin_satisfied(queue_t
*q
, ldtermstd_state_t
*tp
, int sendup
)
4913 if (tp
->t_vtid
!= 0) {
4914 DEBUG4(("vmin_satisfied: cancelled timer id %d\n", tp
->t_vtid
));
4915 (void) quntimeout(q
, tp
->t_vtid
);
4919 if (tp
->t_msglen
== 0 && V_MIN
) {
4921 DEBUG4(("vmin_satisfied: data swiped, msglen = 0\n"));
4923 if ((!q
->q_first
) ||
4924 (q
->q_first
->b_datap
->db_type
!= M_DATA
) ||
4925 (tp
->t_msglen
>= LDCHUNK
)) {
4926 ldterm_msg_upstream(q
, tp
);
4927 DEBUG4(("vmin_satisfied: delivering data\n"));
4932 DEBUG4(("vmin_satisfied: VMIN/TIME state reset\n"));
4934 tp
->t_state
&= ~TS_MREAD
;
4938 vmin_settimer(queue_t
*q
)
4940 ldtermstd_state_t
*tp
;
4942 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4945 * Don't start any time bombs.
4947 if (tp
->t_state
& TS_CLOSE
)
4951 * tp->t_vtid should NOT be set here unless VMIN > 0 and
4955 if (V_MIN
&& V_TIME
) {
4957 DEBUG4(("vmin_settimer: timer restarted, old tid=%d\n",
4961 DEBUG4(("vmin_settimer: tid = %d was still active!\n",
4964 (void) quntimeout(q
, tp
->t_vtid
);
4967 tp
->t_vtid
= qtimeout(q
, vmin_timed_out
, q
,
4968 (clock_t)(V_TIME
* (hz
/ 10)));
4969 DEBUG4(("vmin_settimer: timer started, tid = %d\n", tp
->t_vtid
));
4974 * BRRrrringgg!! VTIME was satisfied instead of VMIN
4977 vmin_timed_out(void *arg
)
4980 ldtermstd_state_t
*tp
;
4982 tp
= (ldtermstd_state_t
*)q
->q_ptr
;
4984 DEBUG4(("vmin_timed_out: tid = %d\n", tp
->t_vtid
));
4985 /* don't call untimeout now that we are in the timeout */
4987 vmin_satisfied(q
, tp
, 1);
4992 * Routine to adjust termios flags to be processed by the line
4993 * discipline. Driver below sends a termios structure, with the flags
4994 * the driver intends to process. XOR'ing the driver sent termios
4995 * structure with current termios structure with the default values
4996 * (or set by ioctls from userland), we come up with a new termios
4997 * structrue, the flags of which will be used by the line discipline
4998 * in processing input and output. On return from this routine, we
4999 * will have the following fields set in tp structure -->
5000 * tp->t_modes: modes the line discipline will process tp->t_amodes:
5001 * modes the user process thinks the line discipline is processing
5005 ldterm_adjust_modes(ldtermstd_state_t
*tp
)
5008 DEBUG6(("original iflag = %o\n", tp
->t_modes
.c_iflag
));
5009 tp
->t_modes
.c_iflag
= tp
->t_amodes
.c_iflag
& ~(tp
->t_dmodes
.c_iflag
);
5010 tp
->t_modes
.c_oflag
= tp
->t_amodes
.c_oflag
& ~(tp
->t_dmodes
.c_oflag
);
5011 tp
->t_modes
.c_lflag
= tp
->t_amodes
.c_lflag
& ~(tp
->t_dmodes
.c_lflag
);
5012 DEBUG6(("driver iflag = %o\n", tp
->t_dmodes
.c_iflag
));
5013 DEBUG6(("apparent iflag = %o\n", tp
->t_amodes
.c_iflag
));
5014 DEBUG6(("effective iflag = %o\n", tp
->t_modes
.c_iflag
));
5016 /* No negotiation of clfags c_cc array special characters */
5018 * Copy from amodes to modes already done by TCSETA/TCSETS
5025 * Erase one multi-byte character. If TS_MEUC is set AND this
5026 * is a multi-byte character, then this should be called instead of
5027 * ldterm_erase. "ldterm_erase" will handle ASCII nicely, thank you.
5029 * We'd better be pointing to the last byte. If we aren't, it will get
5033 ldterm_csi_erase(queue_t
*q
, size_t ebsize
, ldtermstd_state_t
*tp
)
5036 uchar_t
*p
, *bottom
;
5037 uchar_t u8
[LDTERM_CS_MAX_BYTE_LENGTH
];
5042 if (tp
->t_eucleft
) {
5043 /* XXX Ick. We're in the middle of an EUC! */
5044 /* What to do now? */
5046 return; /* ignore it??? */
5048 bottom
= tp
->t_eucp_mp
->b_rptr
;
5049 p
= tp
->t_eucp
- 1; /* previous byte */
5052 ung
= 1; /* number of bytes to un-get from buffer */
5054 * go through the buffer until we find the beginning of the
5057 while ((*p
== 0) && (p
> bottom
)) {
5063 * Now, "ung" is the number of bytes to unget from the buffer
5064 * and "*p" is the disp width of it. Fool "ldterm_rubout"
5065 * into thinking we're rubbing out ASCII characters. Do that
5066 * for the display width of the character.
5068 * Also we accumulate bytes of the character so that if the character
5069 * is a UTF-8 character, we will get the display width of the UTF-8
5072 if (ung
>= LDTERM_CS_MAX_BYTE_LENGTH
) {
5073 j
= len
= LDTERM_CS_MAX_BYTE_LENGTH
;
5077 for (i
= 0; i
< ung
; i
++) { /* remove from buf */
5078 if ((c
= ldterm_unget(tp
)) != (-1)) {
5081 u8
[--j
] = (uchar_t
)c
;
5084 if (*p
== UNKNOWN_WIDTH
) {
5085 if (tp
->t_csdata
.codeset_type
== LDTERM_CS_TYPE_UTF8
) {
5086 *p
= ldterm_utf8_width(u8
, len
);
5091 for (i
= 0; i
< (int)*p
; i
++) /* remove from screen */
5092 ldterm_rubout(' ', q
, ebsize
, tp
);
5094 * Adjust the parallel array pointer. Zero out the contents
5095 * of parallel array for this position, just to make sure...
5103 * This is kind of a safety valve. Whenever we see a bad sequence
5104 * come up, we call eucwarn. It just tallies the junk until a
5105 * threshold is reached. Then it prints ONE message on the console
5106 * and not any more. Hopefully, we can catch garbage; maybe it will
5107 * be useful to somebody.
5110 ldterm_eucwarn(ldtermstd_state_t
*tp
)
5114 if ((tp
->t_eucwarn
> EUC_WARNCNT
) && !(tp
->t_state
& TS_WARNED
)) {
5116 "ldterm: tty at addr %p in multi-byte mode --",
5119 "Over %d bad EUC characters this session", EUC_WARNCNT
);
5120 tp
->t_state
|= TS_WARNED
;
5127 * Copy an "eucioc_t" structure. We use the structure with
5128 * incremented values for Codesets 2 & 3. The specification in
5129 * eucioctl is that the sames values as the CSWIDTH definition at
5130 * user level are passed to us. When we copy it "in" to ourselves, we
5131 * do the increment. That allows us to avoid treating each character
5132 * set separately for "t_eucleft" purposes. When we copy it "out" to
5133 * return it to the user, we decrement the values so the user gets
5134 * what it expects, and it matches CSWIDTH in the environment (if
5135 * things are consistent!).
5138 cp_eucwioc(eucioc_t
*from
, eucioc_t
*to
, int dir
)
5140 bcopy(from
, to
, EUCSIZE
);
5141 if (dir
== EUCOUT
) { /* copying out to user */
5146 } else { /* copying in */
5156 * Take the first byte of a multi-byte, or an ASCII char. Return its
5157 * codeset. If it's NOT the first byte of an EUC, then the return
5158 * value may be garbage, as it's probably not SS2 or SS3, and
5159 * therefore must be in codeset 1. Another bizarre catch here is the
5160 * fact that we don't do anything about the "C1" control codes. In
5161 * real life, we should; but nobody's come up with a good way of
5166 ldterm_codeset(uchar_t codeset_type
, uchar_t c
)
5172 if (codeset_type
!= LDTERM_CS_TYPE_EUC
)
5185 /* The following two functions are additional EUC codeset specific methods. */
5187 * ldterm_dispwidth - Take the first byte of an EUC (or ASCII) and
5188 * return the display width. Since this is intended mostly for
5189 * multi-byte handling, it returns EUC_TWIDTH for tabs so they can be
5190 * differentiated from EUC characters (assumption: EUC require fewer
5191 * than 255 columns). Also, if it's a backspace and !flag, it
5192 * returns EUC_BSWIDTH. Newline & CR also depend on flag. This
5193 * routine SHOULD be cleaner than this, but we have the situation
5194 * where we may or may not be counting control characters as having a
5195 * column width. Therefore, the computation of ASCII is pretty messy.
5196 * The caller will be storing the value, and then switching on it
5197 * when it's used. We really should define the EUC_TWIDTH and other
5198 * constants in a header so that the routine could be used in other
5199 * modules in the kernel.
5202 __ldterm_dispwidth_euc(uchar_t c
, void *p
, int mode
)
5204 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5210 return (EUC_TWIDTH
);
5212 return (mode
? 2 : EUC_BSWIDTH
);
5214 return (EUC_NLWIDTH
);
5216 return (mode
? 2 : EUC_CRWIDTH
);
5218 return (mode
? 2 : 0);
5225 return (tp
->eucwioc
.scrw
[2]);
5227 return (tp
->eucwioc
.scrw
[3]);
5229 return (tp
->eucwioc
.scrw
[1]);
5234 * ldterm_memwidth_euc - Take the first byte of an EUC (or an ASCII char)
5235 * and return its memory width. The routine could have been
5236 * implemented to use only the codeset number, but that would require
5237 * the caller to have that value available. Perhaps the user doesn't
5238 * want to make the extra call or keep the value of codeset around.
5239 * Therefore, we use the actual character with which they're
5240 * concerned. This should never be called with anything but the
5241 * first byte of an EUC, otherwise it will return a garbage value.
5244 __ldterm_memwidth_euc(uchar_t c
, void *p
)
5246 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5252 return (tp
->eucwioc
.eucw
[2]);
5254 return (tp
->eucwioc
.eucw
[3]);
5256 return (tp
->eucwioc
.eucw
[1]);
5261 /* The following two functions are PCCS codeset specific methods. */
5263 __ldterm_dispwidth_pccs(uchar_t c
, void *p
, int mode
)
5265 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5272 return (EUC_TWIDTH
);
5274 return (mode
? 2 : EUC_BSWIDTH
);
5276 return (EUC_NLWIDTH
);
5278 return (mode
? 2 : EUC_CRWIDTH
);
5280 return (mode
? 2 : 0);
5286 for (i
= 0; i
< tp
->t_csdata
.csinfo_num
; i
++) {
5287 if (c
>= tp
->t_csdata
.eucpc_data
[i
].msb_start
&&
5288 c
<= tp
->t_csdata
.eucpc_data
[i
].msb_end
)
5289 return (tp
->t_csdata
.eucpc_data
[i
].screen_width
);
5293 * If this leading byte is not in the range list, either provided
5294 * locale data is not sufficient or we encountered an invalid
5295 * character. We return 1 in this case as a fallback value.
5301 __ldterm_memwidth_pccs(uchar_t c
, void *p
)
5303 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5306 for (i
= 0; i
< tp
->t_csdata
.csinfo_num
; i
++) {
5307 if (c
>= tp
->t_csdata
.eucpc_data
[i
].msb_start
&&
5308 c
<= tp
->t_csdata
.eucpc_data
[i
].msb_end
)
5309 return (tp
->t_csdata
.eucpc_data
[i
].byte_length
);
5313 * If this leading byte is not in the range list, either provided
5314 * locale data is not sufficient or we encountered an invalid
5315 * character. We return 1 in this case as a fallback value.
5321 /* The following two functions are UTF-8 codeset specific methods. */
5323 __ldterm_dispwidth_utf8(uchar_t c
, void *p
, int mode
)
5325 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5331 return (EUC_TWIDTH
);
5333 return (mode
? 2 : EUC_BSWIDTH
);
5335 return (EUC_NLWIDTH
);
5337 return (mode
? 2 : EUC_CRWIDTH
);
5339 return (mode
? 2 : 0);
5345 /* This is to silence the lint. */
5346 if (tp
->t_csdata
.codeset_type
!= LDTERM_CS_TYPE_UTF8
)
5350 * If it is a valid leading byte of a UTF-8 character, we set
5351 * the width as 'UNKNOWN_WIDTH' for now. We need to have all
5352 * the bytes to figure out the display width.
5354 if (c
>= (uchar_t
)0xc0 && c
<= (uchar_t
)0xfd)
5355 return (UNKNOWN_WIDTH
);
5358 * If it is an invalid leading byte, we just do our best by
5359 * giving the display width of 1.
5366 __ldterm_memwidth_utf8(uchar_t c
, void *p
)
5368 ldtermstd_state_t
*tp
= (ldtermstd_state_t
*)p
;
5372 * If the codeset type doesn't match, we treat them as
5373 * an illegal character and return 1.
5375 if (tp
->t_csdata
.codeset_type
!= LDTERM_CS_TYPE_UTF8
)
5378 len
= u8_number_of_bytes
[c
];
5381 * If this is a start of an illegal character, we treat
5382 * such as an 1 byte character and screen out.
5384 return ((len
<= 0) ? 1 : len
);
5388 ldterm_utf8_width(uchar_t
*u8
, int length
)
5397 j
= u8_number_of_bytes
[u8
[0]] - 1;
5400 * If the UTF-8 character is out of UTF-16 code range, or,
5401 * if it is either an ASCII character or an invalid leading byte for
5402 * a UTF-8 character, return 1.
5404 if (length
> 4 || j
<= 0)
5407 intcode
= u8
[0] & u8_masks_tbl
[j
];
5408 for (i
= 1; j
> 0; j
--, i
++) {
5410 * The following additional checking is needed to conform to
5411 * the "UTF-8 Corrigendum" introduced at the Unicode 3.1 and
5412 * then updated one more time at the Unicode 3.2.
5415 if (u8
[i
] < u8_valid_min_2nd_byte
[u8
[0]] ||
5416 u8
[i
] > u8_valid_max_2nd_byte
[u8
[0]])
5418 } else if (u8
[i
] < (uchar_t
)LDTERM_CS_TYPE_UTF8_MIN_BYTE
||
5419 u8
[i
] > (uchar_t
)LDTERM_CS_TYPE_UTF8_MAX_BYTE
)
5423 * All subsequent bytes of UTF-8 character has the following
5428 * hence left shift six bits to make space and then get
5429 * six bits from the new byte.
5431 intcode
= (intcode
<< LDTERM_CS_TYPE_UTF8_SHIFT_BITS
) |
5432 (u8
[i
] & LDTERM_CS_TYPE_UTF8_BIT_MASK
);
5436 if (intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P00
) {
5437 /* Basic Multilingual Plane. */
5442 i
= ldterm_ucode
[0][i
].u0
;
5445 i
= ldterm_ucode
[0][i
].u1
;
5448 i
= ldterm_ucode
[0][i
].u2
;
5451 i
= ldterm_ucode
[0][i
].u3
;
5454 } else if (intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P01
) {
5455 /* Secondary Multilingual Plane. */
5456 intcode
= intcode
& (uint_t
)0xffff;
5461 i
= ldterm_ucode
[1][i
].u0
;
5464 i
= ldterm_ucode
[1][i
].u1
;
5467 i
= ldterm_ucode
[1][i
].u2
;
5470 i
= ldterm_ucode
[1][i
].u3
;
5473 } else if ((intcode
>= LDTERM_CS_TYPE_UTF8_MIN_CJKEXTB
&&
5474 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_CJKEXTB
) ||
5475 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_CJKCOMP
&&
5476 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_CJKCOMP
) ||
5477 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_P15
&&
5478 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P15
) ||
5479 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_P16
&&
5480 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P16
)) {
5482 * Supplementary Plane for CJK Ideographs and
5483 * Private Use Planes.
5486 } else if ((intcode
>= LDTERM_CS_TYPE_UTF8_MIN_P14
&&
5487 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_P14
) ||
5488 (intcode
>= LDTERM_CS_TYPE_UTF8_MIN_VARSEL
&&
5489 intcode
<= LDTERM_CS_TYPE_UTF8_MAX_VARSEL
)) {
5491 * Some Special Purpose Plane characters:
5492 * These are like control characters and not printable.
5498 * We return the display width of 1 for all character code points
5499 * that we didn't catch from the above logic and also for combining
5500 * and conjoining characters with width value of zero.
5502 * In particular, the reason why we are returning 1 for combining
5503 * and conjoining characters is because the GUI-based terminal
5504 * emulators are not yet capable of properly handling such characters
5505 * and in most of the cases, they just treat such characters as if
5506 * they occupy a display cell. If the terminal emulators are capable of
5507 * handling the characters correctly, then, this logic of returning
5508 * 1 should be revisited and changed. See CR 6660526 for more
5511 return ((i
== 0) ? '\1' : (uchar_t
)i
);