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 static void block_sigint PARAMS((void));
56 static void release_sigint PARAMS((void));
58 static void set_winsize PARAMS((int));
60 /* **************************************************************** */
62 /* Signal Management */
64 /* **************************************************************** */
66 #if defined (HAVE_POSIX_SIGNALS)
67 static sigset_t sigint_set, sigint_oset;
68 #else /* !HAVE_POSIX_SIGNALS */
69 # if defined (HAVE_BSD_SIGNALS)
70 static int sigint_oldmask;
71 # endif /* HAVE_BSD_SIGNALS */
72 #endif /* !HAVE_POSIX_SIGNALS */
74 static int sigint_blocked;
76 /* Cause SIGINT to not be delivered until the corresponding call to
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)
95 # endif /* HAVE_USG_SIGHOLD */
96 # endif /* !HAVE_BSD_SIGNALS */
97 #endif /* !HAVE_POSIX_SIGNALS */
102 /* Allow SIGINT to be delivered. */
106 if (sigint_blocked == 0)
109 #if defined (HAVE_POSIX_SIGNALS)
110 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
112 # if defined (HAVE_BSD_SIGNALS)
113 sigsetmask (sigint_oldmask);
114 # else /* !HAVE_BSD_SIGNALS */
115 # if defined (HAVE_USG_SIGHOLD)
117 # endif /* HAVE_USG_SIGHOLD */
118 # endif /* !HAVE_BSD_SIGNALS */
119 #endif /* !HAVE_POSIX_SIGNALS */
124 /* **************************************************************** */
126 /* Saving and Restoring the TTY */
128 /* **************************************************************** */
130 /* Non-zero means that the terminal is in a prepped state. */
131 static int terminal_prepped;
133 static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
135 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
136 and output is suspended. */
137 #if defined (__ksr1__)
141 /* Dummy call to force a backgrounded readline to stop before it tries
142 to get the tty settings. */
147 #if defined (TIOCGWINSZ)
150 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
151 (void) ioctl (tty, TIOCSWINSZ, &w);
152 #endif /* TIOCGWINSZ */
155 #if defined (NEW_TTY_DRIVER)
157 /* Values for the `flags' field of a struct bsdtty. This tells which
158 elements of the struct bsdtty have been fetched from the system and
160 #define SGTTY_SET 0x01
161 #define LFLAG_SET 0x02
162 #define TCHARS_SET 0x04
163 #define LTCHARS_SET 0x08
166 struct sgttyb sgttyb; /* Basic BSD tty driver information. */
167 int lflag; /* Local mode flags, like LPASS8. */
168 #if defined (TIOCGETC)
169 struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
171 #if defined (TIOCGLTC)
172 struct ltchars ltchars; /* 4.2 BSD editing characters */
174 int flags; /* Bitmap saying which parts of the struct are valid. */
177 #define TIOTYPE struct bsdtty
181 static void save_tty_chars PARAMS((TIOTYPE *));
182 static int _get_tty_settings PARAMS((int, TIOTYPE *));
183 static int get_tty_settings PARAMS((int, TIOTYPE *));
184 static int _set_tty_settings PARAMS((int, TIOTYPE *));
185 static int set_tty_settings PARAMS((int, TIOTYPE *));
187 static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
190 save_tty_chars (tiop)
193 _rl_last_tty_chars = _rl_tty_chars;
195 if (tiop->flags & SGTTY_SET)
197 _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
198 _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
201 if (tiop->flags & TCHARS_SET)
203 _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
204 _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
205 _rl_tty_chars.t_start = tiop->tchars.t_startc;
206 _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
207 _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
208 _rl_tty_chars.t_eol = '\n';
209 _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
212 if (tiop->flags & LTCHARS_SET)
214 _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
215 _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
216 _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
217 _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
218 _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
219 _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
222 _rl_tty_chars.t_status = -1;
226 get_tty_settings (tty, tiop)
232 tiop->flags = tiop->lflag = 0;
234 if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
236 tiop->flags |= SGTTY_SET;
238 #if defined (TIOCLGET)
239 if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
240 tiop->flags |= LFLAG_SET;
243 #if defined (TIOCGETC)
244 if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
245 tiop->flags |= TCHARS_SET;
248 #if defined (TIOCGLTC)
249 if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
250 tiop->flags |= LTCHARS_SET;
257 set_tty_settings (tty, tiop)
261 if (tiop->flags & SGTTY_SET)
263 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
264 tiop->flags &= ~SGTTY_SET;
266 readline_echoing_p = 1;
268 #if defined (TIOCLSET)
269 if (tiop->flags & LFLAG_SET)
271 ioctl (tty, TIOCLSET, &(tiop->lflag));
272 tiop->flags &= ~LFLAG_SET;
276 #if defined (TIOCSETC)
277 if (tiop->flags & TCHARS_SET)
279 ioctl (tty, TIOCSETC, &(tiop->tchars));
280 tiop->flags &= ~TCHARS_SET;
284 #if defined (TIOCSLTC)
285 if (tiop->flags & LTCHARS_SET)
287 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
288 tiop->flags &= ~LTCHARS_SET;
296 prepare_terminal_settings (meta_flag, oldtio, tiop)
298 TIOTYPE oldtio, *tiop;
300 readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
302 /* Copy the original settings to the structure we're going to use for
304 tiop->sgttyb = oldtio.sgttyb;
305 tiop->lflag = oldtio.lflag;
306 #if defined (TIOCGETC)
307 tiop->tchars = oldtio.tchars;
309 #if defined (TIOCGLTC)
310 tiop->ltchars = oldtio.ltchars;
312 tiop->flags = oldtio.flags;
314 /* First, the basic settings to put us into character-at-a-time, no-echo
316 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
317 tiop->sgttyb.sg_flags |= CBREAK;
319 /* If this terminal doesn't care how the 8th bit is used, then we can
320 use it for the meta-key. If only one of even or odd parity is
321 specified, then the terminal is using parity, and we cannot. */
323 # define ANYP (EVENP | ODDP)
325 if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
326 ((oldtio.sgttyb.sg_flags & ANYP) == 0))
328 tiop->sgttyb.sg_flags |= ANYP;
330 /* Hack on local mode flags if we can. */
331 #if defined (TIOCLGET)
332 # if defined (LPASS8)
333 tiop->lflag |= LPASS8;
335 #endif /* TIOCLGET */
338 #if defined (TIOCGETC)
339 # if defined (USE_XON_XOFF)
340 /* Get rid of terminal output start and stop characters. */
341 tiop->tchars.t_stopc = -1; /* C-s */
342 tiop->tchars.t_startc = -1; /* C-q */
344 /* If there is an XON character, bind it to restart the output. */
345 if (oldtio.tchars.t_startc != -1)
346 rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
347 # endif /* USE_XON_XOFF */
349 /* If there is an EOF char, bind _rl_eof_char to it. */
350 if (oldtio.tchars.t_eofc != -1)
351 _rl_eof_char = oldtio.tchars.t_eofc;
353 # if defined (NO_KILL_INTR)
354 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
355 tiop->tchars.t_quitc = -1; /* C-\ */
356 tiop->tchars.t_intrc = -1; /* C-c */
357 # endif /* NO_KILL_INTR */
358 #endif /* TIOCGETC */
360 #if defined (TIOCGLTC)
361 /* Make the interrupt keys go away. Just enough to make people happy. */
362 tiop->ltchars.t_dsuspc = -1; /* C-y */
363 tiop->ltchars.t_lnextc = -1; /* C-v */
364 #endif /* TIOCGLTC */
367 #else /* !defined (NEW_TTY_DRIVER) */
377 #if defined (TERMIOS_TTY_DRIVER)
378 # define TIOTYPE struct termios
379 # define DRAIN_OUTPUT(fd) tcdrain (fd)
380 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
382 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
384 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
385 # endif /* !M_UNIX */
387 # define TIOTYPE struct termio
388 # define DRAIN_OUTPUT(fd)
389 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
390 # define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
391 #endif /* !TERMIOS_TTY_DRIVER */
395 static void save_tty_chars PARAMS((TIOTYPE *));
396 static int _get_tty_settings PARAMS((int, TIOTYPE *));
397 static int get_tty_settings PARAMS((int, TIOTYPE *));
398 static int _set_tty_settings PARAMS((int, TIOTYPE *));
399 static int set_tty_settings PARAMS((int, TIOTYPE *));
401 static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
404 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
406 # define OUTPUT_BEING_FLUSHED(tp) 0
410 save_tty_chars (tiop)
413 _rl_last_tty_chars = _rl_tty_chars;
415 _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
416 _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
418 _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
420 _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
422 _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
424 _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
426 _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
428 _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
429 _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
431 _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
434 _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
437 _rl_tty_chars.t_start = tiop->c_cc[VSTART];
440 _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
443 _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
446 _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
449 _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
453 #if defined (_AIX) || defined (_AIX41)
454 /* Currently this is only used on AIX */
459 fprintf (stderr, "readline: warning: %s\n", msg);
468 if ((tp->c_oflag & OPOST) == 0)
470 rltty_warning ("turning on OPOST for terminal\r");
471 tp->c_oflag |= OPOST|ONLCR;
477 _get_tty_settings (tty, tiop)
485 ioctl_ret = GETATTR (tty, tiop);
493 if (OUTPUT_BEING_FLUSHED (tiop))
495 #if defined (FLUSHO) && defined (_AIX41)
496 rltty_warning ("turning off output flushing");
497 tiop->c_lflag &= ~FLUSHO;
510 get_tty_settings (tty, tiop)
516 if (_get_tty_settings (tty, tiop) < 0)
527 _set_tty_settings (tty, tiop)
531 while (SETATTR (tty, tiop) < 0)
541 set_tty_settings (tty, tiop)
545 if (_set_tty_settings (tty, tiop) < 0)
550 #if defined (TERMIOS_TTY_DRIVER)
551 # if defined (__ksr1__)
558 tcflow (tty, TCOON); /* Simulate a ^Q. */
561 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
562 #endif /* !TERMIOS_TTY_DRIVER */
570 prepare_terminal_settings (meta_flag, oldtio, tiop)
572 TIOTYPE oldtio, *tiop;
574 readline_echoing_p = (oldtio.c_lflag & ECHO);
576 tiop->c_lflag &= ~(ICANON | ECHO);
578 if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
579 _rl_eof_char = oldtio.c_cc[VEOF];
581 #if defined (USE_XON_XOFF)
583 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
585 /* `strict' Posix systems do not define IXANY. */
586 tiop->c_iflag &= ~(IXON | IXOFF);
588 #endif /* USE_XON_XOFF */
590 /* Only turn this off if we are using all 8 bits. */
591 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
592 tiop->c_iflag &= ~(ISTRIP | INPCK);
594 /* Make sure we differentiate between CR and NL on input. */
595 tiop->c_iflag &= ~(ICRNL | INLCR);
597 #if !defined (HANDLE_SIGNALS)
598 tiop->c_lflag &= ~ISIG;
600 tiop->c_lflag |= ISIG;
603 tiop->c_cc[VMIN] = 1;
604 tiop->c_cc[VTIME] = 0;
607 if (OUTPUT_BEING_FLUSHED (tiop))
609 tiop->c_lflag &= ~FLUSHO;
610 oldtio.c_lflag &= ~FLUSHO;
614 /* Turn off characters that we need on Posix systems with job control,
615 just to be sure. This includes ^Y and ^V. This should not really
617 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
620 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
624 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
627 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
629 #endif /* NEW_TTY_DRIVER */
631 /* Put the terminal in CBREAK mode so that we can detect key presses. */
633 rl_prep_terminal (meta_flag)
639 if (terminal_prepped)
642 /* Try to keep this function from being INTerrupted. */
645 tty = fileno (rl_instream);
647 if (get_tty_settings (tty, &tio) < 0)
650 fprintf(stderr, "readline: warning: rl_prep_terminal: cannot get terminal settings");
656 save_tty_chars (&otio);
658 prepare_terminal_settings (meta_flag, otio, &tio);
660 if (set_tty_settings (tty, &tio) < 0)
666 if (_rl_enable_keypad)
667 _rl_control_keypad (1);
669 fflush (rl_outstream);
670 terminal_prepped = 1;
671 RL_SETSTATE(RL_STATE_TERMPREPPED);
676 /* Restore the terminal's normal settings and modes. */
678 rl_deprep_terminal ()
682 if (!terminal_prepped)
685 /* Try to keep this function from being interrupted. */
688 tty = fileno (rl_instream);
690 if (_rl_enable_keypad)
691 _rl_control_keypad (0);
693 fflush (rl_outstream);
695 if (set_tty_settings (tty, &otio) < 0)
701 terminal_prepped = 0;
702 RL_UNSETSTATE(RL_STATE_TERMPREPPED);
707 /* **************************************************************** */
709 /* Bogus Flow Control */
711 /* **************************************************************** */
714 rl_restart_output (count, key)
717 int fildes = fileno (rl_outstream);
718 #if defined (TIOCSTART)
720 ioctl (&fildes, TIOCSTART, 0);
722 ioctl (fildes, TIOCSTART, 0);
725 #else /* !TIOCSTART */
726 # if defined (TERMIOS_TTY_DRIVER)
727 # if defined (__ksr1__)
731 tcflow (fildes, TCOON);
734 tcflow (fildes, TCOON); /* Simulate a ^Q. */
736 # else /* !TERMIOS_TTY_DRIVER */
737 # if defined (TCXONC)
738 ioctl (fildes, TCXONC, TCOON);
740 # endif /* !TERMIOS_TTY_DRIVER */
741 #endif /* !TIOCSTART */
747 rl_stop_output (count, key)
750 int fildes = fileno (rl_instream);
752 #if defined (TIOCSTOP)
753 # if defined (apollo)
754 ioctl (&fildes, TIOCSTOP, 0);
756 ioctl (fildes, TIOCSTOP, 0);
758 #else /* !TIOCSTOP */
759 # if defined (TERMIOS_TTY_DRIVER)
760 # if defined (__ksr1__)
763 tcflow (fildes, TCOOFF);
765 # if defined (TCXONC)
766 ioctl (fildes, TCXONC, TCOON);
768 # endif /* !TERMIOS_TTY_DRIVER */
769 #endif /* !TIOCSTOP */
774 /* **************************************************************** */
776 /* Default Key Bindings */
778 /* **************************************************************** */
780 /* Set the system's default editing characters to their readline equivalents
781 in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
783 rltty_set_default_bindings (kmap)
787 int tty = fileno (rl_instream);
789 #if defined (NEW_TTY_DRIVER)
791 #define SET_SPECIAL(sc, func) \
796 if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \
797 kmap[(unsigned char)ic].function = func; \
801 if (get_tty_settings (tty, &ttybuff) == 0)
803 if (ttybuff.flags & SGTTY_SET)
805 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
806 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
809 # if defined (TIOCGLTC)
810 if (ttybuff.flags & LTCHARS_SET)
812 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
813 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
815 # endif /* TIOCGLTC */
818 #else /* !NEW_TTY_DRIVER */
820 #define SET_SPECIAL(sc, func) \
824 uc = ttybuff.c_cc[sc]; \
825 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
826 kmap[uc].function = func; \
830 if (get_tty_settings (tty, &ttybuff) == 0)
832 SET_SPECIAL (VERASE, rl_rubout);
833 SET_SPECIAL (VKILL, rl_unix_line_discard);
835 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
836 SET_SPECIAL (VLNEXT, rl_quoted_insert);
837 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
839 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
840 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
841 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
843 #endif /* !NEW_TTY_DRIVER */
846 /* New public way to set the system default editing chars to their readline
849 rl_tty_set_default_bindings (kmap)
852 rltty_set_default_bindings (kmap);
855 #if defined (HANDLE_SIGNALS)
857 #if defined (NEW_TTY_DRIVER)
859 _rl_disable_tty_signals ()
865 _rl_restore_tty_signals ()
871 static TIOTYPE sigstty, nosigstty;
872 static int tty_sigs_disabled = 0;
875 _rl_disable_tty_signals ()
877 if (tty_sigs_disabled)
880 if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
885 nosigstty.c_lflag &= ~ISIG;
886 nosigstty.c_iflag &= ~IXON;
888 if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
889 return (_set_tty_settings (fileno (rl_instream), &sigstty));
891 tty_sigs_disabled = 1;
896 _rl_restore_tty_signals ()
900 if (tty_sigs_disabled == 0)
903 r = _set_tty_settings (fileno (rl_instream), &sigstty);
906 tty_sigs_disabled = 0;
910 #endif /* !NEW_TTY_DRIVER */
912 #endif /* HANDLE_SIGNALS */