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