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 1, 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 675 Mass Ave, Cambridge, MA 02139, 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 (SHELL) && defined (GWINSZ_IN_SYS_IOCTL)
41 # include <sys/ioctl.h>
42 #endif /* !SHELL && GWINSZ_IN_SYS_IOCTL */
51 extern int readline_echoing_p;
52 extern int _rl_eof_char;
54 extern int _rl_enable_keypad, _rl_enable_meta;
56 #if defined (__GO32__)
58 # undef HANDLE_SIGNALS
61 /* Indirect functions to allow apps control over terminal management. */
62 extern void rl_prep_terminal (), rl_deprep_terminal ();
64 VFunction *rl_prep_term_function = rl_prep_terminal;
65 VFunction *rl_deprep_term_function = rl_deprep_terminal;
67 /* **************************************************************** */
69 /* Signal Management */
71 /* **************************************************************** */
73 #if defined (HAVE_POSIX_SIGNALS)
74 static sigset_t sigint_set, sigint_oset;
75 #else /* !HAVE_POSIX_SIGNALS */
76 # if defined (HAVE_BSD_SIGNALS)
77 static int sigint_oldmask;
78 # endif /* HAVE_BSD_SIGNALS */
79 #endif /* !HAVE_POSIX_SIGNALS */
81 static int sigint_blocked;
83 /* Cause SIGINT to not be delivered until the corresponding call to
91 #if defined (HAVE_POSIX_SIGNALS)
92 sigemptyset (&sigint_set);
93 sigemptyset (&sigint_oset);
94 sigaddset (&sigint_set, SIGINT);
95 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
96 #else /* !HAVE_POSIX_SIGNALS */
97 # if defined (HAVE_BSD_SIGNALS)
98 sigint_oldmask = sigblock (sigmask (SIGINT));
99 # else /* !HAVE_BSD_SIGNALS */
100 # if defined (HAVE_USG_SIGHOLD)
102 # endif /* HAVE_USG_SIGHOLD */
103 # endif /* !HAVE_BSD_SIGNALS */
104 #endif /* !HAVE_POSIX_SIGNALS */
108 /* Allow SIGINT to be delivered. */
115 #if defined (HAVE_POSIX_SIGNALS)
116 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
118 # if defined (HAVE_BSD_SIGNALS)
119 sigsetmask (sigint_oldmask);
120 # else /* !HAVE_BSD_SIGNALS */
121 # if defined (HAVE_USG_SIGHOLD)
123 # endif /* HAVE_USG_SIGHOLD */
124 # endif /* !HAVE_BSD_SIGNALS */
125 #endif /* !HAVE_POSIX_SIGNALS */
130 /* **************************************************************** */
132 /* Saving and Restoring the TTY */
134 /* **************************************************************** */
136 /* Non-zero means that the terminal is in a prepped state. */
137 static int terminal_prepped;
139 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
140 and output is suspended. */
141 #if defined (__ksr1__)
145 #if !defined (SHELL) && defined (TIOCGWINSZ)
146 /* Dummy call to force a backgrounded readline to stop before it tries
147 to get the tty settings. */
154 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
155 (void) ioctl (tty, TIOCSWINSZ, &w);
157 #else /* SHELL || !TIOCGWINSZ */
158 # define set_winsize(tty)
159 #endif /* SHELL || !TIOCGWINSZ */
161 #if defined (NEW_TTY_DRIVER)
163 /* Values for the `flags' field of a struct bsdtty. This tells which
164 elements of the struct bsdtty have been fetched from the system and
166 #define SGTTY_SET 0x01
167 #define LFLAG_SET 0x02
168 #define TCHARS_SET 0x04
169 #define LTCHARS_SET 0x08
172 struct sgttyb sgttyb; /* Basic BSD tty driver information. */
173 int lflag; /* Local mode flags, like LPASS8. */
174 #if defined (TIOCGETC)
175 struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
177 #if defined (TIOCGLTC)
178 struct ltchars ltchars; /* 4.2 BSD editing characters */
180 int flags; /* Bitmap saying which parts of the struct are valid. */
183 #define TIOTYPE struct bsdtty
188 get_tty_settings (tty, tiop)
194 tiop->flags = tiop->lflag = 0;
196 ioctl (tty, TIOCGETP, &(tiop->sgttyb));
197 tiop->flags |= SGTTY_SET;
199 #if defined (TIOCLGET)
200 ioctl (tty, TIOCLGET, &(tiop->lflag));
201 tiop->flags |= LFLAG_SET;
204 #if defined (TIOCGETC)
205 ioctl (tty, TIOCGETC, &(tiop->tchars));
206 tiop->flags |= TCHARS_SET;
209 #if defined (TIOCGLTC)
210 ioctl (tty, TIOCGLTC, &(tiop->ltchars));
211 tiop->flags |= LTCHARS_SET;
218 set_tty_settings (tty, tiop)
222 if (tiop->flags & SGTTY_SET)
224 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
225 tiop->flags &= ~SGTTY_SET;
227 readline_echoing_p = 1;
229 #if defined (TIOCLSET)
230 if (tiop->flags & LFLAG_SET)
232 ioctl (tty, TIOCLSET, &(tiop->lflag));
233 tiop->flags &= ~LFLAG_SET;
237 #if defined (TIOCSETC)
238 if (tiop->flags & TCHARS_SET)
240 ioctl (tty, TIOCSETC, &(tiop->tchars));
241 tiop->flags &= ~TCHARS_SET;
245 #if defined (TIOCSLTC)
246 if (tiop->flags & LTCHARS_SET)
248 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
249 tiop->flags &= ~LTCHARS_SET;
257 prepare_terminal_settings (meta_flag, otio, tiop)
261 #if !defined (__GO32__)
262 readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
264 /* Copy the original settings to the structure we're going to use for
266 tiop->sgttyb = otio.sgttyb;
267 tiop->lflag = otio.lflag;
268 #if defined (TIOCGETC)
269 tiop->tchars = otio.tchars;
271 #if defined (TIOCGLTC)
272 tiop->ltchars = otio.ltchars;
274 tiop->flags = otio.flags;
276 /* First, the basic settings to put us into character-at-a-time, no-echo
278 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
279 tiop->sgttyb.sg_flags |= CBREAK;
281 /* If this terminal doesn't care how the 8th bit is used, then we can
282 use it for the meta-key. If only one of even or odd parity is
283 specified, then the terminal is using parity, and we cannot. */
285 # define ANYP (EVENP | ODDP)
287 if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
288 ((otio.sgttyb.sg_flags & ANYP) == 0))
290 tiop->sgttyb.sg_flags |= ANYP;
292 /* Hack on local mode flags if we can. */
293 #if defined (TIOCLGET)
294 # if defined (LPASS8)
295 tiop->lflag |= LPASS8;
297 #endif /* TIOCLGET */
300 #if defined (TIOCGETC)
301 # if defined (USE_XON_XOFF)
302 /* Get rid of terminal output start and stop characters. */
303 tiop->tchars.t_stopc = -1; /* C-s */
304 tiop->tchars.t_startc = -1; /* C-q */
306 /* If there is an XON character, bind it to restart the output. */
307 if (otio.tchars.t_startc != -1)
308 rl_bind_key (otio.tchars.t_startc, rl_restart_output);
309 # endif /* USE_XON_XOFF */
311 /* If there is an EOF char, bind _rl_eof_char to it. */
312 if (otio.tchars.t_eofc != -1)
313 _rl_eof_char = otio.tchars.t_eofc;
315 # if defined (NO_KILL_INTR)
316 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
317 tiop->tchars.t_quitc = -1; /* C-\ */
318 tiop->tchars.t_intrc = -1; /* C-c */
319 # endif /* NO_KILL_INTR */
320 #endif /* TIOCGETC */
322 #if defined (TIOCGLTC)
323 /* Make the interrupt keys go away. Just enough to make people happy. */
324 tiop->ltchars.t_dsuspc = -1; /* C-y */
325 tiop->ltchars.t_lnextc = -1; /* C-v */
326 #endif /* TIOCGLTC */
327 #endif /* !__GO32__ */
330 #else /* !defined (NEW_TTY_DRIVER) */
340 #if defined (TERMIOS_TTY_DRIVER)
341 # define TIOTYPE struct termios
342 # define DRAIN_OUTPUT(fd) tcdrain (fd)
343 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
345 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
347 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
348 # endif /* !M_UNIX */
350 # define TIOTYPE struct termio
351 # define DRAIN_OUTPUT(fd)
352 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
353 # define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
354 #endif /* !TERMIOS_TTY_DRIVER */
359 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
361 # define OUTPUT_BEING_FLUSHED(tp) 0
368 fprintf (stderr, "readline: warning: %s\n", msg);
376 if ((tp->c_oflag & OPOST) == 0)
378 rltty_warning ("turning on OPOST for terminal\r");
379 tp->c_oflag |= OPOST|ONLCR;
385 get_tty_settings (tty, tiop)
394 ioctl_ret = GETATTR (tty, tiop);
402 if (OUTPUT_BEING_FLUSHED (tiop))
404 #if defined (FLUSHO) && defined (_AIX41)
405 rltty_warning ("turning off output flushing");
406 tiop->c_lflag &= ~FLUSHO;
423 set_tty_settings (tty, tiop)
427 while (SETATTR (tty, tiop) < 0)
436 #if defined (TERMIOS_TTY_DRIVER)
437 # if defined (__ksr1__)
444 tcflow (tty, TCOON); /* Simulate a ^Q. */
447 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
448 #endif /* !TERMIOS_TTY_DRIVER */
456 prepare_terminal_settings (meta_flag, otio, tiop)
460 readline_echoing_p = (otio.c_lflag & ECHO);
462 tiop->c_lflag &= ~(ICANON | ECHO);
464 if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
465 _rl_eof_char = otio.c_cc[VEOF];
467 #if defined (USE_XON_XOFF)
469 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
471 /* `strict' Posix systems do not define IXANY. */
472 tiop->c_iflag &= ~(IXON | IXOFF);
474 #endif /* USE_XON_XOFF */
476 /* Only turn this off if we are using all 8 bits. */
477 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
478 tiop->c_iflag &= ~(ISTRIP | INPCK);
480 /* Make sure we differentiate between CR and NL on input. */
481 tiop->c_iflag &= ~(ICRNL | INLCR);
483 #if !defined (HANDLE_SIGNALS)
484 tiop->c_lflag &= ~ISIG;
486 tiop->c_lflag |= ISIG;
489 tiop->c_cc[VMIN] = 1;
490 tiop->c_cc[VTIME] = 0;
493 if (OUTPUT_BEING_FLUSHED (tiop))
495 tiop->c_lflag &= ~FLUSHO;
496 otio.c_lflag &= ~FLUSHO;
500 /* Turn off characters that we need on Posix systems with job control,
501 just to be sure. This includes ^Y and ^V. This should not really
503 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
506 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
510 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
513 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
515 #endif /* NEW_TTY_DRIVER */
517 /* Put the terminal in CBREAK mode so that we can detect key presses. */
519 rl_prep_terminal (meta_flag)
522 #if !defined (__GO32__)
526 if (terminal_prepped)
529 /* Try to keep this function from being INTerrupted. */
532 tty = fileno (rl_instream);
534 if (get_tty_settings (tty, &tio) < 0)
542 prepare_terminal_settings (meta_flag, otio, &tio);
544 if (set_tty_settings (tty, &tio) < 0)
550 if (_rl_enable_keypad)
551 _rl_control_keypad (1);
553 fflush (rl_outstream);
554 terminal_prepped = 1;
557 #endif /* !__GO32__ */
560 /* Restore the terminal's normal settings and modes. */
562 rl_deprep_terminal ()
564 #if !defined (__GO32__)
567 if (!terminal_prepped)
570 /* Try to keep this function from being interrupted. */
573 tty = fileno (rl_instream);
575 if (_rl_enable_keypad)
576 _rl_control_keypad (0);
578 fflush (rl_outstream);
580 if (set_tty_settings (tty, &otio) < 0)
586 terminal_prepped = 0;
589 #endif /* !__GO32__ */
592 /* **************************************************************** */
594 /* Bogus Flow Control */
596 /* **************************************************************** */
599 rl_restart_output (count, key)
602 int fildes = fileno (rl_outstream);
603 #if defined (TIOCSTART)
605 ioctl (&fildes, TIOCSTART, 0);
607 ioctl (fildes, TIOCSTART, 0);
610 #else /* !TIOCSTART */
611 # if defined (TERMIOS_TTY_DRIVER)
612 # if defined (__ksr1__)
616 tcflow (fildes, TCOON);
619 tcflow (fildes, TCOON); /* Simulate a ^Q. */
621 # else /* !TERMIOS_TTY_DRIVER */
622 # if defined (TCXONC)
623 ioctl (fildes, TCXONC, TCOON);
625 # endif /* !TERMIOS_TTY_DRIVER */
626 #endif /* !TIOCSTART */
632 rl_stop_output (count, key)
635 int fildes = fileno (rl_instream);
637 #if defined (TIOCSTOP)
638 # if defined (apollo)
639 ioctl (&fildes, TIOCSTOP, 0);
641 ioctl (fildes, TIOCSTOP, 0);
643 #else /* !TIOCSTOP */
644 # if defined (TERMIOS_TTY_DRIVER)
645 # if defined (__ksr1__)
648 tcflow (fildes, TCOOFF);
650 # if defined (TCXONC)
651 ioctl (fildes, TCXONC, TCOON);
653 # endif /* !TERMIOS_TTY_DRIVER */
654 #endif /* !TIOCSTOP */
659 /* **************************************************************** */
661 /* Default Key Bindings */
663 /* **************************************************************** */
665 rltty_set_default_bindings (kmap)
669 int tty = fileno (rl_instream);
671 #if defined (NEW_TTY_DRIVER)
673 #define SET_SPECIAL(sc, func) \
678 if (ic != -1 && kmap[ic].type == ISFUNC) \
679 kmap[ic].function = func; \
683 if (get_tty_settings (tty, &ttybuff) == 0)
685 if (ttybuff.flags & SGTTY_SET)
687 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
688 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
691 # if defined (TIOCGLTC)
692 if (ttybuff.flags & LTCHARS_SET)
694 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
695 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
697 # endif /* TIOCGLTC */
700 #else /* !NEW_TTY_DRIVER */
702 #define SET_SPECIAL(sc, func) \
706 uc = ttybuff.c_cc[sc]; \
707 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
708 kmap[uc].function = func; \
712 if (get_tty_settings (tty, &ttybuff) == 0)
714 SET_SPECIAL (VERASE, rl_rubout);
715 SET_SPECIAL (VKILL, rl_unix_line_discard);
717 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
718 SET_SPECIAL (VLNEXT, rl_quoted_insert);
719 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
721 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
722 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
723 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
725 #endif /* !NEW_TTY_DRIVER */