tty.c revision 1.6 1 1.6 scottr /* $NetBSD: tty.c,v 1.6 1997/10/20 08:07:56 scottr Exp $ */
2 1.2 lukem
3 1.1 cgd /*-
4 1.1 cgd * Copyright (c) 1992, 1993
5 1.1 cgd * The Regents of the University of California. All rights reserved.
6 1.1 cgd *
7 1.1 cgd * This code is derived from software contributed to Berkeley by
8 1.1 cgd * Christos Zoulas of Cornell University.
9 1.1 cgd *
10 1.1 cgd * Redistribution and use in source and binary forms, with or without
11 1.1 cgd * modification, are permitted provided that the following conditions
12 1.1 cgd * are met:
13 1.1 cgd * 1. Redistributions of source code must retain the above copyright
14 1.1 cgd * notice, this list of conditions and the following disclaimer.
15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 cgd * notice, this list of conditions and the following disclaimer in the
17 1.1 cgd * documentation and/or other materials provided with the distribution.
18 1.1 cgd * 3. All advertising materials mentioning features or use of this software
19 1.1 cgd * must display the following acknowledgement:
20 1.1 cgd * This product includes software developed by the University of
21 1.1 cgd * California, Berkeley and its contributors.
22 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
23 1.1 cgd * may be used to endorse or promote products derived from this software
24 1.1 cgd * without specific prior written permission.
25 1.1 cgd *
26 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 1.1 cgd * SUCH DAMAGE.
37 1.1 cgd */
38 1.1 cgd
39 1.4 christos #include <sys/cdefs.h>
40 1.1 cgd #if !defined(lint) && !defined(SCCSID)
41 1.2 lukem #if 0
42 1.1 cgd static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
43 1.2 lukem #else
44 1.6 scottr __RCSID("$NetBSD: tty.c,v 1.6 1997/10/20 08:07:56 scottr Exp $");
45 1.2 lukem #endif
46 1.1 cgd #endif /* not lint && not SCCSID */
47 1.1 cgd
48 1.1 cgd /*
49 1.1 cgd * tty.c: tty interface stuff
50 1.1 cgd */
51 1.1 cgd #include "sys.h"
52 1.1 cgd #include "tty.h"
53 1.1 cgd #include "el.h"
54 1.1 cgd
55 1.1 cgd typedef struct ttymodes_t {
56 1.1 cgd char *m_name;
57 1.3 christos u_int m_value;
58 1.1 cgd int m_type;
59 1.1 cgd } ttymodes_t;
60 1.1 cgd
61 1.1 cgd typedef struct ttymap_t {
62 1.1 cgd int nch, och; /* Internal and termio rep of chars */
63 1.1 cgd el_action_t bind[3]; /* emacs, vi, and vi-cmd */
64 1.1 cgd } ttymap_t;
65 1.1 cgd
66 1.1 cgd
67 1.1 cgd private ttyperm_t ttyperm = {
68 1.1 cgd {
69 1.1 cgd { "iflag:", ICRNL, (INLCR|IGNCR) },
70 1.1 cgd { "oflag:", (OPOST|ONLCR), ONLRET },
71 1.1 cgd { "cflag:", 0, 0 },
72 1.1 cgd { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
73 1.1 cgd (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
74 1.1 cgd { "chars:", 0, 0 },
75 1.1 cgd },
76 1.1 cgd {
77 1.1 cgd { "iflag:", (INLCR|ICRNL), IGNCR },
78 1.1 cgd { "oflag:", (OPOST|ONLCR), ONLRET },
79 1.1 cgd { "cflag:", 0, 0 },
80 1.1 cgd { "lflag:", ISIG,
81 1.1 cgd (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
82 1.1 cgd { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
83 1.1 cgd C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
84 1.1 cgd C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
85 1.1 cgd },
86 1.1 cgd {
87 1.1 cgd { "iflag:", 0, IXON | IXOFF },
88 1.1 cgd { "oflag:", 0, 0 },
89 1.1 cgd { "cflag:", 0, 0 },
90 1.1 cgd { "lflag:", 0, ISIG | IEXTEN },
91 1.1 cgd { "chars:", 0, 0 },
92 1.1 cgd }
93 1.1 cgd };
94 1.1 cgd
95 1.1 cgd private ttychar_t ttychar = {
96 1.1 cgd {
97 1.1 cgd CINTR, CQUIT, CERASE, CKILL,
98 1.1 cgd CEOF, CEOL, CEOL2, CSWTCH,
99 1.1 cgd CDSWTCH, CERASE2, CSTART, CSTOP,
100 1.1 cgd CWERASE, CSUSP, CDSUSP, CREPRINT,
101 1.1 cgd CDISCARD, CLNEXT, CSTATUS, CPAGE,
102 1.1 cgd CPGOFF, CKILL2, CBRK, CMIN,
103 1.1 cgd CTIME
104 1.1 cgd },
105 1.1 cgd {
106 1.1 cgd CINTR, CQUIT, CERASE, CKILL,
107 1.1 cgd _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
108 1.1 cgd _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
109 1.1 cgd _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
110 1.1 cgd CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
111 1.1 cgd _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
112 1.1 cgd 0
113 1.1 cgd },
114 1.1 cgd {
115 1.1 cgd 0, 0, 0, 0,
116 1.1 cgd 0, 0, 0, 0,
117 1.1 cgd 0, 0, 0, 0,
118 1.1 cgd 0, 0, 0, 0,
119 1.1 cgd 0, 0, 0, 0,
120 1.1 cgd 0, 0, 0, 0,
121 1.1 cgd 0
122 1.1 cgd }
123 1.1 cgd };
124 1.1 cgd
125 1.1 cgd private ttymap_t tty_map[] = {
126 1.1 cgd #ifdef VERASE
127 1.1 cgd { C_ERASE, VERASE,
128 1.1 cgd { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
129 1.1 cgd #endif /* VERASE */
130 1.1 cgd #ifdef VERASE2
131 1.1 cgd { C_ERASE2, VERASE2,
132 1.1 cgd { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
133 1.1 cgd #endif /* VERASE2 */
134 1.1 cgd #ifdef VKILL
135 1.1 cgd { C_KILL, VKILL,
136 1.1 cgd { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
137 1.1 cgd #endif /* VKILL */
138 1.1 cgd #ifdef VKILL2
139 1.1 cgd { C_KILL2, VKILL2,
140 1.1 cgd { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
141 1.1 cgd #endif /* VKILL2 */
142 1.1 cgd #ifdef VEOF
143 1.1 cgd { C_EOF, VEOF,
144 1.1 cgd { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
145 1.1 cgd #endif /* VEOF */
146 1.1 cgd #ifdef VWERASE
147 1.1 cgd { C_WERASE, VWERASE,
148 1.1 cgd { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
149 1.1 cgd #endif /* VWERASE */
150 1.1 cgd #ifdef VREPRINT
151 1.1 cgd { C_REPRINT, VREPRINT,
152 1.1 cgd { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
153 1.1 cgd #endif /* VREPRINT */
154 1.1 cgd #ifdef VLNEXT
155 1.1 cgd { C_LNEXT, VLNEXT,
156 1.1 cgd { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
157 1.1 cgd #endif /* VLNEXT */
158 1.1 cgd { -1, -1,
159 1.1 cgd { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
160 1.1 cgd };
161 1.1 cgd
162 1.1 cgd private ttymodes_t ttymodes[] = {
163 1.1 cgd # ifdef IGNBRK
164 1.1 cgd { "ignbrk", IGNBRK, M_INP },
165 1.1 cgd # endif /* IGNBRK */
166 1.1 cgd # ifdef BRKINT
167 1.1 cgd { "brkint", BRKINT, M_INP },
168 1.1 cgd # endif /* BRKINT */
169 1.1 cgd # ifdef IGNPAR
170 1.1 cgd { "ignpar", IGNPAR, M_INP },
171 1.1 cgd # endif /* IGNPAR */
172 1.1 cgd # ifdef PARMRK
173 1.1 cgd { "parmrk", PARMRK, M_INP },
174 1.1 cgd # endif /* PARMRK */
175 1.1 cgd # ifdef INPCK
176 1.1 cgd { "inpck", INPCK, M_INP },
177 1.1 cgd # endif /* INPCK */
178 1.1 cgd # ifdef ISTRIP
179 1.1 cgd { "istrip", ISTRIP, M_INP },
180 1.1 cgd # endif /* ISTRIP */
181 1.1 cgd # ifdef INLCR
182 1.1 cgd { "inlcr", INLCR, M_INP },
183 1.1 cgd # endif /* INLCR */
184 1.1 cgd # ifdef IGNCR
185 1.1 cgd { "igncr", IGNCR, M_INP },
186 1.1 cgd # endif /* IGNCR */
187 1.1 cgd # ifdef ICRNL
188 1.1 cgd { "icrnl", ICRNL, M_INP },
189 1.1 cgd # endif /* ICRNL */
190 1.1 cgd # ifdef IUCLC
191 1.1 cgd { "iuclc", IUCLC, M_INP },
192 1.1 cgd # endif /* IUCLC */
193 1.1 cgd # ifdef IXON
194 1.1 cgd { "ixon", IXON, M_INP },
195 1.1 cgd # endif /* IXON */
196 1.1 cgd # ifdef IXANY
197 1.1 cgd { "ixany", IXANY, M_INP },
198 1.1 cgd # endif /* IXANY */
199 1.1 cgd # ifdef IXOFF
200 1.1 cgd { "ixoff", IXOFF, M_INP },
201 1.1 cgd # endif /* IXOFF */
202 1.1 cgd # ifdef IMAXBEL
203 1.1 cgd { "imaxbel",IMAXBEL,M_INP },
204 1.1 cgd # endif /* IMAXBEL */
205 1.1 cgd
206 1.1 cgd # ifdef OPOST
207 1.1 cgd { "opost", OPOST, M_OUT },
208 1.1 cgd # endif /* OPOST */
209 1.1 cgd # ifdef OLCUC
210 1.1 cgd { "olcuc", OLCUC, M_OUT },
211 1.1 cgd # endif /* OLCUC */
212 1.1 cgd # ifdef ONLCR
213 1.1 cgd { "onlcr", ONLCR, M_OUT },
214 1.1 cgd # endif /* ONLCR */
215 1.1 cgd # ifdef OCRNL
216 1.1 cgd { "ocrnl", OCRNL, M_OUT },
217 1.1 cgd # endif /* OCRNL */
218 1.1 cgd # ifdef ONOCR
219 1.1 cgd { "onocr", ONOCR, M_OUT },
220 1.1 cgd # endif /* ONOCR */
221 1.1 cgd # ifdef ONOEOT
222 1.1 cgd { "onoeot", ONOEOT, M_OUT },
223 1.1 cgd # endif /* ONOEOT */
224 1.1 cgd # ifdef ONLRET
225 1.1 cgd { "onlret", ONLRET, M_OUT },
226 1.1 cgd # endif /* ONLRET */
227 1.1 cgd # ifdef OFILL
228 1.1 cgd { "ofill", OFILL, M_OUT },
229 1.1 cgd # endif /* OFILL */
230 1.1 cgd # ifdef OFDEL
231 1.1 cgd { "ofdel", OFDEL, M_OUT },
232 1.1 cgd # endif /* OFDEL */
233 1.1 cgd # ifdef NLDLY
234 1.1 cgd { "nldly", NLDLY, M_OUT },
235 1.1 cgd # endif /* NLDLY */
236 1.1 cgd # ifdef CRDLY
237 1.1 cgd { "crdly", CRDLY, M_OUT },
238 1.1 cgd # endif /* CRDLY */
239 1.1 cgd # ifdef TABDLY
240 1.1 cgd { "tabdly", TABDLY, M_OUT },
241 1.1 cgd # endif /* TABDLY */
242 1.1 cgd # ifdef XTABS
243 1.1 cgd { "xtabs", XTABS, M_OUT },
244 1.1 cgd # endif /* XTABS */
245 1.1 cgd # ifdef BSDLY
246 1.1 cgd { "bsdly", BSDLY, M_OUT },
247 1.1 cgd # endif /* BSDLY */
248 1.1 cgd # ifdef VTDLY
249 1.1 cgd { "vtdly", VTDLY, M_OUT },
250 1.1 cgd # endif /* VTDLY */
251 1.1 cgd # ifdef FFDLY
252 1.1 cgd { "ffdly", FFDLY, M_OUT },
253 1.1 cgd # endif /* FFDLY */
254 1.1 cgd # ifdef PAGEOUT
255 1.1 cgd { "pageout",PAGEOUT,M_OUT },
256 1.1 cgd # endif /* PAGEOUT */
257 1.1 cgd # ifdef WRAP
258 1.1 cgd { "wrap", WRAP, M_OUT },
259 1.1 cgd # endif /* WRAP */
260 1.1 cgd
261 1.1 cgd # ifdef CIGNORE
262 1.1 cgd { "cignore",CIGNORE,M_CTL },
263 1.1 cgd # endif /* CBAUD */
264 1.1 cgd # ifdef CBAUD
265 1.1 cgd { "cbaud", CBAUD, M_CTL },
266 1.1 cgd # endif /* CBAUD */
267 1.1 cgd # ifdef CSTOPB
268 1.1 cgd { "cstopb", CSTOPB, M_CTL },
269 1.1 cgd # endif /* CSTOPB */
270 1.1 cgd # ifdef CREAD
271 1.1 cgd { "cread", CREAD, M_CTL },
272 1.1 cgd # endif /* CREAD */
273 1.1 cgd # ifdef PARENB
274 1.1 cgd { "parenb", PARENB, M_CTL },
275 1.1 cgd # endif /* PARENB */
276 1.1 cgd # ifdef PARODD
277 1.1 cgd { "parodd", PARODD, M_CTL },
278 1.1 cgd # endif /* PARODD */
279 1.1 cgd # ifdef HUPCL
280 1.1 cgd { "hupcl", HUPCL, M_CTL },
281 1.1 cgd # endif /* HUPCL */
282 1.1 cgd # ifdef CLOCAL
283 1.1 cgd { "clocal", CLOCAL, M_CTL },
284 1.1 cgd # endif /* CLOCAL */
285 1.1 cgd # ifdef LOBLK
286 1.1 cgd { "loblk", LOBLK, M_CTL },
287 1.1 cgd # endif /* LOBLK */
288 1.1 cgd # ifdef CIBAUD
289 1.1 cgd { "cibaud", CIBAUD, M_CTL },
290 1.1 cgd # endif /* CIBAUD */
291 1.1 cgd # ifdef CRTSCTS
292 1.1 cgd # ifdef CCTS_OFLOW
293 1.1 cgd { "ccts_oflow",CCTS_OFLOW,M_CTL },
294 1.1 cgd # else
295 1.1 cgd { "crtscts",CRTSCTS,M_CTL },
296 1.1 cgd # endif /* CCTS_OFLOW */
297 1.1 cgd # endif /* CRTSCTS */
298 1.1 cgd # ifdef CRTS_IFLOW
299 1.1 cgd { "crts_iflow",CRTS_IFLOW,M_CTL },
300 1.1 cgd # endif /* CRTS_IFLOW */
301 1.6 scottr # ifdef CDTRCTS
302 1.6 scottr { "cdtrcts",CDTRCTS,M_CTL },
303 1.6 scottr # endif /* CDTRCTS */
304 1.1 cgd # ifdef MDMBUF
305 1.1 cgd { "mdmbuf", MDMBUF, M_CTL },
306 1.1 cgd # endif /* MDMBUF */
307 1.1 cgd # ifdef RCV1EN
308 1.1 cgd { "rcv1en", RCV1EN, M_CTL },
309 1.1 cgd # endif /* RCV1EN */
310 1.1 cgd # ifdef XMT1EN
311 1.1 cgd { "xmt1en", XMT1EN, M_CTL },
312 1.1 cgd # endif /* XMT1EN */
313 1.1 cgd
314 1.1 cgd # ifdef ISIG
315 1.1 cgd { "isig", ISIG, M_LIN },
316 1.1 cgd # endif /* ISIG */
317 1.1 cgd # ifdef ICANON
318 1.1 cgd { "icanon", ICANON, M_LIN },
319 1.1 cgd # endif /* ICANON */
320 1.1 cgd # ifdef XCASE
321 1.1 cgd { "xcase", XCASE, M_LIN },
322 1.1 cgd # endif /* XCASE */
323 1.1 cgd # ifdef ECHO
324 1.1 cgd { "echo", ECHO, M_LIN },
325 1.1 cgd # endif /* ECHO */
326 1.1 cgd # ifdef ECHOE
327 1.1 cgd { "echoe", ECHOE, M_LIN },
328 1.1 cgd # endif /* ECHOE */
329 1.1 cgd # ifdef ECHOK
330 1.1 cgd { "echok", ECHOK, M_LIN },
331 1.1 cgd # endif /* ECHOK */
332 1.1 cgd # ifdef ECHONL
333 1.1 cgd { "echonl", ECHONL, M_LIN },
334 1.1 cgd # endif /* ECHONL */
335 1.1 cgd # ifdef NOFLSH
336 1.1 cgd { "noflsh", NOFLSH, M_LIN },
337 1.1 cgd # endif /* NOFLSH */
338 1.1 cgd # ifdef TOSTOP
339 1.1 cgd { "tostop", TOSTOP, M_LIN },
340 1.1 cgd # endif /* TOSTOP */
341 1.1 cgd # ifdef ECHOCTL
342 1.1 cgd { "echoctl",ECHOCTL,M_LIN },
343 1.1 cgd # endif /* ECHOCTL */
344 1.1 cgd # ifdef ECHOPRT
345 1.1 cgd { "echoprt",ECHOPRT,M_LIN },
346 1.1 cgd # endif /* ECHOPRT */
347 1.1 cgd # ifdef ECHOKE
348 1.1 cgd { "echoke", ECHOKE, M_LIN },
349 1.1 cgd # endif /* ECHOKE */
350 1.1 cgd # ifdef DEFECHO
351 1.1 cgd { "defecho",DEFECHO,M_LIN },
352 1.1 cgd # endif /* DEFECHO */
353 1.1 cgd # ifdef FLUSHO
354 1.1 cgd { "flusho", FLUSHO, M_LIN },
355 1.1 cgd # endif /* FLUSHO */
356 1.1 cgd # ifdef PENDIN
357 1.1 cgd { "pendin", PENDIN, M_LIN },
358 1.1 cgd # endif /* PENDIN */
359 1.1 cgd # ifdef IEXTEN
360 1.1 cgd { "iexten", IEXTEN, M_LIN },
361 1.1 cgd # endif /* IEXTEN */
362 1.1 cgd # ifdef NOKERNINFO
363 1.1 cgd { "nokerninfo",NOKERNINFO,M_LIN },
364 1.1 cgd # endif /* NOKERNINFO */
365 1.1 cgd # ifdef ALTWERASE
366 1.1 cgd { "altwerase",ALTWERASE,M_LIN },
367 1.1 cgd # endif /* ALTWERASE */
368 1.1 cgd # ifdef EXTPROC
369 1.1 cgd { "extproc",EXTPROC, M_LIN },
370 1.1 cgd # endif /* EXTPROC */
371 1.1 cgd
372 1.1 cgd # if defined(VINTR)
373 1.1 cgd { "intr", C_SH(C_INTR), M_CHAR },
374 1.1 cgd # endif /* VINTR */
375 1.1 cgd # if defined(VQUIT)
376 1.1 cgd { "quit", C_SH(C_QUIT), M_CHAR },
377 1.1 cgd # endif /* VQUIT */
378 1.1 cgd # if defined(VERASE)
379 1.1 cgd { "erase", C_SH(C_ERASE), M_CHAR },
380 1.1 cgd # endif /* VERASE */
381 1.1 cgd # if defined(VKILL)
382 1.1 cgd { "kill", C_SH(C_KILL), M_CHAR },
383 1.1 cgd # endif /* VKILL */
384 1.1 cgd # if defined(VEOF)
385 1.1 cgd { "eof", C_SH(C_EOF), M_CHAR },
386 1.1 cgd # endif /* VEOF */
387 1.1 cgd # if defined(VEOL)
388 1.1 cgd { "eol", C_SH(C_EOL), M_CHAR },
389 1.1 cgd # endif /* VEOL */
390 1.1 cgd # if defined(VEOL2)
391 1.1 cgd { "eol2", C_SH(C_EOL2), M_CHAR },
392 1.1 cgd # endif /* VEOL2 */
393 1.1 cgd # if defined(VSWTCH)
394 1.1 cgd { "swtch", C_SH(C_SWTCH), M_CHAR },
395 1.1 cgd # endif /* VSWTCH */
396 1.1 cgd # if defined(VDSWTCH)
397 1.1 cgd { "dswtch", C_SH(C_DSWTCH), M_CHAR },
398 1.1 cgd # endif /* VDSWTCH */
399 1.1 cgd # if defined(VERASE2)
400 1.1 cgd { "erase2", C_SH(C_ERASE2), M_CHAR },
401 1.1 cgd # endif /* VERASE2 */
402 1.1 cgd # if defined(VSTART)
403 1.1 cgd { "start", C_SH(C_START), M_CHAR },
404 1.1 cgd # endif /* VSTART */
405 1.1 cgd # if defined(VSTOP)
406 1.1 cgd { "stop", C_SH(C_STOP), M_CHAR },
407 1.1 cgd # endif /* VSTOP */
408 1.1 cgd # if defined(VWERASE)
409 1.1 cgd { "werase", C_SH(C_WERASE), M_CHAR },
410 1.1 cgd # endif /* VWERASE */
411 1.1 cgd # if defined(VSUSP)
412 1.1 cgd { "susp", C_SH(C_SUSP), M_CHAR },
413 1.1 cgd # endif /* VSUSP */
414 1.1 cgd # if defined(VDSUSP)
415 1.1 cgd { "dsusp", C_SH(C_DSUSP), M_CHAR },
416 1.1 cgd # endif /* VDSUSP */
417 1.1 cgd # if defined(VREPRINT)
418 1.1 cgd { "reprint", C_SH(C_REPRINT),M_CHAR },
419 1.1 cgd # endif /* VREPRINT */
420 1.1 cgd # if defined(VDISCARD)
421 1.1 cgd { "discard", C_SH(C_DISCARD),M_CHAR },
422 1.1 cgd # endif /* VDISCARD */
423 1.1 cgd # if defined(VLNEXT)
424 1.1 cgd { "lnext", C_SH(C_LNEXT), M_CHAR },
425 1.1 cgd # endif /* VLNEXT */
426 1.1 cgd # if defined(VSTATUS)
427 1.1 cgd { "status", C_SH(C_STATUS), M_CHAR },
428 1.1 cgd # endif /* VSTATUS */
429 1.1 cgd # if defined(VPAGE)
430 1.1 cgd { "page", C_SH(C_PAGE), M_CHAR },
431 1.1 cgd # endif /* VPAGE */
432 1.1 cgd # if defined(VPGOFF)
433 1.1 cgd { "pgoff", C_SH(C_PGOFF), M_CHAR },
434 1.1 cgd # endif /* VPGOFF */
435 1.1 cgd # if defined(VKILL2)
436 1.1 cgd { "kill2", C_SH(C_KILL2), M_CHAR },
437 1.1 cgd # endif /* VKILL2 */
438 1.1 cgd # if defined(VBRK)
439 1.1 cgd { "brk", C_SH(C_BRK), M_CHAR },
440 1.1 cgd # endif /* VBRK */
441 1.1 cgd # if defined(VMIN)
442 1.1 cgd { "min", C_SH(C_MIN), M_CHAR },
443 1.1 cgd # endif /* VMIN */
444 1.1 cgd # if defined(VTIME)
445 1.1 cgd { "time", C_SH(C_TIME), M_CHAR },
446 1.1 cgd # endif /* VTIME */
447 1.1 cgd { NULL, 0, -1 },
448 1.1 cgd };
449 1.1 cgd
450 1.1 cgd
451 1.1 cgd
452 1.1 cgd #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
453 1.1 cgd #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
454 1.1 cgd
455 1.1 cgd #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
456 1.1 cgd #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
457 1.1 cgd #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
458 1.1 cgd
459 1.1 cgd private void tty__getchar __P((struct termios *, unsigned char *));
460 1.1 cgd private void tty__setchar __P((struct termios *, unsigned char *));
461 1.1 cgd private speed_t tty__getspeed __P((struct termios *));
462 1.1 cgd private int tty_setup __P((EditLine *));
463 1.1 cgd
464 1.1 cgd #define t_qu t_ts
465 1.1 cgd
466 1.1 cgd
467 1.1 cgd /* tty_setup():
468 1.1 cgd * Get the tty parameters and initialize the editing state
469 1.1 cgd */
470 1.1 cgd private int
471 1.1 cgd tty_setup(el)
472 1.1 cgd EditLine *el;
473 1.1 cgd {
474 1.1 cgd int rst = 1;
475 1.1 cgd if (tty_getty(el, &el->el_tty.t_ed) == -1) {
476 1.1 cgd #ifdef DEBUG_TTY
477 1.1 cgd (void) fprintf(el->el_errfile,
478 1.1 cgd "tty_setup: tty_getty: %s\n", strerror(errno));
479 1.1 cgd #endif /* DEBUG_TTY */
480 1.1 cgd return(-1);
481 1.1 cgd }
482 1.1 cgd el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
483 1.1 cgd
484 1.1 cgd el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
485 1.1 cgd el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
486 1.1 cgd el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
487 1.1 cgd
488 1.1 cgd el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
489 1.1 cgd el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
490 1.1 cgd
491 1.1 cgd el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
492 1.1 cgd el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
493 1.1 cgd
494 1.1 cgd el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
495 1.1 cgd el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
496 1.1 cgd
497 1.1 cgd el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
498 1.1 cgd el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
499 1.1 cgd
500 1.1 cgd /*
501 1.1 cgd * Reset the tty chars to reasonable defaults
502 1.1 cgd * If they are disabled, then enable them.
503 1.1 cgd */
504 1.1 cgd if (rst) {
505 1.1 cgd if (tty__cooked_mode(&el->el_tty.t_ts)) {
506 1.1 cgd tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
507 1.1 cgd /*
508 1.1 cgd * Don't affect CMIN and CTIME for the editor mode
509 1.1 cgd */
510 1.1 cgd for (rst = 0; rst < C_NCC - 2; rst++)
511 1.1 cgd if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
512 1.1 cgd el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
513 1.1 cgd el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
514 1.1 cgd for (rst = 0; rst < C_NCC; rst++)
515 1.5 christos if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable)
516 1.1 cgd el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
517 1.1 cgd }
518 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
519 1.1 cgd if (tty_setty(el, &el->el_tty.t_ex) == -1) {
520 1.1 cgd #ifdef DEBUG_TTY
521 1.1 cgd (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n",
522 1.1 cgd strerror(errno));
523 1.1 cgd #endif /* DEBUG_TTY */
524 1.1 cgd return(-1);
525 1.1 cgd }
526 1.1 cgd }
527 1.1 cgd else
528 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
529 1.1 cgd
530 1.1 cgd el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
531 1.1 cgd el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
532 1.1 cgd
533 1.1 cgd el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
534 1.1 cgd el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
535 1.1 cgd
536 1.1 cgd el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
537 1.1 cgd el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
538 1.1 cgd
539 1.1 cgd el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
540 1.1 cgd el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
541 1.1 cgd
542 1.1 cgd tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
543 1.1 cgd return 0;
544 1.1 cgd }
545 1.1 cgd
546 1.1 cgd protected int
547 1.1 cgd tty_init(el)
548 1.1 cgd EditLine *el;
549 1.1 cgd {
550 1.1 cgd el->el_tty.t_mode = EX_IO;
551 1.1 cgd el->el_tty.t_vdisable = _POSIX_VDISABLE;
552 1.1 cgd (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
553 1.1 cgd (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
554 1.1 cgd return tty_setup(el);
555 1.1 cgd } /* end tty_init */
556 1.1 cgd
557 1.1 cgd
558 1.1 cgd /* tty_end():
559 1.1 cgd * Restore the tty to its original settings
560 1.1 cgd */
561 1.1 cgd protected void
562 1.1 cgd /*ARGSUSED*/
563 1.1 cgd tty_end(el)
564 1.1 cgd EditLine *el;
565 1.1 cgd {
566 1.1 cgd /* XXX: Maybe reset to an initial state? */
567 1.1 cgd }
568 1.1 cgd
569 1.1 cgd
570 1.1 cgd /* tty__getspeed():
571 1.1 cgd * Get the tty speed
572 1.1 cgd */
573 1.1 cgd private speed_t
574 1.1 cgd tty__getspeed(td)
575 1.1 cgd struct termios *td;
576 1.1 cgd {
577 1.1 cgd speed_t spd;
578 1.1 cgd
579 1.1 cgd if ((spd = cfgetispeed(td)) == 0)
580 1.1 cgd spd = cfgetospeed(td);
581 1.1 cgd return spd;
582 1.1 cgd } /* end tty__getspeed */
583 1.1 cgd
584 1.1 cgd
585 1.1 cgd /* tty__getchar():
586 1.1 cgd * Get the tty characters
587 1.1 cgd */
588 1.1 cgd private void
589 1.1 cgd tty__getchar(td, s)
590 1.1 cgd struct termios *td;
591 1.1 cgd unsigned char *s;
592 1.1 cgd {
593 1.1 cgd # ifdef VINTR
594 1.1 cgd s[C_INTR] = td->c_cc[VINTR];
595 1.1 cgd # endif /* VINTR */
596 1.1 cgd # ifdef VQUIT
597 1.1 cgd s[C_QUIT] = td->c_cc[VQUIT];
598 1.1 cgd # endif /* VQUIT */
599 1.1 cgd # ifdef VERASE
600 1.1 cgd s[C_ERASE] = td->c_cc[VERASE];
601 1.1 cgd # endif /* VERASE */
602 1.1 cgd # ifdef VKILL
603 1.1 cgd s[C_KILL] = td->c_cc[VKILL];
604 1.1 cgd # endif /* VKILL */
605 1.1 cgd # ifdef VEOF
606 1.1 cgd s[C_EOF] = td->c_cc[VEOF];
607 1.1 cgd # endif /* VEOF */
608 1.1 cgd # ifdef VEOL
609 1.1 cgd s[C_EOL] = td->c_cc[VEOL];
610 1.1 cgd # endif /* VEOL */
611 1.1 cgd # ifdef VEOL2
612 1.1 cgd s[C_EOL2] = td->c_cc[VEOL2];
613 1.1 cgd # endif /* VEOL2 */
614 1.1 cgd # ifdef VSWTCH
615 1.1 cgd s[C_SWTCH] = td->c_cc[VSWTCH];
616 1.1 cgd # endif /* VSWTCH */
617 1.1 cgd # ifdef VDSWTCH
618 1.1 cgd s[C_DSWTCH] = td->c_cc[VDSWTCH];
619 1.1 cgd # endif /* VDSWTCH */
620 1.1 cgd # ifdef VERASE2
621 1.1 cgd s[C_ERASE2] = td->c_cc[VERASE2];
622 1.1 cgd # endif /* VERASE2 */
623 1.1 cgd # ifdef VSTART
624 1.1 cgd s[C_START] = td->c_cc[VSTART];
625 1.1 cgd # endif /* VSTART */
626 1.1 cgd # ifdef VSTOP
627 1.1 cgd s[C_STOP] = td->c_cc[VSTOP];
628 1.1 cgd # endif /* VSTOP */
629 1.1 cgd # ifdef VWERASE
630 1.1 cgd s[C_WERASE] = td->c_cc[VWERASE];
631 1.1 cgd # endif /* VWERASE */
632 1.1 cgd # ifdef VSUSP
633 1.1 cgd s[C_SUSP] = td->c_cc[VSUSP];
634 1.1 cgd # endif /* VSUSP */
635 1.1 cgd # ifdef VDSUSP
636 1.1 cgd s[C_DSUSP] = td->c_cc[VDSUSP];
637 1.1 cgd # endif /* VDSUSP */
638 1.1 cgd # ifdef VREPRINT
639 1.1 cgd s[C_REPRINT]= td->c_cc[VREPRINT];
640 1.1 cgd # endif /* VREPRINT */
641 1.1 cgd # ifdef VDISCARD
642 1.1 cgd s[C_DISCARD]= td->c_cc[VDISCARD];
643 1.1 cgd # endif /* VDISCARD */
644 1.1 cgd # ifdef VLNEXT
645 1.1 cgd s[C_LNEXT] = td->c_cc[VLNEXT];
646 1.1 cgd # endif /* VLNEXT */
647 1.1 cgd # ifdef VSTATUS
648 1.1 cgd s[C_STATUS] = td->c_cc[VSTATUS];
649 1.1 cgd # endif /* VSTATUS */
650 1.1 cgd # ifdef VPAGE
651 1.1 cgd s[C_PAGE] = td->c_cc[VPAGE];
652 1.1 cgd # endif /* VPAGE */
653 1.1 cgd # ifdef VPGOFF
654 1.1 cgd s[C_PGOFF] = td->c_cc[VPGOFF];
655 1.1 cgd # endif /* VPGOFF */
656 1.1 cgd # ifdef VKILL2
657 1.1 cgd s[C_KILL2] = td->c_cc[VKILL2];
658 1.1 cgd # endif /* KILL2 */
659 1.1 cgd # ifdef VMIN
660 1.1 cgd s[C_MIN] = td->c_cc[VMIN];
661 1.1 cgd # endif /* VMIN */
662 1.1 cgd # ifdef VTIME
663 1.1 cgd s[C_TIME] = td->c_cc[VTIME];
664 1.1 cgd # endif /* VTIME */
665 1.1 cgd } /* tty__getchar */
666 1.1 cgd
667 1.1 cgd
668 1.1 cgd /* tty__setchar():
669 1.1 cgd * Set the tty characters
670 1.1 cgd */
671 1.1 cgd private void
672 1.1 cgd tty__setchar(td, s)
673 1.1 cgd struct termios *td;
674 1.1 cgd unsigned char *s;
675 1.1 cgd {
676 1.1 cgd # ifdef VINTR
677 1.1 cgd td->c_cc[VINTR] = s[C_INTR];
678 1.1 cgd # endif /* VINTR */
679 1.1 cgd # ifdef VQUIT
680 1.1 cgd td->c_cc[VQUIT] = s[C_QUIT];
681 1.1 cgd # endif /* VQUIT */
682 1.1 cgd # ifdef VERASE
683 1.1 cgd td->c_cc[VERASE] = s[C_ERASE];
684 1.1 cgd # endif /* VERASE */
685 1.1 cgd # ifdef VKILL
686 1.1 cgd td->c_cc[VKILL] = s[C_KILL];
687 1.1 cgd # endif /* VKILL */
688 1.1 cgd # ifdef VEOF
689 1.1 cgd td->c_cc[VEOF] = s[C_EOF];
690 1.1 cgd # endif /* VEOF */
691 1.1 cgd # ifdef VEOL
692 1.1 cgd td->c_cc[VEOL] = s[C_EOL];
693 1.1 cgd # endif /* VEOL */
694 1.1 cgd # ifdef VEOL2
695 1.1 cgd td->c_cc[VEOL2] = s[C_EOL2];
696 1.1 cgd # endif /* VEOL2 */
697 1.1 cgd # ifdef VSWTCH
698 1.1 cgd td->c_cc[VSWTCH] = s[C_SWTCH];
699 1.1 cgd # endif /* VSWTCH */
700 1.1 cgd # ifdef VDSWTCH
701 1.1 cgd td->c_cc[VDSWTCH] = s[C_DSWTCH];
702 1.1 cgd # endif /* VDSWTCH */
703 1.1 cgd # ifdef VERASE2
704 1.1 cgd td->c_cc[VERASE2] = s[C_ERASE2];
705 1.1 cgd # endif /* VERASE2 */
706 1.1 cgd # ifdef VSTART
707 1.1 cgd td->c_cc[VSTART] = s[C_START];
708 1.1 cgd # endif /* VSTART */
709 1.1 cgd # ifdef VSTOP
710 1.1 cgd td->c_cc[VSTOP] = s[C_STOP];
711 1.1 cgd # endif /* VSTOP */
712 1.1 cgd # ifdef VWERASE
713 1.1 cgd td->c_cc[VWERASE] = s[C_WERASE];
714 1.1 cgd # endif /* VWERASE */
715 1.1 cgd # ifdef VSUSP
716 1.1 cgd td->c_cc[VSUSP] = s[C_SUSP];
717 1.1 cgd # endif /* VSUSP */
718 1.1 cgd # ifdef VDSUSP
719 1.1 cgd td->c_cc[VDSUSP] = s[C_DSUSP];
720 1.1 cgd # endif /* VDSUSP */
721 1.1 cgd # ifdef VREPRINT
722 1.1 cgd td->c_cc[VREPRINT] = s[C_REPRINT];
723 1.1 cgd # endif /* VREPRINT */
724 1.1 cgd # ifdef VDISCARD
725 1.1 cgd td->c_cc[VDISCARD] = s[C_DISCARD];
726 1.1 cgd # endif /* VDISCARD */
727 1.1 cgd # ifdef VLNEXT
728 1.1 cgd td->c_cc[VLNEXT] = s[C_LNEXT];
729 1.1 cgd # endif /* VLNEXT */
730 1.1 cgd # ifdef VSTATUS
731 1.1 cgd td->c_cc[VSTATUS] = s[C_STATUS];
732 1.1 cgd # endif /* VSTATUS */
733 1.1 cgd # ifdef VPAGE
734 1.1 cgd td->c_cc[VPAGE] = s[C_PAGE];
735 1.1 cgd # endif /* VPAGE */
736 1.1 cgd # ifdef VPGOFF
737 1.1 cgd td->c_cc[VPGOFF] = s[C_PGOFF];
738 1.1 cgd # endif /* VPGOFF */
739 1.1 cgd # ifdef VKILL2
740 1.1 cgd td->c_cc[VKILL2] = s[C_KILL2];
741 1.1 cgd # endif /* VKILL2 */
742 1.1 cgd # ifdef VMIN
743 1.1 cgd td->c_cc[VMIN] = s[C_MIN];
744 1.1 cgd # endif /* VMIN */
745 1.1 cgd # ifdef VTIME
746 1.1 cgd td->c_cc[VTIME] = s[C_TIME];
747 1.1 cgd # endif /* VTIME */
748 1.1 cgd } /* tty__setchar */
749 1.1 cgd
750 1.1 cgd
751 1.1 cgd /* tty_bind_char():
752 1.1 cgd * Rebind the editline functions
753 1.1 cgd */
754 1.1 cgd protected void
755 1.1 cgd tty_bind_char(el, force)
756 1.1 cgd EditLine *el;
757 1.1 cgd int force;
758 1.1 cgd {
759 1.1 cgd unsigned char *t_n = el->el_tty.t_c[ED_IO];
760 1.1 cgd unsigned char *t_o = el->el_tty.t_ed.c_cc;
761 1.1 cgd char new[2], old[2];
762 1.1 cgd ttymap_t *tp;
763 1.1 cgd el_action_t *dmap, *dalt, *map, *alt;
764 1.1 cgd new[1] = old[1] = '\0';
765 1.1 cgd
766 1.1 cgd
767 1.1 cgd map = el->el_map.key;
768 1.1 cgd alt = el->el_map.alt;
769 1.1 cgd if (el->el_map.type == MAP_VI) {
770 1.1 cgd dmap = el->el_map.vii;
771 1.1 cgd dalt = el->el_map.vic;
772 1.1 cgd }
773 1.1 cgd else {
774 1.1 cgd dmap = el->el_map.emacs;
775 1.1 cgd dalt = NULL;
776 1.1 cgd }
777 1.1 cgd
778 1.1 cgd for (tp = tty_map; tp->nch != -1; tp++) {
779 1.1 cgd new[0] = t_n[tp->nch];
780 1.1 cgd old[0] = t_o[tp->och];
781 1.1 cgd if (new[0] == old[0] && !force)
782 1.1 cgd continue;
783 1.1 cgd /* Put the old default binding back, and set the new binding */
784 1.1 cgd key_clear(el, map, old);
785 1.1 cgd map[old[0]] = dmap[old[0]];
786 1.1 cgd key_clear(el, map, new);
787 1.1 cgd /* MAP_VI == 1, MAP_EMACS == 0... */
788 1.1 cgd map[new[0]] = tp->bind[el->el_map.type];
789 1.1 cgd if (dalt) {
790 1.1 cgd key_clear(el, alt, old);
791 1.1 cgd alt[old[0]] = dalt[old[0]];
792 1.1 cgd key_clear(el, alt, new);
793 1.1 cgd alt[new[0]] = tp->bind[el->el_map.type+1];
794 1.1 cgd }
795 1.1 cgd }
796 1.1 cgd }
797 1.1 cgd
798 1.1 cgd /* tty_rawmode():
799 1.1 cgd * Set terminal into 1 character at a time mode.
800 1.1 cgd */
801 1.1 cgd protected int
802 1.1 cgd tty_rawmode(el)
803 1.1 cgd EditLine *el;
804 1.1 cgd {
805 1.1 cgd if (el->el_tty.t_mode == ED_IO)
806 1.1 cgd return (0);
807 1.1 cgd
808 1.1 cgd if (tty_getty(el, &el->el_tty.t_ts) == -1) {
809 1.1 cgd #ifdef DEBUG_TTY
810 1.1 cgd (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
811 1.1 cgd #endif /* DEBUG_TTY */
812 1.1 cgd return(-1);
813 1.1 cgd }
814 1.1 cgd
815 1.1 cgd /*
816 1.1 cgd * We always keep up with the eight bit setting and the speed of the
817 1.1 cgd * tty. But only we only believe changes that are made to cooked mode!
818 1.1 cgd */
819 1.1 cgd el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
820 1.1 cgd el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
821 1.1 cgd
822 1.1 cgd if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
823 1.1 cgd tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
824 1.1 cgd (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
825 1.1 cgd (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
826 1.1 cgd (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
827 1.1 cgd (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
828 1.1 cgd }
829 1.1 cgd
830 1.1 cgd if (tty__cooked_mode(&el->el_tty.t_ts)) {
831 1.1 cgd if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
832 1.1 cgd el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag;
833 1.1 cgd el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
834 1.1 cgd el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
835 1.1 cgd
836 1.1 cgd el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
837 1.1 cgd el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
838 1.1 cgd el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
839 1.1 cgd }
840 1.1 cgd
841 1.1 cgd if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
842 1.1 cgd (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
843 1.1 cgd el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag;
844 1.1 cgd el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
845 1.1 cgd el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
846 1.1 cgd
847 1.1 cgd el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
848 1.1 cgd el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
849 1.1 cgd el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
850 1.1 cgd }
851 1.1 cgd
852 1.1 cgd if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
853 1.1 cgd (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
854 1.1 cgd el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag;
855 1.1 cgd el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
856 1.1 cgd el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
857 1.1 cgd
858 1.1 cgd el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
859 1.1 cgd el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
860 1.1 cgd el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
861 1.1 cgd }
862 1.1 cgd
863 1.1 cgd if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
864 1.1 cgd (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
865 1.1 cgd el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag;
866 1.1 cgd el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
867 1.1 cgd el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
868 1.1 cgd
869 1.1 cgd el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
870 1.1 cgd el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
871 1.1 cgd el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
872 1.1 cgd }
873 1.1 cgd
874 1.1 cgd if (tty__gettabs(&el->el_tty.t_ex) == 0)
875 1.1 cgd el->el_tty.t_tabs = 0;
876 1.1 cgd else
877 1.1 cgd el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
878 1.1 cgd
879 1.1 cgd {
880 1.1 cgd int i;
881 1.1 cgd
882 1.1 cgd tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
883 1.1 cgd /*
884 1.1 cgd * Check if the user made any changes.
885 1.1 cgd * If he did, then propagate the changes to the
886 1.1 cgd * edit and execute data structures.
887 1.1 cgd */
888 1.1 cgd for (i = 0; i < C_NCC; i++)
889 1.1 cgd if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
890 1.1 cgd break;
891 1.1 cgd
892 1.1 cgd if (i != C_NCC) {
893 1.1 cgd /*
894 1.1 cgd * Propagate changes only to the unprotected chars
895 1.1 cgd * that have been modified just now.
896 1.1 cgd */
897 1.1 cgd for (i = 0; i < C_NCC; i++) {
898 1.1 cgd if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
899 1.1 cgd && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
900 1.1 cgd el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
901 1.1 cgd if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
902 1.1 cgd el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
903 1.1 cgd }
904 1.1 cgd tty_bind_char(el, 0);
905 1.1 cgd tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
906 1.1 cgd
907 1.1 cgd for (i = 0; i < C_NCC; i++) {
908 1.1 cgd if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
909 1.1 cgd && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
910 1.1 cgd el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
911 1.1 cgd if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
912 1.1 cgd el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
913 1.1 cgd }
914 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
915 1.1 cgd }
916 1.1 cgd }
917 1.1 cgd }
918 1.1 cgd
919 1.1 cgd if (tty_setty(el, &el->el_tty.t_ed) == -1) {
920 1.1 cgd #ifdef DEBUG_TTY
921 1.1 cgd (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
922 1.1 cgd strerror(errno));
923 1.1 cgd #endif /* DEBUG_TTY */
924 1.1 cgd return -1;
925 1.1 cgd }
926 1.1 cgd el->el_tty.t_mode = ED_IO;
927 1.1 cgd return (0);
928 1.1 cgd } /* end tty_rawmode */
929 1.1 cgd
930 1.1 cgd
931 1.1 cgd /* tty_cookedmode():
932 1.1 cgd * Set the tty back to normal mode
933 1.1 cgd */
934 1.1 cgd protected int
935 1.1 cgd tty_cookedmode(el)
936 1.1 cgd EditLine *el;
937 1.1 cgd { /* set tty in normal setup */
938 1.1 cgd if (el->el_tty.t_mode == EX_IO)
939 1.1 cgd return (0);
940 1.1 cgd
941 1.1 cgd if (tty_setty(el, &el->el_tty.t_ex) == -1) {
942 1.1 cgd #ifdef DEBUG_TTY
943 1.1 cgd (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
944 1.1 cgd strerror(errno));
945 1.1 cgd #endif /* DEBUG_TTY */
946 1.1 cgd return -1;
947 1.1 cgd }
948 1.1 cgd el->el_tty.t_mode = EX_IO;
949 1.1 cgd return (0);
950 1.1 cgd } /* end tty_cookedmode */
951 1.1 cgd
952 1.1 cgd
953 1.1 cgd /* tty_quotemode():
954 1.1 cgd * Turn on quote mode
955 1.1 cgd */
956 1.1 cgd protected int
957 1.1 cgd tty_quotemode(el)
958 1.1 cgd EditLine *el;
959 1.1 cgd {
960 1.1 cgd if (el->el_tty.t_mode == QU_IO)
961 1.1 cgd return 0;
962 1.1 cgd
963 1.1 cgd el->el_tty.t_qu = el->el_tty.t_ed;
964 1.1 cgd
965 1.1 cgd el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
966 1.1 cgd el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
967 1.1 cgd
968 1.1 cgd el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
969 1.1 cgd el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
970 1.1 cgd
971 1.1 cgd el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
972 1.1 cgd el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
973 1.1 cgd
974 1.1 cgd el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
975 1.1 cgd el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
976 1.1 cgd
977 1.1 cgd if (tty_setty(el, &el->el_tty.t_qu) == -1) {
978 1.1 cgd #ifdef DEBUG_TTY
979 1.1 cgd (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
980 1.1 cgd strerror(errno));
981 1.1 cgd #endif /* DEBUG_TTY */
982 1.1 cgd return -1;
983 1.1 cgd }
984 1.1 cgd el->el_tty.t_mode = QU_IO;
985 1.1 cgd return 0;
986 1.1 cgd } /* end tty_quotemode */
987 1.1 cgd
988 1.1 cgd
989 1.1 cgd /* tty_noquotemode():
990 1.1 cgd * Turn off quote mode
991 1.1 cgd */
992 1.1 cgd protected int
993 1.1 cgd tty_noquotemode(el)
994 1.1 cgd EditLine *el;
995 1.1 cgd {
996 1.1 cgd if (el->el_tty.t_mode != QU_IO)
997 1.1 cgd return 0;
998 1.1 cgd if (tty_setty(el, &el->el_tty.t_ed) == -1) {
999 1.1 cgd #ifdef DEBUG_TTY
1000 1.1 cgd (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
1001 1.1 cgd strerror(errno));
1002 1.1 cgd #endif /* DEBUG_TTY */
1003 1.1 cgd return -1;
1004 1.1 cgd }
1005 1.1 cgd el->el_tty.t_mode = ED_IO;
1006 1.1 cgd return 0;
1007 1.1 cgd }
1008 1.1 cgd
1009 1.1 cgd /* tty_stty():
1010 1.1 cgd * Stty builtin
1011 1.1 cgd */
1012 1.1 cgd protected int
1013 1.1 cgd /*ARGSUSED*/
1014 1.1 cgd tty_stty(el, argc, argv)
1015 1.1 cgd EditLine *el;
1016 1.1 cgd int argc;
1017 1.1 cgd char **argv;
1018 1.1 cgd {
1019 1.1 cgd ttymodes_t *m;
1020 1.1 cgd char x, *d;
1021 1.1 cgd int aflag = 0;
1022 1.1 cgd char *s;
1023 1.1 cgd char *name;
1024 1.1 cgd int z = EX_IO;
1025 1.1 cgd
1026 1.1 cgd if (argv == NULL)
1027 1.1 cgd return -1;
1028 1.1 cgd name = *argv++;
1029 1.1 cgd
1030 1.1 cgd while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
1031 1.1 cgd switch (argv[0][1]) {
1032 1.1 cgd case 'a':
1033 1.1 cgd aflag++;
1034 1.1 cgd argv++;
1035 1.1 cgd break;
1036 1.1 cgd case 'd':
1037 1.1 cgd argv++;
1038 1.1 cgd z = ED_IO;
1039 1.1 cgd break;
1040 1.1 cgd case 'x':
1041 1.1 cgd argv++;
1042 1.1 cgd z = EX_IO;
1043 1.1 cgd break;
1044 1.1 cgd case 'q':
1045 1.1 cgd argv++;
1046 1.1 cgd z = QU_IO;
1047 1.1 cgd break;
1048 1.1 cgd default:
1049 1.1 cgd (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
1050 1.1 cgd name, argv[0][1]);
1051 1.1 cgd return -1;
1052 1.1 cgd }
1053 1.1 cgd
1054 1.1 cgd if (!argv || !*argv) {
1055 1.1 cgd int i = -1;
1056 1.1 cgd int len = 0, st = 0, cu;
1057 1.1 cgd for (m = ttymodes; m->m_name; m++) {
1058 1.1 cgd if (m->m_type != i) {
1059 1.1 cgd (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
1060 1.1 cgd el->el_tty.t_t[z][m->m_type].t_name);
1061 1.1 cgd i = m->m_type;
1062 1.1 cgd st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
1063 1.1 cgd }
1064 1.1 cgd
1065 1.1 cgd x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
1066 1.1 cgd x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
1067 1.1 cgd
1068 1.1 cgd if (x != '\0' || aflag) {
1069 1.1 cgd
1070 1.1 cgd cu = strlen(m->m_name) + (x != '\0') + 1;
1071 1.1 cgd
1072 1.1 cgd if (len + cu >= el->el_term.t_size.h) {
1073 1.1 cgd (void) fprintf(el->el_outfile, "\n%*s", st, "");
1074 1.1 cgd len = st + cu;
1075 1.1 cgd }
1076 1.1 cgd else
1077 1.1 cgd len += cu;
1078 1.1 cgd
1079 1.1 cgd if (x != '\0')
1080 1.1 cgd (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
1081 1.1 cgd else
1082 1.1 cgd (void) fprintf(el->el_outfile, "%s ", m->m_name);
1083 1.1 cgd }
1084 1.1 cgd }
1085 1.1 cgd (void) fprintf(el->el_outfile, "\n");
1086 1.1 cgd return 0;
1087 1.1 cgd }
1088 1.1 cgd
1089 1.1 cgd while (argv && (s = *argv++)) {
1090 1.1 cgd switch (*s) {
1091 1.1 cgd case '+':
1092 1.1 cgd case '-':
1093 1.1 cgd x = *s++;
1094 1.1 cgd break;
1095 1.1 cgd default:
1096 1.1 cgd x = '\0';
1097 1.1 cgd break;
1098 1.1 cgd }
1099 1.1 cgd d = s;
1100 1.1 cgd for (m = ttymodes; m->m_name; m++)
1101 1.1 cgd if (strcmp(m->m_name, d) == 0)
1102 1.1 cgd break;
1103 1.1 cgd
1104 1.1 cgd if (!m->m_name) {
1105 1.1 cgd (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
1106 1.1 cgd name, d);
1107 1.1 cgd return -1;
1108 1.1 cgd }
1109 1.1 cgd
1110 1.1 cgd switch (x) {
1111 1.1 cgd case '+':
1112 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1113 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1114 1.1 cgd break;
1115 1.1 cgd case '-':
1116 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1117 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1118 1.1 cgd break;
1119 1.1 cgd default:
1120 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1121 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1122 1.1 cgd break;
1123 1.1 cgd }
1124 1.1 cgd }
1125 1.1 cgd return 0;
1126 1.1 cgd } /* end tty_stty */
1127 1.1 cgd
1128 1.1 cgd
1129 1.1 cgd #ifdef notyet
1130 1.1 cgd /* tty_printchar():
1131 1.1 cgd * DEbugging routine to print the tty characters
1132 1.1 cgd */
1133 1.1 cgd private void
1134 1.1 cgd tty_printchar(el, s)
1135 1.1 cgd EditLine *el;
1136 1.1 cgd unsigned char *s;
1137 1.1 cgd {
1138 1.1 cgd ttyperm_t *m;
1139 1.1 cgd int i;
1140 1.1 cgd
1141 1.1 cgd for (i = 0; i < C_NCC; i++) {
1142 1.1 cgd for (m = el->el_tty.t_t; m->m_name; m++)
1143 1.1 cgd if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
1144 1.1 cgd break;
1145 1.1 cgd if (m->m_name)
1146 1.1 cgd (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
1147 1.1 cgd if (i % 5 == 0)
1148 1.1 cgd (void) fprintf(el->el_errfile, "\n");
1149 1.1 cgd }
1150 1.1 cgd (void) fprintf(el->el_errfile, "\n");
1151 1.1 cgd }
1152 1.1 cgd #endif /* notyet */
1153