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