1: /* rltty.c -- functions to prepare and restore the terminal for readline's
2: use. */
3:
4: /* Copyright (C) 1992-2017 Free Software Foundation, Inc.
5:
6: This file is part of the GNU Readline Library (Readline), a library
7: for reading lines of text with interactive input and history editing.
8:
9: Readline is free software: you can redistribute it and/or modify
10: it under the terms of the GNU General Public License as published by
11: the Free Software Foundation, either version 3 of the License, or
12: (at your option) any later version.
13:
14: Readline is distributed in the hope that it will be useful,
15: but WITHOUT ANY WARRANTY; without even the implied warranty of
16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: GNU General Public License for more details.
18:
19: You should have received a copy of the GNU General Public License
20: along with Readline. If not, see <http://www.gnu.org/licenses/>.
21: */
22:
23: #define READLINE_LIBRARY
24:
25: #if defined (HAVE_CONFIG_H)
26: # include <config.h>
27: #endif
28:
29: #include <sys/types.h>
30: #include <signal.h>
31: #include <errno.h>
32: #include <stdio.h>
33:
34: #if defined (HAVE_UNISTD_H)
35: # include <unistd.h>
36: #endif /* HAVE_UNISTD_H */
37:
38: #include "rldefs.h"
39:
40: #include "rltty.h"
41: #if defined (HAVE_SYS_IOCTL_H)
42: # include <sys/ioctl.h> /* include for declaration of ioctl */
43: #endif
44:
45: #include "readline.h"
46: #include "rlprivate.h"
47:
48: #if !defined (errno)
49: extern int errno;
50: #endif /* !errno */
51:
52: rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
53: rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
54:
55: static void set_winsize PARAMS((int));
56:
57: /* **************************************************************** */
58: /* */
59: /* Saving and Restoring the TTY */
60: /* */
61: /* **************************************************************** */
62:
63: /* Non-zero means that the terminal is in a prepped state. There are several
64: flags that are OR'd in to denote whether or not we have sent various
65: init strings to the terminal. */
66: #define TPX_PREPPED 0x01
67: #define TPX_BRACKPASTE 0x02
68: #define TPX_METAKEY 0x04
69:
70: static int terminal_prepped;
71:
72: static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
73:
74: /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
75: and output is suspended. */
76: #if defined (__ksr1__)
77: static int ksrflow;
78: #endif
79:
80: /* Dummy call to force a backgrounded readline to stop before it tries
81: to get the tty settings. */
82: static void
83: set_winsize (tty)
84: int tty;
85: {
86: #if defined (TIOCGWINSZ)
87: struct winsize w;
88:
89: if (ioctl (tty, TIOCGWINSZ, &w) == 0)
90: (void) ioctl (tty, TIOCSWINSZ, &w);
91: #endif /* TIOCGWINSZ */
92: }
93:
94: #if defined (NO_TTY_DRIVER)
95: /* Nothing */
96: #elif defined (NEW_TTY_DRIVER)
97:
98: /* Values for the `flags' field of a struct bsdtty. This tells which
99: elements of the struct bsdtty have been fetched from the system and
100: are valid. */
101: #define SGTTY_SET 0x01
102: #define LFLAG_SET 0x02
103: #define TCHARS_SET 0x04
104: #define LTCHARS_SET 0x08
105:
106: struct bsdtty {
107: struct sgttyb sgttyb; /* Basic BSD tty driver information. */
108: int lflag; /* Local mode flags, like LPASS8. */
109: #if defined (TIOCGETC)
110: struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
111: #endif
112: #if defined (TIOCGLTC)
113: struct ltchars ltchars; /* 4.2 BSD editing characters */
114: #endif
115: int flags; /* Bitmap saying which parts of the struct are valid. */
116: };
117:
118: #define TIOTYPE struct bsdtty
119:
120: static TIOTYPE otio;
121:
122: static void save_tty_chars PARAMS((TIOTYPE *));
123: static int _get_tty_settings PARAMS((int, TIOTYPE *));
124: static int get_tty_settings PARAMS((int, TIOTYPE *));
125: static int _set_tty_settings PARAMS((int, TIOTYPE *));
126: static int set_tty_settings PARAMS((int, TIOTYPE *));
127:
128: static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
129:
130: static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *));
131:
132: static void
133: save_tty_chars (TIOTYPE *tiop)
134: {
135: _rl_last_tty_chars = _rl_tty_chars;
136:
137: if (tiop->flags & SGTTY_SET)
138: {
139: _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
140: _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
141: }
142:
143: if (tiop->flags & TCHARS_SET)
144: {
145: _rl_intr_char = _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
146: _rl_quit_char = _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
147:
148: _rl_tty_chars.t_start = tiop->tchars.t_startc;
149: _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
150: _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
151: _rl_tty_chars.t_eol = '\n';
152: _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
153: }
154:
155: if (tiop->flags & LTCHARS_SET)
156: {
157: _rl_susp_char = _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
158:
159: _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
160: _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
161: _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
162: _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
163: _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
164: }
165:
166: _rl_tty_chars.t_status = -1;
167: }
168:
169: static int
170: get_tty_settings (int tty, TIOTYPE *tiop)
171: {
172: set_winsize (tty);
173:
174: tiop->flags = tiop->lflag = 0;
175:
176: errno = 0;
177: if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
178: return -1;
179: tiop->flags |= SGTTY_SET;
180:
181: #if defined (TIOCLGET)
182: if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
183: tiop->flags |= LFLAG_SET;
184: #endif
185:
186: #if defined (TIOCGETC)
187: if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
188: tiop->flags |= TCHARS_SET;
189: #endif
190:
191: #if defined (TIOCGLTC)
192: if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
193: tiop->flags |= LTCHARS_SET;
194: #endif
195:
196: return 0;
197: }
198:
199: static int
200: set_tty_settings (int tty, TIOTYPE *tiop)
201: {
202: if (tiop->flags & SGTTY_SET)
203: {
204: ioctl (tty, TIOCSETN, &(tiop->sgttyb));
205: tiop->flags &= ~SGTTY_SET;
206: }
207: _rl_echoing_p = 1;
208:
209: #if defined (TIOCLSET)
210: if (tiop->flags & LFLAG_SET)
211: {
212: ioctl (tty, TIOCLSET, &(tiop->lflag));
213: tiop->flags &= ~LFLAG_SET;
214: }
215: #endif
216:
217: #if defined (TIOCSETC)
218: if (tiop->flags & TCHARS_SET)
219: {
220: ioctl (tty, TIOCSETC, &(tiop->tchars));
221: tiop->flags &= ~TCHARS_SET;
222: }
223: #endif
224:
225: #if defined (TIOCSLTC)
226: if (tiop->flags & LTCHARS_SET)
227: {
228: ioctl (tty, TIOCSLTC, &(tiop->ltchars));
229: tiop->flags &= ~LTCHARS_SET;
230: }
231: #endif
232:
233: return 0;
234: }
235:
236: static void
237: prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop)
238: {
239: _rl_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
240: _rl_echoctl = (oldtio.sgttyb.sg_flags & ECHOCTL);
241:
242: /* Copy the original settings to the structure we're going to use for
243: our settings. */
244: tiop->sgttyb = oldtio.sgttyb;
245: tiop->lflag = oldtio.lflag;
246: #if defined (TIOCGETC)
247: tiop->tchars = oldtio.tchars;
248: #endif
249: #if defined (TIOCGLTC)
250: tiop->ltchars = oldtio.ltchars;
251: #endif
252: tiop->flags = oldtio.flags;
253:
254: /* First, the basic settings to put us into character-at-a-time, no-echo
255: input mode. */
256: tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
257: tiop->sgttyb.sg_flags |= CBREAK;
258:
259: /* If this terminal doesn't care how the 8th bit is used, then we can
260: use it for the meta-key. If only one of even or odd parity is
261: specified, then the terminal is using parity, and we cannot. */
262: #if !defined (ANYP)
263: # define ANYP (EVENP | ODDP)
264: #endif
265: if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
266: ((oldtio.sgttyb.sg_flags & ANYP) == 0))
267: {
268: tiop->sgttyb.sg_flags |= ANYP;
269:
270: /* Hack on local mode flags if we can. */
271: #if defined (TIOCLGET)
272: # if defined (LPASS8)
273: tiop->lflag |= LPASS8;
274: # endif /* LPASS8 */
275: #endif /* TIOCLGET */
276: }
277:
278: #if defined (TIOCGETC)
279: # if defined (USE_XON_XOFF)
280: /* Get rid of terminal output start and stop characters. */
281: tiop->tchars.t_stopc = -1; /* C-s */
282: tiop->tchars.t_startc = -1; /* C-q */
283:
284: /* If there is an XON character, bind it to restart the output. */
285: if (oldtio.tchars.t_startc != -1)
286: rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
287: # endif /* USE_XON_XOFF */
288:
289: /* If there is an EOF char, bind _rl_eof_char to it. */
290: if (oldtio.tchars.t_eofc != -1)
291: _rl_eof_char = oldtio.tchars.t_eofc;
292:
293: # if defined (NO_KILL_INTR)
294: /* Get rid of terminal-generated SIGQUIT and SIGINT. */
295: tiop->tchars.t_quitc = -1; /* C-\ */
296: tiop->tchars.t_intrc = -1; /* C-c */
297: # endif /* NO_KILL_INTR */
298: #endif /* TIOCGETC */
299:
300: #if defined (TIOCGLTC)
301: /* Make the interrupt keys go away. Just enough to make people happy. */
302: tiop->ltchars.t_dsuspc = -1; /* C-y */
303: tiop->ltchars.t_lnextc = -1; /* C-v */
304: #endif /* TIOCGLTC */
305: }
306:
307: #else /* !defined (NEW_TTY_DRIVER) */
308:
309: #if !defined (VMIN)
310: # define VMIN VEOF
311: #endif
312:
313: #if !defined (VTIME)
314: # define VTIME VEOL
315: #endif
316:
317: #if defined (TERMIOS_TTY_DRIVER)
318: # define TIOTYPE struct termios
319: # define DRAIN_OUTPUT(fd) tcdrain (fd)
320: # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
321: # ifdef M_UNIX
322: # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
323: # else
324: # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
325: # endif /* !M_UNIX */
326: #else
327: # define TIOTYPE struct termio
328: # define DRAIN_OUTPUT(fd)
329: # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
330: # define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
331: #endif /* !TERMIOS_TTY_DRIVER */
332:
333: static TIOTYPE otio;
334:
335: static void save_tty_chars PARAMS((TIOTYPE *));
336: static int _get_tty_settings PARAMS((int, TIOTYPE *));
337: static int get_tty_settings PARAMS((int, TIOTYPE *));
338: static int _set_tty_settings PARAMS((int, TIOTYPE *));
339: static int set_tty_settings PARAMS((int, TIOTYPE *));
340:
341: static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
342:
343: static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *));
344: static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
345:
346: #if defined (FLUSHO)
347: # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
348: #else
349: # define OUTPUT_BEING_FLUSHED(tp) 0
350: #endif
351:
352: static void
353: save_tty_chars (TIOTYPE *tiop)
354: {
355: _rl_last_tty_chars = _rl_tty_chars;
356:
357: _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
358: _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
359: #ifdef VEOL2
360: _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
361: #endif
362: _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
363: #ifdef VWERASE
364: _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
365: #endif
366: _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
367: #ifdef VREPRINT
368: _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
369: #endif
370: _rl_intr_char = _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
371: _rl_quit_char = _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
372: #ifdef VSUSP
373: _rl_susp_char = _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
374: #endif
375: #ifdef VDSUSP
376: _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
377: #endif
378: #ifdef VSTART
379: _rl_tty_chars.t_start = tiop->c_cc[VSTART];
380: #endif
381: #ifdef VSTOP
382: _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
383: #endif
384: #ifdef VLNEXT
385: _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
386: #endif
387: #ifdef VDISCARD
388: _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
389: #endif
390: #ifdef VSTATUS
391: _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
392: #endif
393: }
394:
395: #if defined (_AIX) || defined (_AIX41)
396: /* Currently this is only used on AIX */
397: static void
398: rltty_warning (char *msg)
399: {
400: _rl_errmsg ("warning: %s", msg);
401: }
402: #endif
403:
404: #if defined (_AIX)
405: void
406: setopost (TIOTYPE *tp)
407: {
408: if ((tp->c_oflag & OPOST) == 0)
409: {
410: _rl_errmsg ("warning: turning on OPOST for terminal\r");
411: tp->c_oflag |= OPOST|ONLCR;
412: }
413: }
414: #endif
415:
416: static int
417: _get_tty_settings (int tty, TIOTYPE *tiop)
418: {
419: int ioctl_ret;
420:
421: while (1)
422: {
423: ioctl_ret = GETATTR (tty, tiop);
424: if (ioctl_ret < 0)
425: {
426: if (errno != EINTR)
427: return -1;
428: else
429: continue;
430: }
431: if (OUTPUT_BEING_FLUSHED (tiop))
432: {
433: #if defined (FLUSHO)
434: _rl_errmsg ("warning: turning off output flushing");
435: tiop->c_lflag &= ~FLUSHO;
436: break;
437: #else
438: continue;
439: #endif
440: }
441: break;
442: }
443:
444: return 0;
445: }
446:
447: static int
448: get_tty_settings (int tty, TIOTYPE *tiop)
449: {
450: set_winsize (tty);
451:
452: errno = 0;
453: if (_get_tty_settings (tty, tiop) < 0)
454: return -1;
455:
456: #if defined (_AIX)
457: setopost(tiop);
458: #endif
459:
460: return 0;
461: }
462:
463: static int
464: _set_tty_settings (int tty, TIOTYPE *tiop)
465: {
466: while (SETATTR (tty, tiop) < 0)
467: {
468: if (errno != EINTR)
469: return -1;
470: errno = 0;
471: }
472: return 0;
473: }
474:
475: static int
476: set_tty_settings (int tty, TIOTYPE *tiop)
477: {
478: if (_set_tty_settings (tty, tiop) < 0)
479: return -1;
480:
481: #if 0
482:
483: #if defined (TERMIOS_TTY_DRIVER)
484: # if defined (__ksr1__)
485: if (ksrflow)
486: {
487: ksrflow = 0;
488: tcflow (tty, TCOON);
489: }
490: # else /* !ksr1 */
491: tcflow (tty, TCOON); /* Simulate a ^Q. */
492: # endif /* !ksr1 */
493: #else
494: ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
495: #endif /* !TERMIOS_TTY_DRIVER */
496:
497: #endif /* 0 */
498:
499: return 0;
500: }
501:
502: static void
503: prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop)
504: {
505: int sc;
506: Keymap kmap;
507:
508: _rl_echoing_p = (oldtio.c_lflag & ECHO);
509: #if defined (ECHOCTL)
510: _rl_echoctl = (oldtio.c_lflag & ECHOCTL);
511: #endif
512:
513: tiop->c_lflag &= ~(ICANON | ECHO);
514:
515: if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
516: _rl_eof_char = oldtio.c_cc[VEOF];
517:
518: #if defined (USE_XON_XOFF)
519: #if defined (IXANY)
520: tiop->c_iflag &= ~(IXON | IXANY);
521: #else
522: /* `strict' Posix systems do not define IXANY. */
523: tiop->c_iflag &= ~IXON;
524: #endif /* IXANY */
525: #endif /* USE_XON_XOFF */
526:
527: /* Only turn this off if we are using all 8 bits. */
528: if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
529: tiop->c_iflag &= ~(ISTRIP | INPCK);
530:
531: /* Make sure we differentiate between CR and NL on input. */
532: tiop->c_iflag &= ~(ICRNL | INLCR);
533:
534: #if !defined (HANDLE_SIGNALS)
535: tiop->c_lflag &= ~ISIG;
536: #else
537: tiop->c_lflag |= ISIG;
538: #endif
539:
540: tiop->c_cc[VMIN] = 1;
541: tiop->c_cc[VTIME] = 0;
542:
543: #if defined (FLUSHO)
544: if (OUTPUT_BEING_FLUSHED (tiop))
545: {
546: tiop->c_lflag &= ~FLUSHO;
547: oldtio.c_lflag &= ~FLUSHO;
548: }
549: #endif
550:
551: /* Turn off characters that we need on Posix systems with job control,
552: just to be sure. This includes ^Y and ^V. This should not really
553: be necessary. */
554: #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
555:
556: #if defined (VLNEXT)
557: tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
558: #endif
559:
560: #if defined (VDSUSP)
561: tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
562: #endif
563:
564: /* Conditionally disable some other tty special characters if there is a
565: key binding for them in the current keymap. Readline ordinarily doesn't
566: bind these characters, but an application or user might. */
567: #if defined (VI_MODE)
568: kmap = (rl_editing_mode == vi_mode) ? vi_insertion_keymap : _rl_keymap;
569: #else
570: kmap = _rl_keymap;
571: #endif
572: #if defined (VDISCARD)
573: sc = tiop->c_cc[VDISCARD];
574: if (sc != _POSIX_VDISABLE && kmap[(unsigned char)sc].type == ISFUNC)
575: tiop->c_cc[VDISCARD] = _POSIX_VDISABLE;
576: #endif /* VDISCARD */
577:
578: #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
579: }
580: #endif /* !NEW_TTY_DRIVER */
581:
582: /* Put the terminal in CBREAK mode so that we can detect key presses. */
583: #if defined (NO_TTY_DRIVER)
584: void
585: rl_prep_terminal (int meta_flag)
586: {
587: _rl_echoing_p = 1;
588: }
589:
590: void
591: rl_deprep_terminal (void)
592: {
593: }
594:
595: #else /* ! NO_TTY_DRIVER */
596: void
597: rl_prep_terminal (int meta_flag)
598: {
599: int tty, nprep;
600: TIOTYPE tio;
601:
602: if (terminal_prepped)
603: return;
604:
605: /* Try to keep this function from being INTerrupted. */
606: _rl_block_sigint ();
607:
608: tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
609:
610: if (get_tty_settings (tty, &tio) < 0)
611: {
612: #if defined (ENOTSUP)
613: /* MacOS X and Linux, at least, lie about the value of errno if
614: tcgetattr fails. */
615: if (errno == ENOTTY || errno == EINVAL || errno == ENOTSUP)
616: #else
617: if (errno == ENOTTY || errno == EINVAL)
618: #endif
619: _rl_echoing_p = 1; /* XXX */
620:
621: _rl_release_sigint ();
622: return;
623: }
624:
625: otio = tio;
626:
627: if (_rl_bind_stty_chars)
628: {
629: #if defined (VI_MODE)
630: /* If editing in vi mode, make sure we restore the bindings in the
631: insertion keymap no matter what keymap we ended up in. */
632: if (rl_editing_mode == vi_mode)
633: rl_tty_unset_default_bindings (vi_insertion_keymap);
634: else
635: #endif
636: rl_tty_unset_default_bindings (_rl_keymap);
637: }
638: save_tty_chars (&otio);
639: RL_SETSTATE(RL_STATE_TTYCSAVED);
640: if (_rl_bind_stty_chars)
641: {
642: #if defined (VI_MODE)
643: /* If editing in vi mode, make sure we set the bindings in the
644: insertion keymap no matter what keymap we ended up in. */
645: if (rl_editing_mode == vi_mode)
646: _rl_bind_tty_special_chars (vi_insertion_keymap, tio);
647: else
648: #endif
649: _rl_bind_tty_special_chars (_rl_keymap, tio);
650: }
651:
652: prepare_terminal_settings (meta_flag, otio, &tio);
653:
654: if (set_tty_settings (tty, &tio) < 0)
655: {
656: _rl_release_sigint ();
657: return;
658: }
659:
660: if (_rl_enable_keypad)
661: _rl_control_keypad (1);
662:
663: nprep = TPX_PREPPED;
664:
665: if (_rl_enable_bracketed_paste)
666: {
667: fprintf (rl_outstream, BRACK_PASTE_INIT);
668: nprep |= TPX_BRACKPASTE;
669: }
670:
671: fflush (rl_outstream);
672: terminal_prepped = nprep;
673: RL_SETSTATE(RL_STATE_TERMPREPPED);
674:
675: _rl_release_sigint ();
676: }
677:
678: /* Restore the terminal's normal settings and modes. */
679: void
680: rl_deprep_terminal (void)
681: {
682: int tty;
683:
684: if (terminal_prepped == 0)
685: return;
686:
687: /* Try to keep this function from being interrupted. */
688: _rl_block_sigint ();
689:
690: tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
691:
692: if (terminal_prepped & TPX_BRACKPASTE)
693: {
694: fprintf (rl_outstream, BRACK_PASTE_FINI);
695: if (_rl_eof_found)
696: fprintf (rl_outstream, "\n");
697: }
698:
699: if (_rl_enable_keypad)
700: _rl_control_keypad (0);
701:
702: fflush (rl_outstream);
703:
704: if (set_tty_settings (tty, &otio) < 0)
705: {
706: _rl_release_sigint ();
707: return;
708: }
709:
710: terminal_prepped = 0;
711: RL_UNSETSTATE(RL_STATE_TERMPREPPED);
712:
713: _rl_release_sigint ();
714: }
715: #endif /* !NO_TTY_DRIVER */
716:
717: /* Set readline's idea of whether or not it is echoing output to the terminal,
718: returning the old value. */
719: int
720: rl_tty_set_echoing (int u)
721: {
722: int o;
723:
724: o = _rl_echoing_p;
725: _rl_echoing_p = u;
726: return o;
727: }
728:
729: /* **************************************************************** */
730: /* */
731: /* Bogus Flow Control */
732: /* */
733: /* **************************************************************** */
734:
735: int
736: rl_restart_output (int count, int key)
737: {
738: #if defined (__MINGW32__)
739: return 0;
740: #else /* !__MING32__ */
741:
742: int fildes = fileno (rl_outstream);
743: #if defined (TIOCSTART)
744: #if defined (apollo)
745: ioctl (&fildes, TIOCSTART, 0);
746: #else
747: ioctl (fildes, TIOCSTART, 0);
748: #endif /* apollo */
749:
750: #else /* !TIOCSTART */
751: # if defined (TERMIOS_TTY_DRIVER)
752: # if defined (__ksr1__)
753: if (ksrflow)
754: {
755: ksrflow = 0;
756: tcflow (fildes, TCOON);
757: }
758: # else /* !ksr1 */
759: tcflow (fildes, TCOON); /* Simulate a ^Q. */
760: # endif /* !ksr1 */
761: # else /* !TERMIOS_TTY_DRIVER */
762: # if defined (TCXONC)
763: ioctl (fildes, TCXONC, TCOON);
764: # endif /* TCXONC */
765: # endif /* !TERMIOS_TTY_DRIVER */
766: #endif /* !TIOCSTART */
767:
768: return 0;
769: #endif /* !__MINGW32__ */
770: }
771:
772: int
773: rl_stop_output (int count, int key)
774: {
775: #if defined (__MINGW32__)
776: return 0;
777: #else
778:
779: int fildes = fileno (rl_instream);
780:
781: #if defined (TIOCSTOP)
782: # if defined (apollo)
783: ioctl (&fildes, TIOCSTOP, 0);
784: # else
785: ioctl (fildes, TIOCSTOP, 0);
786: # endif /* apollo */
787: #else /* !TIOCSTOP */
788: # if defined (TERMIOS_TTY_DRIVER)
789: # if defined (__ksr1__)
790: ksrflow = 1;
791: # endif /* ksr1 */
792: tcflow (fildes, TCOOFF);
793: # else
794: # if defined (TCXONC)
795: ioctl (fildes, TCXONC, TCOON);
796: # endif /* TCXONC */
797: # endif /* !TERMIOS_TTY_DRIVER */
798: #endif /* !TIOCSTOP */
799:
800: return 0;
801: #endif /* !__MINGW32__ */
802: }
803:
804: /* **************************************************************** */
805: /* */
806: /* Default Key Bindings */
807: /* */
808: /* **************************************************************** */
809:
810: #if !defined (NO_TTY_DRIVER)
811: #define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
812: #endif
813:
814: #if defined (NO_TTY_DRIVER)
815:
816: #define SET_SPECIAL(sc, func)
817: #define RESET_SPECIAL(c)
818:
819: #elif defined (NEW_TTY_DRIVER)
820: static void
821: set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func)
822: {
823: if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
824: kmap[(unsigned char)sc].function = func;
825: }
826:
827: #define RESET_SPECIAL(c) \
828: if (c != -1 && kmap[(unsigned char)c].type == ISFUNC) \
829: kmap[(unsigned char)c].function = rl_insert;
830:
831: static void
832: _rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff)
833: {
834: if (ttybuff.flags & SGTTY_SET)
835: {
836: SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
837: SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
838: }
839:
840: # if defined (TIOCGLTC)
841: if (ttybuff.flags & LTCHARS_SET)
842: {
843: SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
844: SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
845: }
846: # endif /* TIOCGLTC */
847: }
848:
849: #else /* !NEW_TTY_DRIVER */
850: static void
851: set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func)
852: {
853: unsigned char uc;
854:
855: uc = tiop->c_cc[sc];
856: if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
857: kmap[uc].function = func;
858: }
859:
860: /* used later */
861: #define RESET_SPECIAL(uc) \
862: if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
863: kmap[uc].function = rl_insert;
864:
865: static void
866: _rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff)
867: {
868: SET_SPECIAL (VERASE, rl_rubout);
869: SET_SPECIAL (VKILL, rl_unix_line_discard);
870:
871: # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
872: SET_SPECIAL (VLNEXT, rl_quoted_insert);
873: # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
874:
875: # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
876: # if defined (VI_MODE)
877: if (rl_editing_mode == vi_mode)
878: SET_SPECIAL (VWERASE, rl_vi_unix_word_rubout);
879: else
880: # endif
881: SET_SPECIAL (VWERASE, rl_unix_word_rubout);
882: # endif /* VWERASE && TERMIOS_TTY_DRIVER */
883: }
884:
885: #endif /* !NEW_TTY_DRIVER */
886:
887: /* Set the system's default editing characters to their readline equivalents
888: in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
889: void
890: rltty_set_default_bindings (Keymap kmap)
891: {
892: #if !defined (NO_TTY_DRIVER)
893: TIOTYPE ttybuff;
894: int tty;
895:
896: tty = fileno (rl_instream);
897:
898: if (get_tty_settings (tty, &ttybuff) == 0)
899: _rl_bind_tty_special_chars (kmap, ttybuff);
900: #endif
901: }
902:
903: /* New public way to set the system default editing chars to their readline
904: equivalents. */
905: void
906: rl_tty_set_default_bindings (Keymap kmap)
907: {
908: rltty_set_default_bindings (kmap);
909: }
910:
911: /* Rebind all of the tty special chars that readline worries about back
912: to self-insert. Call this before saving the current terminal special
913: chars with save_tty_chars(). This only works on POSIX termios or termio
914: systems. */
915: void
916: rl_tty_unset_default_bindings (Keymap kmap)
917: {
918: /* Don't bother before we've saved the tty special chars at least once. */
919: if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
920: return;
921:
922: RESET_SPECIAL (_rl_tty_chars.t_erase);
923: RESET_SPECIAL (_rl_tty_chars.t_kill);
924:
925: # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
926: RESET_SPECIAL (_rl_tty_chars.t_lnext);
927: # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
928:
929: # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
930: RESET_SPECIAL (_rl_tty_chars.t_werase);
931: # endif /* VWERASE && TERMIOS_TTY_DRIVER */
932: }
933:
934: #if defined (HANDLE_SIGNALS)
935:
936: #if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
937: int
938: _rl_disable_tty_signals (void)
939: {
940: return 0;
941: }
942:
943: int
944: _rl_restore_tty_signals (void)
945: {
946: return 0;
947: }
948: #else
949:
950: static TIOTYPE sigstty, nosigstty;
951: static int tty_sigs_disabled = 0;
952:
953: int
954: _rl_disable_tty_signals (void)
955: {
956: if (tty_sigs_disabled)
957: return 0;
958:
959: if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
960: return -1;
961:
962: nosigstty = sigstty;
963:
964: nosigstty.c_lflag &= ~ISIG;
965: nosigstty.c_iflag &= ~IXON;
966:
967: if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
968: return (_set_tty_settings (fileno (rl_instream), &sigstty));
969:
970: tty_sigs_disabled = 1;
971: return 0;
972: }
973:
974: int
975: _rl_restore_tty_signals (void)
976: {
977: int r;
978:
979: if (tty_sigs_disabled == 0)
980: return 0;
981:
982: r = _set_tty_settings (fileno (rl_instream), &sigstty);
983:
984: if (r == 0)
985: tty_sigs_disabled = 0;
986:
987: return r;
988: }
989: #endif /* !NEW_TTY_DRIVER */
990:
991: #endif /* HANDLE_SIGNALS */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>