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