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