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 # undef HANDLE_SIGNALS
63 /* Indirect functions to allow apps control over terminal management. */
64 extern void rl_prep_terminal (), rl_deprep_terminal ();
66 VFunction *rl_prep_term_function = rl_prep_terminal;
67 VFunction *rl_deprep_term_function = rl_deprep_terminal;
69 /* **************************************************************** */
71 /* Signal Management */
73 /* **************************************************************** */
75 #if defined (HAVE_POSIX_SIGNALS)
76 static sigset_t sigint_set, sigint_oset;
77 #else /* !HAVE_POSIX_SIGNALS */
78 # if defined (HAVE_BSD_SIGNALS)
79 static int sigint_oldmask;
80 # endif /* HAVE_BSD_SIGNALS */
81 #endif /* !HAVE_POSIX_SIGNALS */
83 static int sigint_blocked;
85 /* Cause SIGINT to not be delivered until the corresponding call to
93 #if defined (HAVE_POSIX_SIGNALS)
94 sigemptyset (&sigint_set);
95 sigemptyset (&sigint_oset);
96 sigaddset (&sigint_set, SIGINT);
97 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
98 #else /* !HAVE_POSIX_SIGNALS */
99 # if defined (HAVE_BSD_SIGNALS)
100 sigint_oldmask = sigblock (sigmask (SIGINT));
101 # else /* !HAVE_BSD_SIGNALS */
102 # if defined (HAVE_USG_SIGHOLD)
104 # endif /* HAVE_USG_SIGHOLD */
105 # endif /* !HAVE_BSD_SIGNALS */
106 #endif /* !HAVE_POSIX_SIGNALS */
110 /* Allow SIGINT to be delivered. */
117 #if defined (HAVE_POSIX_SIGNALS)
118 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
120 # if defined (HAVE_BSD_SIGNALS)
121 sigsetmask (sigint_oldmask);
122 # else /* !HAVE_BSD_SIGNALS */
123 # if defined (HAVE_USG_SIGHOLD)
125 # endif /* HAVE_USG_SIGHOLD */
126 # endif /* !HAVE_BSD_SIGNALS */
127 #endif /* !HAVE_POSIX_SIGNALS */
132 /* **************************************************************** */
134 /* Saving and Restoring the TTY */
136 /* **************************************************************** */
138 /* Non-zero means that the terminal is in a prepped state. */
139 static int terminal_prepped;
141 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
142 and output is suspended. */
143 #if defined (__ksr1__)
147 #if defined (TIOCGWINSZ)
148 /* Dummy call to force a backgrounded readline to stop before it tries
149 to get the tty settings. */
156 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
157 (void) ioctl (tty, TIOCSWINSZ, &w);
159 #endif /* 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)
395 ioctl_ret = GETATTR (tty, tiop);
403 if (OUTPUT_BEING_FLUSHED (tiop))
405 #if defined (FLUSHO) && defined (_AIX41)
406 rltty_warning ("turning off output flushing");
407 tiop->c_lflag &= ~FLUSHO;
424 set_tty_settings (tty, tiop)
428 while (SETATTR (tty, tiop) < 0)
437 #if defined (TERMIOS_TTY_DRIVER)
438 # if defined (__ksr1__)
445 tcflow (tty, TCOON); /* Simulate a ^Q. */
448 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
449 #endif /* !TERMIOS_TTY_DRIVER */
457 prepare_terminal_settings (meta_flag, otio, tiop)
461 readline_echoing_p = (otio.c_lflag & ECHO);
463 tiop->c_lflag &= ~(ICANON | ECHO);
465 if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
466 _rl_eof_char = otio.c_cc[VEOF];
468 #if defined (USE_XON_XOFF)
470 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
472 /* `strict' Posix systems do not define IXANY. */
473 tiop->c_iflag &= ~(IXON | IXOFF);
475 #endif /* USE_XON_XOFF */
477 /* Only turn this off if we are using all 8 bits. */
478 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
479 tiop->c_iflag &= ~(ISTRIP | INPCK);
481 /* Make sure we differentiate between CR and NL on input. */
482 tiop->c_iflag &= ~(ICRNL | INLCR);
484 #if !defined (HANDLE_SIGNALS)
485 tiop->c_lflag &= ~ISIG;
487 tiop->c_lflag |= ISIG;
490 tiop->c_cc[VMIN] = 1;
491 tiop->c_cc[VTIME] = 0;
494 if (OUTPUT_BEING_FLUSHED (tiop))
496 tiop->c_lflag &= ~FLUSHO;
497 otio.c_lflag &= ~FLUSHO;
501 /* Turn off characters that we need on Posix systems with job control,
502 just to be sure. This includes ^Y and ^V. This should not really
504 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
507 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
511 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
514 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
516 #endif /* NEW_TTY_DRIVER */
518 /* Put the terminal in CBREAK mode so that we can detect key presses. */
520 rl_prep_terminal (meta_flag)
523 #if !defined (__GO32__)
527 if (terminal_prepped)
530 /* Try to keep this function from being INTerrupted. */
533 tty = fileno (rl_instream);
535 if (get_tty_settings (tty, &tio) < 0)
543 prepare_terminal_settings (meta_flag, otio, &tio);
545 if (set_tty_settings (tty, &tio) < 0)
551 if (_rl_enable_keypad)
552 _rl_control_keypad (1);
554 fflush (rl_outstream);
555 terminal_prepped = 1;
558 #endif /* !__GO32__ */
561 /* Restore the terminal's normal settings and modes. */
563 rl_deprep_terminal ()
565 #if !defined (__GO32__)
568 if (!terminal_prepped)
571 /* Try to keep this function from being interrupted. */
574 tty = fileno (rl_instream);
576 if (_rl_enable_keypad)
577 _rl_control_keypad (0);
579 fflush (rl_outstream);
581 if (set_tty_settings (tty, &otio) < 0)
587 terminal_prepped = 0;
590 #endif /* !__GO32__ */
593 /* **************************************************************** */
595 /* Bogus Flow Control */
597 /* **************************************************************** */
600 rl_restart_output (count, key)
603 int fildes = fileno (rl_outstream);
604 #if defined (TIOCSTART)
606 ioctl (&fildes, TIOCSTART, 0);
608 ioctl (fildes, TIOCSTART, 0);
611 #else /* !TIOCSTART */
612 # if defined (TERMIOS_TTY_DRIVER)
613 # if defined (__ksr1__)
617 tcflow (fildes, TCOON);
620 tcflow (fildes, TCOON); /* Simulate a ^Q. */
622 # else /* !TERMIOS_TTY_DRIVER */
623 # if defined (TCXONC)
624 ioctl (fildes, TCXONC, TCOON);
626 # endif /* !TERMIOS_TTY_DRIVER */
627 #endif /* !TIOCSTART */
633 rl_stop_output (count, key)
636 int fildes = fileno (rl_instream);
638 #if defined (TIOCSTOP)
639 # if defined (apollo)
640 ioctl (&fildes, TIOCSTOP, 0);
642 ioctl (fildes, TIOCSTOP, 0);
644 #else /* !TIOCSTOP */
645 # if defined (TERMIOS_TTY_DRIVER)
646 # if defined (__ksr1__)
649 tcflow (fildes, TCOOFF);
651 # if defined (TCXONC)
652 ioctl (fildes, TCXONC, TCOON);
654 # endif /* !TERMIOS_TTY_DRIVER */
655 #endif /* !TIOCSTOP */
660 /* **************************************************************** */
662 /* Default Key Bindings */
664 /* **************************************************************** */
666 rltty_set_default_bindings (kmap)
670 int tty = fileno (rl_instream);
672 #if defined (NEW_TTY_DRIVER)
674 #define SET_SPECIAL(sc, func) \
679 if (ic != -1 && kmap[ic].type == ISFUNC) \
680 kmap[ic].function = func; \
684 if (get_tty_settings (tty, &ttybuff) == 0)
686 if (ttybuff.flags & SGTTY_SET)
688 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
689 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
692 # if defined (TIOCGLTC)
693 if (ttybuff.flags & LTCHARS_SET)
695 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
696 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
698 # endif /* TIOCGLTC */
701 #else /* !NEW_TTY_DRIVER */
703 #define SET_SPECIAL(sc, func) \
707 uc = ttybuff.c_cc[sc]; \
708 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
709 kmap[uc].function = func; \
713 if (get_tty_settings (tty, &ttybuff) == 0)
715 SET_SPECIAL (VERASE, rl_rubout);
716 SET_SPECIAL (VKILL, rl_unix_line_discard);
718 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
719 SET_SPECIAL (VLNEXT, rl_quoted_insert);
720 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
722 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
723 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
724 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
726 #endif /* !NEW_TTY_DRIVER */