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 (GWINSZ_IN_SYS_IOCTL)
41 # include <sys/ioctl.h>
42 #endif /* 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 extern void _rl_control_keypad ();
58 #if defined (__GO32__)
60 # if !defined (__DJGPP__)
61 # undef HANDLE_SIGNALS
62 # endif /* !__DJGPP__ */
65 /* Indirect functions to allow apps control over terminal management. */
66 extern void rl_prep_terminal (), rl_deprep_terminal ();
68 VFunction *rl_prep_term_function = rl_prep_terminal;
69 VFunction *rl_deprep_term_function = rl_deprep_terminal;
71 /* **************************************************************** */
73 /* Signal Management */
75 /* **************************************************************** */
77 #if defined (HAVE_POSIX_SIGNALS)
78 static sigset_t sigint_set, sigint_oset;
79 #else /* !HAVE_POSIX_SIGNALS */
80 # if defined (HAVE_BSD_SIGNALS)
81 static int sigint_oldmask;
82 # endif /* HAVE_BSD_SIGNALS */
83 #endif /* !HAVE_POSIX_SIGNALS */
85 static int sigint_blocked;
87 /* Cause SIGINT to not be delivered until the corresponding call to
95 #if defined (HAVE_POSIX_SIGNALS)
96 sigemptyset (&sigint_set);
97 sigemptyset (&sigint_oset);
98 sigaddset (&sigint_set, SIGINT);
99 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
100 #else /* !HAVE_POSIX_SIGNALS */
101 # if defined (HAVE_BSD_SIGNALS)
102 sigint_oldmask = sigblock (sigmask (SIGINT));
103 # else /* !HAVE_BSD_SIGNALS */
104 # if defined (HAVE_USG_SIGHOLD)
106 # endif /* HAVE_USG_SIGHOLD */
107 # endif /* !HAVE_BSD_SIGNALS */
108 #endif /* !HAVE_POSIX_SIGNALS */
112 /* Allow SIGINT to be delivered. */
119 #if defined (HAVE_POSIX_SIGNALS)
120 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
122 # if defined (HAVE_BSD_SIGNALS)
123 sigsetmask (sigint_oldmask);
124 # else /* !HAVE_BSD_SIGNALS */
125 # if defined (HAVE_USG_SIGHOLD)
127 # endif /* HAVE_USG_SIGHOLD */
128 # endif /* !HAVE_BSD_SIGNALS */
129 #endif /* !HAVE_POSIX_SIGNALS */
134 /* **************************************************************** */
136 /* Saving and Restoring the TTY */
138 /* **************************************************************** */
140 /* Non-zero means that the terminal is in a prepped state. */
141 static int terminal_prepped;
143 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
144 and output is suspended. */
145 #if defined (__ksr1__)
149 #if defined (TIOCGWINSZ)
150 /* Dummy call to force a backgrounded readline to stop before it tries
151 to get the tty settings. */
158 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
159 (void) ioctl (tty, TIOCSWINSZ, &w);
161 #endif /* TIOCGWINSZ */
163 #if defined (NEW_TTY_DRIVER)
165 /* Values for the `flags' field of a struct bsdtty. This tells which
166 elements of the struct bsdtty have been fetched from the system and
168 #define SGTTY_SET 0x01
169 #define LFLAG_SET 0x02
170 #define TCHARS_SET 0x04
171 #define LTCHARS_SET 0x08
174 struct sgttyb sgttyb; /* Basic BSD tty driver information. */
175 int lflag; /* Local mode flags, like LPASS8. */
176 #if defined (TIOCGETC)
177 struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
179 #if defined (TIOCGLTC)
180 struct ltchars ltchars; /* 4.2 BSD editing characters */
182 int flags; /* Bitmap saying which parts of the struct are valid. */
185 #define TIOTYPE struct bsdtty
190 get_tty_settings (tty, tiop)
194 #if defined (TIOCGWINSZ)
198 tiop->flags = tiop->lflag = 0;
200 ioctl (tty, TIOCGETP, &(tiop->sgttyb));
201 tiop->flags |= SGTTY_SET;
203 #if defined (TIOCLGET)
204 ioctl (tty, TIOCLGET, &(tiop->lflag));
205 tiop->flags |= LFLAG_SET;
208 #if defined (TIOCGETC)
209 ioctl (tty, TIOCGETC, &(tiop->tchars));
210 tiop->flags |= TCHARS_SET;
213 #if defined (TIOCGLTC)
214 ioctl (tty, TIOCGLTC, &(tiop->ltchars));
215 tiop->flags |= LTCHARS_SET;
222 set_tty_settings (tty, tiop)
226 if (tiop->flags & SGTTY_SET)
228 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
229 tiop->flags &= ~SGTTY_SET;
231 readline_echoing_p = 1;
233 #if defined (TIOCLSET)
234 if (tiop->flags & LFLAG_SET)
236 ioctl (tty, TIOCLSET, &(tiop->lflag));
237 tiop->flags &= ~LFLAG_SET;
241 #if defined (TIOCSETC)
242 if (tiop->flags & TCHARS_SET)
244 ioctl (tty, TIOCSETC, &(tiop->tchars));
245 tiop->flags &= ~TCHARS_SET;
249 #if defined (TIOCSLTC)
250 if (tiop->flags & LTCHARS_SET)
252 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
253 tiop->flags &= ~LTCHARS_SET;
261 prepare_terminal_settings (meta_flag, otio, tiop)
265 #if !defined (__GO32__) || defined (HAVE_TERMIOS_H)
266 readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
268 /* Copy the original settings to the structure we're going to use for
270 tiop->sgttyb = otio.sgttyb;
271 tiop->lflag = otio.lflag;
272 #if defined (TIOCGETC)
273 tiop->tchars = otio.tchars;
275 #if defined (TIOCGLTC)
276 tiop->ltchars = otio.ltchars;
278 tiop->flags = otio.flags;
280 /* First, the basic settings to put us into character-at-a-time, no-echo
282 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
283 tiop->sgttyb.sg_flags |= CBREAK;
285 /* If this terminal doesn't care how the 8th bit is used, then we can
286 use it for the meta-key. If only one of even or odd parity is
287 specified, then the terminal is using parity, and we cannot. */
289 # define ANYP (EVENP | ODDP)
291 if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
292 ((otio.sgttyb.sg_flags & ANYP) == 0))
294 tiop->sgttyb.sg_flags |= ANYP;
296 /* Hack on local mode flags if we can. */
297 #if defined (TIOCLGET)
298 # if defined (LPASS8)
299 tiop->lflag |= LPASS8;
301 #endif /* TIOCLGET */
304 #if defined (TIOCGETC)
305 # if defined (USE_XON_XOFF)
306 /* Get rid of terminal output start and stop characters. */
307 tiop->tchars.t_stopc = -1; /* C-s */
308 tiop->tchars.t_startc = -1; /* C-q */
310 /* If there is an XON character, bind it to restart the output. */
311 if (otio.tchars.t_startc != -1)
312 rl_bind_key (otio.tchars.t_startc, rl_restart_output);
313 # endif /* USE_XON_XOFF */
315 /* If there is an EOF char, bind _rl_eof_char to it. */
316 if (otio.tchars.t_eofc != -1)
317 _rl_eof_char = otio.tchars.t_eofc;
319 # if defined (NO_KILL_INTR)
320 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
321 tiop->tchars.t_quitc = -1; /* C-\ */
322 tiop->tchars.t_intrc = -1; /* C-c */
323 # endif /* NO_KILL_INTR */
324 #endif /* TIOCGETC */
326 #if defined (TIOCGLTC)
327 /* Make the interrupt keys go away. Just enough to make people happy. */
328 tiop->ltchars.t_dsuspc = -1; /* C-y */
329 tiop->ltchars.t_lnextc = -1; /* C-v */
330 #endif /* TIOCGLTC */
331 #endif /* !__GO32__ || HAVE_TERMIOS_H */
334 #else /* !defined (NEW_TTY_DRIVER) */
344 #if defined (TERMIOS_TTY_DRIVER)
345 # define TIOTYPE struct termios
346 # define DRAIN_OUTPUT(fd) tcdrain (fd)
347 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
349 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
351 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
352 # endif /* !M_UNIX */
354 # define TIOTYPE struct termio
355 # define DRAIN_OUTPUT(fd)
356 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
357 # define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
358 #endif /* !TERMIOS_TTY_DRIVER */
363 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
365 # define OUTPUT_BEING_FLUSHED(tp) 0
372 fprintf (stderr, "readline: warning: %s\n", msg);
380 if ((tp->c_oflag & OPOST) == 0)
382 rltty_warning ("turning on OPOST for terminal\r");
383 tp->c_oflag |= OPOST|ONLCR;
389 get_tty_settings (tty, tiop)
395 #if defined (TIOCGWINSZ)
401 ioctl_ret = GETATTR (tty, tiop);
409 if (OUTPUT_BEING_FLUSHED (tiop))
411 #if defined (FLUSHO) && defined (_AIX41)
412 rltty_warning ("turning off output flushing");
413 tiop->c_lflag &= ~FLUSHO;
430 set_tty_settings (tty, tiop)
434 while (SETATTR (tty, tiop) < 0)
443 #if defined (TERMIOS_TTY_DRIVER)
444 # if defined (__ksr1__)
451 tcflow (tty, TCOON); /* Simulate a ^Q. */
454 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
455 #endif /* !TERMIOS_TTY_DRIVER */
463 prepare_terminal_settings (meta_flag, otio, tiop)
467 readline_echoing_p = (otio.c_lflag & ECHO);
469 tiop->c_lflag &= ~(ICANON | ECHO);
471 if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
472 _rl_eof_char = otio.c_cc[VEOF];
474 #if defined (USE_XON_XOFF)
476 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
478 /* `strict' Posix systems do not define IXANY. */
479 tiop->c_iflag &= ~(IXON | IXOFF);
481 #endif /* USE_XON_XOFF */
483 /* Only turn this off if we are using all 8 bits. */
484 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
485 tiop->c_iflag &= ~(ISTRIP | INPCK);
487 /* Make sure we differentiate between CR and NL on input. */
488 tiop->c_iflag &= ~(ICRNL | INLCR);
490 #if !defined (HANDLE_SIGNALS)
491 tiop->c_lflag &= ~ISIG;
493 tiop->c_lflag |= ISIG;
496 tiop->c_cc[VMIN] = 1;
497 tiop->c_cc[VTIME] = 0;
500 if (OUTPUT_BEING_FLUSHED (tiop))
502 tiop->c_lflag &= ~FLUSHO;
503 otio.c_lflag &= ~FLUSHO;
507 /* Turn off characters that we need on Posix systems with job control,
508 just to be sure. This includes ^Y and ^V. This should not really
510 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
513 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
517 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
520 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
522 #endif /* NEW_TTY_DRIVER */
524 /* Put the terminal in CBREAK mode so that we can detect key presses. */
526 rl_prep_terminal (meta_flag)
529 #if !defined (__GO32__) || defined (HAVE_TERMIOS_H)
533 if (terminal_prepped)
536 /* Try to keep this function from being INTerrupted. */
539 tty = fileno (rl_instream);
541 if (get_tty_settings (tty, &tio) < 0)
549 prepare_terminal_settings (meta_flag, otio, &tio);
551 if (set_tty_settings (tty, &tio) < 0)
557 if (_rl_enable_keypad)
558 _rl_control_keypad (1);
560 fflush (rl_outstream);
561 terminal_prepped = 1;
564 #endif /* !__GO32__ || HAVE_TERMIOS_H */
567 /* Restore the terminal's normal settings and modes. */
569 rl_deprep_terminal ()
571 #if !defined (__GO32__) || defined (HAVE_TERMIOS_H)
574 if (!terminal_prepped)
577 /* Try to keep this function from being interrupted. */
580 tty = fileno (rl_instream);
582 if (_rl_enable_keypad)
583 _rl_control_keypad (0);
585 fflush (rl_outstream);
587 if (set_tty_settings (tty, &otio) < 0)
593 terminal_prepped = 0;
596 #endif /* !__GO32__ || HAVE_TERMIOS_H */
599 /* **************************************************************** */
601 /* Bogus Flow Control */
603 /* **************************************************************** */
606 rl_restart_output (count, key)
609 int fildes = fileno (rl_outstream);
610 #if defined (TIOCSTART)
612 ioctl (&fildes, TIOCSTART, 0);
614 ioctl (fildes, TIOCSTART, 0);
617 #else /* !TIOCSTART */
618 # if defined (TERMIOS_TTY_DRIVER)
619 # if defined (__ksr1__)
623 tcflow (fildes, TCOON);
626 tcflow (fildes, TCOON); /* Simulate a ^Q. */
628 # else /* !TERMIOS_TTY_DRIVER */
629 # if defined (TCXONC)
630 ioctl (fildes, TCXONC, TCOON);
632 # endif /* !TERMIOS_TTY_DRIVER */
633 #endif /* !TIOCSTART */
639 rl_stop_output (count, key)
642 int fildes = fileno (rl_instream);
644 #if defined (TIOCSTOP)
645 # if defined (apollo)
646 ioctl (&fildes, TIOCSTOP, 0);
648 ioctl (fildes, TIOCSTOP, 0);
650 #else /* !TIOCSTOP */
651 # if defined (TERMIOS_TTY_DRIVER)
652 # if defined (__ksr1__)
655 tcflow (fildes, TCOOFF);
657 # if defined (TCXONC)
658 ioctl (fildes, TCXONC, TCOON);
660 # endif /* !TERMIOS_TTY_DRIVER */
661 #endif /* !TIOCSTOP */
666 /* **************************************************************** */
668 /* Default Key Bindings */
670 /* **************************************************************** */
672 rltty_set_default_bindings (kmap)
676 int tty = fileno (rl_instream);
678 #if defined (NEW_TTY_DRIVER)
680 #define SET_SPECIAL(sc, func) \
685 if (ic != -1 && kmap[ic].type == ISFUNC) \
686 kmap[ic].function = func; \
690 if (get_tty_settings (tty, &ttybuff) == 0)
692 if (ttybuff.flags & SGTTY_SET)
694 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
695 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
698 # if defined (TIOCGLTC)
699 if (ttybuff.flags & LTCHARS_SET)
701 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
702 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
704 # endif /* TIOCGLTC */
707 #else /* !NEW_TTY_DRIVER */
709 #define SET_SPECIAL(sc, func) \
713 uc = ttybuff.c_cc[sc]; \
714 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
715 kmap[uc].function = func; \
719 if (get_tty_settings (tty, &ttybuff) == 0)
721 SET_SPECIAL (VERASE, rl_rubout);
722 SET_SPECIAL (VKILL, rl_unix_line_discard);
724 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
725 SET_SPECIAL (VLNEXT, rl_quoted_insert);
726 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
728 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
729 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
730 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
732 #endif /* !NEW_TTY_DRIVER */