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 VFunction *rl_prep_term_function = rl_prep_terminal;
53 VFunction *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)
217 #if defined (TIOCGWINSZ)
221 tiop->flags = tiop->lflag = 0;
223 ioctl (tty, TIOCGETP, &(tiop->sgttyb));
224 tiop->flags |= SGTTY_SET;
226 #if defined (TIOCLGET)
227 ioctl (tty, TIOCLGET, &(tiop->lflag));
228 tiop->flags |= LFLAG_SET;
231 #if defined (TIOCGETC)
232 ioctl (tty, TIOCGETC, &(tiop->tchars));
233 tiop->flags |= TCHARS_SET;
236 #if defined (TIOCGLTC)
237 ioctl (tty, TIOCGLTC, &(tiop->ltchars));
238 tiop->flags |= LTCHARS_SET;
245 set_tty_settings (tty, tiop)
249 if (tiop->flags & SGTTY_SET)
251 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
252 tiop->flags &= ~SGTTY_SET;
254 readline_echoing_p = 1;
256 #if defined (TIOCLSET)
257 if (tiop->flags & LFLAG_SET)
259 ioctl (tty, TIOCLSET, &(tiop->lflag));
260 tiop->flags &= ~LFLAG_SET;
264 #if defined (TIOCSETC)
265 if (tiop->flags & TCHARS_SET)
267 ioctl (tty, TIOCSETC, &(tiop->tchars));
268 tiop->flags &= ~TCHARS_SET;
272 #if defined (TIOCSLTC)
273 if (tiop->flags & LTCHARS_SET)
275 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
276 tiop->flags &= ~LTCHARS_SET;
284 prepare_terminal_settings (meta_flag, otio, tiop)
288 readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
290 /* Copy the original settings to the structure we're going to use for
292 tiop->sgttyb = otio.sgttyb;
293 tiop->lflag = otio.lflag;
294 #if defined (TIOCGETC)
295 tiop->tchars = otio.tchars;
297 #if defined (TIOCGLTC)
298 tiop->ltchars = otio.ltchars;
300 tiop->flags = otio.flags;
302 /* First, the basic settings to put us into character-at-a-time, no-echo
304 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
305 tiop->sgttyb.sg_flags |= CBREAK;
307 /* If this terminal doesn't care how the 8th bit is used, then we can
308 use it for the meta-key. If only one of even or odd parity is
309 specified, then the terminal is using parity, and we cannot. */
311 # define ANYP (EVENP | ODDP)
313 if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
314 ((otio.sgttyb.sg_flags & ANYP) == 0))
316 tiop->sgttyb.sg_flags |= ANYP;
318 /* Hack on local mode flags if we can. */
319 #if defined (TIOCLGET)
320 # if defined (LPASS8)
321 tiop->lflag |= LPASS8;
323 #endif /* TIOCLGET */
326 #if defined (TIOCGETC)
327 # if defined (USE_XON_XOFF)
328 /* Get rid of terminal output start and stop characters. */
329 tiop->tchars.t_stopc = -1; /* C-s */
330 tiop->tchars.t_startc = -1; /* C-q */
332 /* If there is an XON character, bind it to restart the output. */
333 if (otio.tchars.t_startc != -1)
334 rl_bind_key (otio.tchars.t_startc, rl_restart_output);
335 # endif /* USE_XON_XOFF */
337 /* If there is an EOF char, bind _rl_eof_char to it. */
338 if (otio.tchars.t_eofc != -1)
339 _rl_eof_char = otio.tchars.t_eofc;
341 # if defined (NO_KILL_INTR)
342 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
343 tiop->tchars.t_quitc = -1; /* C-\ */
344 tiop->tchars.t_intrc = -1; /* C-c */
345 # endif /* NO_KILL_INTR */
346 #endif /* TIOCGETC */
348 #if defined (TIOCGLTC)
349 /* Make the interrupt keys go away. Just enough to make people happy. */
350 tiop->ltchars.t_dsuspc = -1; /* C-y */
351 tiop->ltchars.t_lnextc = -1; /* C-v */
352 #endif /* TIOCGLTC */
355 #else /* !defined (NEW_TTY_DRIVER) */
365 #if defined (TERMIOS_TTY_DRIVER)
366 # define TIOTYPE struct termios
367 # define DRAIN_OUTPUT(fd) tcdrain (fd)
368 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
370 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
372 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
373 # endif /* !M_UNIX */
375 # define TIOTYPE struct termio
376 # define DRAIN_OUTPUT(fd)
377 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
378 # define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
379 #endif /* !TERMIOS_TTY_DRIVER */
384 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
386 # define OUTPUT_BEING_FLUSHED(tp) 0
390 save_tty_chars (tiop)
393 _rl_last_tty_chars = _rl_tty_chars;
395 _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
396 _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
398 _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
400 _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
402 _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
404 _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
406 _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
408 _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
409 _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
411 _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
414 _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
417 _rl_tty_chars.t_start = tiop->c_cc[VSTART];
420 _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
423 _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
426 _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
429 _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
433 #if defined (_AIX) || defined (_AIX41)
434 /* Currently this is only used on AIX */
439 fprintf (stderr, "readline: warning: %s\n", msg);
448 if ((tp->c_oflag & OPOST) == 0)
450 rltty_warning ("turning on OPOST for terminal\r");
451 tp->c_oflag |= OPOST|ONLCR;
457 _get_tty_settings (tty, tiop)
465 ioctl_ret = GETATTR (tty, tiop);
473 if (OUTPUT_BEING_FLUSHED (tiop))
475 #if defined (FLUSHO) && defined (_AIX41)
476 rltty_warning ("turning off output flushing");
477 tiop->c_lflag &= ~FLUSHO;
490 get_tty_settings (tty, tiop)
494 #if defined (TIOCGWINSZ)
498 if (_get_tty_settings (tty, tiop) < 0)
509 _set_tty_settings (tty, tiop)
513 while (SETATTR (tty, tiop) < 0)
523 set_tty_settings (tty, tiop)
527 if (_set_tty_settings (tty, tiop) < 0)
532 #if defined (TERMIOS_TTY_DRIVER)
533 # if defined (__ksr1__)
540 tcflow (tty, TCOON); /* Simulate a ^Q. */
543 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
544 #endif /* !TERMIOS_TTY_DRIVER */
552 prepare_terminal_settings (meta_flag, otio, tiop)
556 readline_echoing_p = (otio.c_lflag & ECHO);
558 tiop->c_lflag &= ~(ICANON | ECHO);
560 if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
561 _rl_eof_char = otio.c_cc[VEOF];
563 #if defined (USE_XON_XOFF)
565 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
567 /* `strict' Posix systems do not define IXANY. */
568 tiop->c_iflag &= ~(IXON | IXOFF);
570 #endif /* USE_XON_XOFF */
572 /* Only turn this off if we are using all 8 bits. */
573 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
574 tiop->c_iflag &= ~(ISTRIP | INPCK);
576 /* Make sure we differentiate between CR and NL on input. */
577 tiop->c_iflag &= ~(ICRNL | INLCR);
579 #if !defined (HANDLE_SIGNALS)
580 tiop->c_lflag &= ~ISIG;
582 tiop->c_lflag |= ISIG;
585 tiop->c_cc[VMIN] = 1;
586 tiop->c_cc[VTIME] = 0;
589 if (OUTPUT_BEING_FLUSHED (tiop))
591 tiop->c_lflag &= ~FLUSHO;
592 otio.c_lflag &= ~FLUSHO;
596 /* Turn off characters that we need on Posix systems with job control,
597 just to be sure. This includes ^Y and ^V. This should not really
599 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
602 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
606 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
609 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
611 #endif /* NEW_TTY_DRIVER */
613 /* Put the terminal in CBREAK mode so that we can detect key presses. */
615 rl_prep_terminal (meta_flag)
621 if (terminal_prepped)
624 /* Try to keep this function from being INTerrupted. */
627 tty = fileno (rl_instream);
629 if (get_tty_settings (tty, &tio) < 0)
637 save_tty_chars (&otio);
639 prepare_terminal_settings (meta_flag, otio, &tio);
641 if (set_tty_settings (tty, &tio) < 0)
647 if (_rl_enable_keypad)
648 _rl_control_keypad (1);
650 fflush (rl_outstream);
651 terminal_prepped = 1;
656 /* Restore the terminal's normal settings and modes. */
658 rl_deprep_terminal ()
662 if (!terminal_prepped)
665 /* Try to keep this function from being interrupted. */
668 tty = fileno (rl_instream);
670 if (_rl_enable_keypad)
671 _rl_control_keypad (0);
673 fflush (rl_outstream);
675 if (set_tty_settings (tty, &otio) < 0)
681 terminal_prepped = 0;
686 /* **************************************************************** */
688 /* Bogus Flow Control */
690 /* **************************************************************** */
693 rl_restart_output (count, key)
696 int fildes = fileno (rl_outstream);
697 #if defined (TIOCSTART)
699 ioctl (&fildes, TIOCSTART, 0);
701 ioctl (fildes, TIOCSTART, 0);
704 #else /* !TIOCSTART */
705 # if defined (TERMIOS_TTY_DRIVER)
706 # if defined (__ksr1__)
710 tcflow (fildes, TCOON);
713 tcflow (fildes, TCOON); /* Simulate a ^Q. */
715 # else /* !TERMIOS_TTY_DRIVER */
716 # if defined (TCXONC)
717 ioctl (fildes, TCXONC, TCOON);
719 # endif /* !TERMIOS_TTY_DRIVER */
720 #endif /* !TIOCSTART */
726 rl_stop_output (count, key)
729 int fildes = fileno (rl_instream);
731 #if defined (TIOCSTOP)
732 # if defined (apollo)
733 ioctl (&fildes, TIOCSTOP, 0);
735 ioctl (fildes, TIOCSTOP, 0);
737 #else /* !TIOCSTOP */
738 # if defined (TERMIOS_TTY_DRIVER)
739 # if defined (__ksr1__)
742 tcflow (fildes, TCOOFF);
744 # if defined (TCXONC)
745 ioctl (fildes, TCXONC, TCOON);
747 # endif /* !TERMIOS_TTY_DRIVER */
748 #endif /* !TIOCSTOP */
753 /* **************************************************************** */
755 /* Default Key Bindings */
757 /* **************************************************************** */
759 rltty_set_default_bindings (kmap)
763 int tty = fileno (rl_instream);
765 #if defined (NEW_TTY_DRIVER)
767 #define SET_SPECIAL(sc, func) \
772 if (ic != -1 && kmap[ic].type == ISFUNC) \
773 kmap[ic].function = func; \
777 if (get_tty_settings (tty, &ttybuff) == 0)
779 if (ttybuff.flags & SGTTY_SET)
781 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
782 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
785 # if defined (TIOCGLTC)
786 if (ttybuff.flags & LTCHARS_SET)
788 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
789 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
791 # endif /* TIOCGLTC */
794 #else /* !NEW_TTY_DRIVER */
796 #define SET_SPECIAL(sc, func) \
800 uc = ttybuff.c_cc[sc]; \
801 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
802 kmap[uc].function = func; \
806 if (get_tty_settings (tty, &ttybuff) == 0)
808 SET_SPECIAL (VERASE, rl_rubout);
809 SET_SPECIAL (VKILL, rl_unix_line_discard);
811 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
812 SET_SPECIAL (VLNEXT, rl_quoted_insert);
813 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
815 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
816 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
817 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
819 #endif /* !NEW_TTY_DRIVER */
822 #if defined (HANDLE_SIGNALS)
824 #if defined (NEW_TTY_DRIVER)
826 _rl_disable_tty_signals ()
832 _rl_restore_tty_signals ()
838 static TIOTYPE sigstty, nosigstty;
839 static int tty_sigs_disabled = 0;
842 _rl_disable_tty_signals ()
844 if (tty_sigs_disabled)
847 if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
852 nosigstty.c_lflag &= ~ISIG;
854 if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
855 return (_set_tty_settings (fileno (rl_instream), &sigstty));
857 tty_sigs_disabled = 1;
862 _rl_restore_tty_signals ()
864 if (tty_sigs_disabled == 0)
867 return (_set_tty_settings (fileno (rl_instream), &sigstty));
869 #endif /* !NEW_TTY_DRIVER */
871 #endif /* HANDLE_SIGNALS */