1 /* rltty.c -- functions to prepare and restore the terminal for readline's
4 /* Copyright (C) 1992 Free Software Foundation, Inc.
6 This file is part of the GNU Readline Library, a library for
7 reading lines of text with interactive input and history editing.
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.
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.
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 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #define READLINE_LIBRARY
25 #if defined (HAVE_CONFIG_H)
29 #include <sys/types.h>
34 #if defined (HAVE_UNISTD_H)
36 #endif /* HAVE_UNISTD_H */
40 #if defined (GWINSZ_IN_SYS_IOCTL)
41 # include <sys/ioctl.h>
42 #endif /* GWINSZ_IN_SYS_IOCTL */
46 #include "rlprivate.h"
52 rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
53 rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
55 /* **************************************************************** */
57 /* Signal Management */
59 /* **************************************************************** */
61 #if defined (HAVE_POSIX_SIGNALS)
62 static sigset_t sigint_set, sigint_oset;
63 #else /* !HAVE_POSIX_SIGNALS */
64 # if defined (HAVE_BSD_SIGNALS)
65 static int sigint_oldmask;
66 # endif /* HAVE_BSD_SIGNALS */
67 #endif /* !HAVE_POSIX_SIGNALS */
69 static int sigint_blocked;
71 /* Cause SIGINT to not be delivered until the corresponding call to
79 #if defined (HAVE_POSIX_SIGNALS)
80 sigemptyset (&sigint_set);
81 sigemptyset (&sigint_oset);
82 sigaddset (&sigint_set, SIGINT);
83 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
84 #else /* !HAVE_POSIX_SIGNALS */
85 # if defined (HAVE_BSD_SIGNALS)
86 sigint_oldmask = sigblock (sigmask (SIGINT));
87 # else /* !HAVE_BSD_SIGNALS */
88 # if defined (HAVE_USG_SIGHOLD)
90 # endif /* HAVE_USG_SIGHOLD */
91 # endif /* !HAVE_BSD_SIGNALS */
92 #endif /* !HAVE_POSIX_SIGNALS */
97 /* Allow SIGINT to be delivered. */
101 if (sigint_blocked == 0)
104 #if defined (HAVE_POSIX_SIGNALS)
105 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
107 # if defined (HAVE_BSD_SIGNALS)
108 sigsetmask (sigint_oldmask);
109 # else /* !HAVE_BSD_SIGNALS */
110 # if defined (HAVE_USG_SIGHOLD)
112 # endif /* HAVE_USG_SIGHOLD */
113 # endif /* !HAVE_BSD_SIGNALS */
114 #endif /* !HAVE_POSIX_SIGNALS */
119 /* **************************************************************** */
121 /* Saving and Restoring the TTY */
123 /* **************************************************************** */
125 /* Non-zero means that the terminal is in a prepped state. */
126 static int terminal_prepped;
128 static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
130 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
131 and output is suspended. */
132 #if defined (__ksr1__)
136 /* Dummy call to force a backgrounded readline to stop before it tries
137 to get the tty settings. */
142 #if defined (TIOCGWINSZ)
145 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
146 (void) ioctl (tty, TIOCSWINSZ, &w);
147 #endif /* TIOCGWINSZ */
150 #if defined (NEW_TTY_DRIVER)
152 /* Values for the `flags' field of a struct bsdtty. This tells which
153 elements of the struct bsdtty have been fetched from the system and
155 #define SGTTY_SET 0x01
156 #define LFLAG_SET 0x02
157 #define TCHARS_SET 0x04
158 #define LTCHARS_SET 0x08
161 struct sgttyb sgttyb; /* Basic BSD tty driver information. */
162 int lflag; /* Local mode flags, like LPASS8. */
163 #if defined (TIOCGETC)
164 struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
166 #if defined (TIOCGLTC)
167 struct ltchars ltchars; /* 4.2 BSD editing characters */
169 int flags; /* Bitmap saying which parts of the struct are valid. */
172 #define TIOTYPE struct bsdtty
177 save_tty_chars (tiop)
180 _rl_last_tty_chars = _rl_tty_chars;
182 if (tiop->flags & SGTTY_SET)
184 _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
185 _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
188 if (tiop->flags & TCHARS_SET)
190 _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
191 _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
192 _rl_tty_chars.t_start = tiop->tchars.t_startc;
193 _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
194 _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
195 _rl_tty_chars.t_eol = '\n';
196 _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
199 if (tiop->flags & LTCHARS_SET)
201 _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
202 _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
203 _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
204 _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
205 _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
206 _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
209 _rl_tty_chars.t_status = -1;
213 get_tty_settings (tty, tiop)
219 tiop->flags = tiop->lflag = 0;
221 if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
223 tiop->flags |= SGTTY_SET;
225 #if defined (TIOCLGET)
226 if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
227 tiop->flags |= LFLAG_SET;
230 #if defined (TIOCGETC)
231 if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
232 tiop->flags |= TCHARS_SET;
235 #if defined (TIOCGLTC)
236 if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
237 tiop->flags |= LTCHARS_SET;
244 set_tty_settings (tty, tiop)
248 if (tiop->flags & SGTTY_SET)
250 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
251 tiop->flags &= ~SGTTY_SET;
253 readline_echoing_p = 1;
255 #if defined (TIOCLSET)
256 if (tiop->flags & LFLAG_SET)
258 ioctl (tty, TIOCLSET, &(tiop->lflag));
259 tiop->flags &= ~LFLAG_SET;
263 #if defined (TIOCSETC)
264 if (tiop->flags & TCHARS_SET)
266 ioctl (tty, TIOCSETC, &(tiop->tchars));
267 tiop->flags &= ~TCHARS_SET;
271 #if defined (TIOCSLTC)
272 if (tiop->flags & LTCHARS_SET)
274 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
275 tiop->flags &= ~LTCHARS_SET;
283 prepare_terminal_settings (meta_flag, oldtio, tiop)
285 TIOTYPE oldtio, *tiop;
287 readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
289 /* Copy the original settings to the structure we're going to use for
291 tiop->sgttyb = oldtio.sgttyb;
292 tiop->lflag = oldtio.lflag;
293 #if defined (TIOCGETC)
294 tiop->tchars = oldtio.tchars;
296 #if defined (TIOCGLTC)
297 tiop->ltchars = oldtio.ltchars;
299 tiop->flags = oldtio.flags;
301 /* First, the basic settings to put us into character-at-a-time, no-echo
303 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
304 tiop->sgttyb.sg_flags |= CBREAK;
306 /* If this terminal doesn't care how the 8th bit is used, then we can
307 use it for the meta-key. If only one of even or odd parity is
308 specified, then the terminal is using parity, and we cannot. */
310 # define ANYP (EVENP | ODDP)
312 if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
313 ((oldtio.sgttyb.sg_flags & ANYP) == 0))
315 tiop->sgttyb.sg_flags |= ANYP;
317 /* Hack on local mode flags if we can. */
318 #if defined (TIOCLGET)
319 # if defined (LPASS8)
320 tiop->lflag |= LPASS8;
322 #endif /* TIOCLGET */
325 #if defined (TIOCGETC)
326 # if defined (USE_XON_XOFF)
327 /* Get rid of terminal output start and stop characters. */
328 tiop->tchars.t_stopc = -1; /* C-s */
329 tiop->tchars.t_startc = -1; /* C-q */
331 /* If there is an XON character, bind it to restart the output. */
332 if (oldtio.tchars.t_startc != -1)
333 rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
334 # endif /* USE_XON_XOFF */
336 /* If there is an EOF char, bind _rl_eof_char to it. */
337 if (oldtio.tchars.t_eofc != -1)
338 _rl_eof_char = oldtio.tchars.t_eofc;
340 # if defined (NO_KILL_INTR)
341 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
342 tiop->tchars.t_quitc = -1; /* C-\ */
343 tiop->tchars.t_intrc = -1; /* C-c */
344 # endif /* NO_KILL_INTR */
345 #endif /* TIOCGETC */
347 #if defined (TIOCGLTC)
348 /* Make the interrupt keys go away. Just enough to make people happy. */
349 tiop->ltchars.t_dsuspc = -1; /* C-y */
350 tiop->ltchars.t_lnextc = -1; /* C-v */
351 #endif /* TIOCGLTC */
354 #else /* !defined (NEW_TTY_DRIVER) */
364 #if defined (TERMIOS_TTY_DRIVER)
365 # define TIOTYPE struct termios
366 # define DRAIN_OUTPUT(fd) tcdrain (fd)
367 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
369 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
371 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
372 # endif /* !M_UNIX */
374 # define TIOTYPE struct termio
375 # define DRAIN_OUTPUT(fd)
376 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
377 # define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
378 #endif /* !TERMIOS_TTY_DRIVER */
383 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
385 # define OUTPUT_BEING_FLUSHED(tp) 0
389 save_tty_chars (tiop)
392 _rl_last_tty_chars = _rl_tty_chars;
394 _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
395 _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
397 _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
399 _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
401 _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
403 _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
405 _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
407 _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
408 _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
410 _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
413 _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
416 _rl_tty_chars.t_start = tiop->c_cc[VSTART];
419 _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
422 _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
425 _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
428 _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
432 #if defined (_AIX) || defined (_AIX41)
433 /* Currently this is only used on AIX */
438 fprintf (stderr, "readline: warning: %s\n", msg);
447 if ((tp->c_oflag & OPOST) == 0)
449 rltty_warning ("turning on OPOST for terminal\r");
450 tp->c_oflag |= OPOST|ONLCR;
456 _get_tty_settings (tty, tiop)
464 ioctl_ret = GETATTR (tty, tiop);
472 if (OUTPUT_BEING_FLUSHED (tiop))
474 #if defined (FLUSHO) && defined (_AIX41)
475 rltty_warning ("turning off output flushing");
476 tiop->c_lflag &= ~FLUSHO;
489 get_tty_settings (tty, tiop)
495 if (_get_tty_settings (tty, tiop) < 0)
506 _set_tty_settings (tty, tiop)
510 while (SETATTR (tty, tiop) < 0)
520 set_tty_settings (tty, tiop)
524 if (_set_tty_settings (tty, tiop) < 0)
529 #if defined (TERMIOS_TTY_DRIVER)
530 # if defined (__ksr1__)
537 tcflow (tty, TCOON); /* Simulate a ^Q. */
540 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
541 #endif /* !TERMIOS_TTY_DRIVER */
549 prepare_terminal_settings (meta_flag, oldtio, tiop)
551 TIOTYPE oldtio, *tiop;
553 readline_echoing_p = (oldtio.c_lflag & ECHO);
555 tiop->c_lflag &= ~(ICANON | ECHO);
557 if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
558 _rl_eof_char = oldtio.c_cc[VEOF];
560 #if defined (USE_XON_XOFF)
562 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
564 /* `strict' Posix systems do not define IXANY. */
565 tiop->c_iflag &= ~(IXON | IXOFF);
567 #endif /* USE_XON_XOFF */
569 /* Only turn this off if we are using all 8 bits. */
570 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
571 tiop->c_iflag &= ~(ISTRIP | INPCK);
573 /* Make sure we differentiate between CR and NL on input. */
574 tiop->c_iflag &= ~(ICRNL | INLCR);
576 #if !defined (HANDLE_SIGNALS)
577 tiop->c_lflag &= ~ISIG;
579 tiop->c_lflag |= ISIG;
582 tiop->c_cc[VMIN] = 1;
583 tiop->c_cc[VTIME] = 0;
586 if (OUTPUT_BEING_FLUSHED (tiop))
588 tiop->c_lflag &= ~FLUSHO;
589 oldtio.c_lflag &= ~FLUSHO;
593 /* Turn off characters that we need on Posix systems with job control,
594 just to be sure. This includes ^Y and ^V. This should not really
596 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
599 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
603 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
606 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
608 #endif /* NEW_TTY_DRIVER */
610 /* Put the terminal in CBREAK mode so that we can detect key presses. */
612 rl_prep_terminal (meta_flag)
618 if (terminal_prepped)
621 /* Try to keep this function from being INTerrupted. */
624 tty = fileno (rl_instream);
626 if (get_tty_settings (tty, &tio) < 0)
634 save_tty_chars (&otio);
636 prepare_terminal_settings (meta_flag, otio, &tio);
638 if (set_tty_settings (tty, &tio) < 0)
644 if (_rl_enable_keypad)
645 _rl_control_keypad (1);
647 fflush (rl_outstream);
648 terminal_prepped = 1;
649 RL_SETSTATE(RL_STATE_TERMPREPPED);
654 /* Restore the terminal's normal settings and modes. */
656 rl_deprep_terminal ()
660 if (!terminal_prepped)
663 /* Try to keep this function from being interrupted. */
666 tty = fileno (rl_instream);
668 if (_rl_enable_keypad)
669 _rl_control_keypad (0);
671 fflush (rl_outstream);
673 if (set_tty_settings (tty, &otio) < 0)
679 terminal_prepped = 0;
680 RL_UNSETSTATE(RL_STATE_TERMPREPPED);
685 /* **************************************************************** */
687 /* Bogus Flow Control */
689 /* **************************************************************** */
692 rl_restart_output (count, key)
695 int fildes = fileno (rl_outstream);
696 #if defined (TIOCSTART)
698 ioctl (&fildes, TIOCSTART, 0);
700 ioctl (fildes, TIOCSTART, 0);
703 #else /* !TIOCSTART */
704 # if defined (TERMIOS_TTY_DRIVER)
705 # if defined (__ksr1__)
709 tcflow (fildes, TCOON);
712 tcflow (fildes, TCOON); /* Simulate a ^Q. */
714 # else /* !TERMIOS_TTY_DRIVER */
715 # if defined (TCXONC)
716 ioctl (fildes, TCXONC, TCOON);
718 # endif /* !TERMIOS_TTY_DRIVER */
719 #endif /* !TIOCSTART */
725 rl_stop_output (count, key)
728 int fildes = fileno (rl_instream);
730 #if defined (TIOCSTOP)
731 # if defined (apollo)
732 ioctl (&fildes, TIOCSTOP, 0);
734 ioctl (fildes, TIOCSTOP, 0);
736 #else /* !TIOCSTOP */
737 # if defined (TERMIOS_TTY_DRIVER)
738 # if defined (__ksr1__)
741 tcflow (fildes, TCOOFF);
743 # if defined (TCXONC)
744 ioctl (fildes, TCXONC, TCOON);
746 # endif /* !TERMIOS_TTY_DRIVER */
747 #endif /* !TIOCSTOP */
752 /* **************************************************************** */
754 /* Default Key Bindings */
756 /* **************************************************************** */
758 /* Set the system's default editing characters to their readline equivalents
759 in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
761 rltty_set_default_bindings (kmap)
765 int tty = fileno (rl_instream);
767 #if defined (NEW_TTY_DRIVER)
769 #define SET_SPECIAL(sc, func) \
774 if (ic != -1 && kmap[ic].type == ISFUNC) \
775 kmap[ic].function = func; \
779 if (get_tty_settings (tty, &ttybuff) == 0)
781 if (ttybuff.flags & SGTTY_SET)
783 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
784 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
787 # if defined (TIOCGLTC)
788 if (ttybuff.flags & LTCHARS_SET)
790 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
791 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
793 # endif /* TIOCGLTC */
796 #else /* !NEW_TTY_DRIVER */
798 #define SET_SPECIAL(sc, func) \
802 uc = ttybuff.c_cc[sc]; \
803 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
804 kmap[uc].function = func; \
808 if (get_tty_settings (tty, &ttybuff) == 0)
810 SET_SPECIAL (VERASE, rl_rubout);
811 SET_SPECIAL (VKILL, rl_unix_line_discard);
813 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
814 SET_SPECIAL (VLNEXT, rl_quoted_insert);
815 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
817 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
818 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
819 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
821 #endif /* !NEW_TTY_DRIVER */
824 /* New public way to set the system default editing chars to their readline
827 rl_tty_set_default_bindings (kmap)
830 rltty_set_default_bindings (kmap);
833 #if defined (HANDLE_SIGNALS)
835 #if defined (NEW_TTY_DRIVER)
837 _rl_disable_tty_signals ()
843 _rl_restore_tty_signals ()
849 static TIOTYPE sigstty, nosigstty;
850 static int tty_sigs_disabled = 0;
853 _rl_disable_tty_signals ()
855 if (tty_sigs_disabled)
858 if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
863 nosigstty.c_lflag &= ~ISIG;
865 if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
866 return (_set_tty_settings (fileno (rl_instream), &sigstty));
868 tty_sigs_disabled = 1;
873 _rl_restore_tty_signals ()
875 if (tty_sigs_disabled == 0)
878 return (_set_tty_settings (fileno (rl_instream), &sigstty));
880 #endif /* !NEW_TTY_DRIVER */
882 #endif /* HANDLE_SIGNALS */