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
)
219 tiop
->flags
= tiop
->lflag
= 0;
221 ioctl (tty
, TIOCGETP
, &(tiop
->sgttyb
));
222 tiop
->flags
|= SGTTY_SET
;
224 #if defined (TIOCLGET)
225 ioctl (tty
, TIOCLGET
, &(tiop
->lflag
));
226 tiop
->flags
|= LFLAG_SET
;
229 #if defined (TIOCGETC)
230 ioctl (tty
, TIOCGETC
, &(tiop
->tchars
));
231 tiop
->flags
|= TCHARS_SET
;
234 #if defined (TIOCGLTC)
235 ioctl (tty
, TIOCGLTC
, &(tiop
->ltchars
));
236 tiop
->flags
|= LTCHARS_SET
;
243 set_tty_settings (tty
, tiop
)
247 if (tiop
->flags
& SGTTY_SET
)
249 ioctl (tty
, TIOCSETN
, &(tiop
->sgttyb
));
250 tiop
->flags
&= ~SGTTY_SET
;
252 readline_echoing_p
= 1;
254 #if defined (TIOCLSET)
255 if (tiop
->flags
& LFLAG_SET
)
257 ioctl (tty
, TIOCLSET
, &(tiop
->lflag
));
258 tiop
->flags
&= ~LFLAG_SET
;
262 #if defined (TIOCSETC)
263 if (tiop
->flags
& TCHARS_SET
)
265 ioctl (tty
, TIOCSETC
, &(tiop
->tchars
));
266 tiop
->flags
&= ~TCHARS_SET
;
270 #if defined (TIOCSLTC)
271 if (tiop
->flags
& LTCHARS_SET
)
273 ioctl (tty
, TIOCSLTC
, &(tiop
->ltchars
));
274 tiop
->flags
&= ~LTCHARS_SET
;
282 prepare_terminal_settings (meta_flag
, otio
, tiop
)
286 readline_echoing_p
= (otio
.sgttyb
.sg_flags
& ECHO
);
288 /* Copy the original settings to the structure we're going to use for
290 tiop
->sgttyb
= otio
.sgttyb
;
291 tiop
->lflag
= otio
.lflag
;
292 #if defined (TIOCGETC)
293 tiop
->tchars
= otio
.tchars
;
295 #if defined (TIOCGLTC)
296 tiop
->ltchars
= otio
.ltchars
;
298 tiop
->flags
= otio
.flags
;
300 /* First, the basic settings to put us into character-at-a-time, no-echo
302 tiop
->sgttyb
.sg_flags
&= ~(ECHO
| CRMOD
);
303 tiop
->sgttyb
.sg_flags
|= CBREAK
;
305 /* If this terminal doesn't care how the 8th bit is used, then we can
306 use it for the meta-key. If only one of even or odd parity is
307 specified, then the terminal is using parity, and we cannot. */
309 # define ANYP (EVENP | ODDP)
311 if (((otio
.sgttyb
.sg_flags
& ANYP
) == ANYP
) ||
312 ((otio
.sgttyb
.sg_flags
& ANYP
) == 0))
314 tiop
->sgttyb
.sg_flags
|= ANYP
;
316 /* Hack on local mode flags if we can. */
317 #if defined (TIOCLGET)
318 # if defined (LPASS8)
319 tiop
->lflag
|= LPASS8
;
321 #endif /* TIOCLGET */
324 #if defined (TIOCGETC)
325 # if defined (USE_XON_XOFF)
326 /* Get rid of terminal output start and stop characters. */
327 tiop
->tchars
.t_stopc
= -1; /* C-s */
328 tiop
->tchars
.t_startc
= -1; /* C-q */
330 /* If there is an XON character, bind it to restart the output. */
331 if (otio
.tchars
.t_startc
!= -1)
332 rl_bind_key (otio
.tchars
.t_startc
, rl_restart_output
);
333 # endif /* USE_XON_XOFF */
335 /* If there is an EOF char, bind _rl_eof_char to it. */
336 if (otio
.tchars
.t_eofc
!= -1)
337 _rl_eof_char
= otio
.tchars
.t_eofc
;
339 # if defined (NO_KILL_INTR)
340 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
341 tiop
->tchars
.t_quitc
= -1; /* C-\ */
342 tiop
->tchars
.t_intrc
= -1; /* C-c */
343 # endif /* NO_KILL_INTR */
344 #endif /* TIOCGETC */
346 #if defined (TIOCGLTC)
347 /* Make the interrupt keys go away. Just enough to make people happy. */
348 tiop
->ltchars
.t_dsuspc
= -1; /* C-y */
349 tiop
->ltchars
.t_lnextc
= -1; /* C-v */
350 #endif /* TIOCGLTC */
353 #else /* !defined (NEW_TTY_DRIVER) */
363 #if defined (TERMIOS_TTY_DRIVER)
364 # define TIOTYPE struct termios
365 # define DRAIN_OUTPUT(fd) tcdrain (fd)
366 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
368 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
370 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
371 # endif /* !M_UNIX */
373 # define TIOTYPE struct termio
374 # define DRAIN_OUTPUT(fd)
375 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
376 # define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
377 #endif /* !TERMIOS_TTY_DRIVER */
382 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
384 # define OUTPUT_BEING_FLUSHED(tp) 0
388 save_tty_chars (tiop
)
391 _rl_last_tty_chars
= _rl_tty_chars
;
393 _rl_tty_chars
.t_eof
= tiop
->c_cc
[VEOF
];
394 _rl_tty_chars
.t_eol
= tiop
->c_cc
[VEOL
];
396 _rl_tty_chars
.t_eol2
= tiop
->c_cc
[VEOL2
];
398 _rl_tty_chars
.t_erase
= tiop
->c_cc
[VERASE
];
400 _rl_tty_chars
.t_werase
= tiop
->c_cc
[VWERASE
];
402 _rl_tty_chars
.t_kill
= tiop
->c_cc
[VKILL
];
404 _rl_tty_chars
.t_reprint
= tiop
->c_cc
[VREPRINT
];
406 _rl_tty_chars
.t_intr
= tiop
->c_cc
[VINTR
];
407 _rl_tty_chars
.t_quit
= tiop
->c_cc
[VQUIT
];
409 _rl_tty_chars
.t_susp
= tiop
->c_cc
[VSUSP
];
412 _rl_tty_chars
.t_dsusp
= tiop
->c_cc
[VDSUSP
];
415 _rl_tty_chars
.t_start
= tiop
->c_cc
[VSTART
];
418 _rl_tty_chars
.t_stop
= tiop
->c_cc
[VSTOP
];
421 _rl_tty_chars
.t_lnext
= tiop
->c_cc
[VLNEXT
];
424 _rl_tty_chars
.t_flush
= tiop
->c_cc
[VDISCARD
];
427 _rl_tty_chars
.t_status
= tiop
->c_cc
[VSTATUS
];
431 #if defined (_AIX) || defined (_AIX41)
432 /* Currently this is only used on AIX */
437 fprintf (stderr
, "readline: warning: %s\n", msg
);
446 if ((tp
->c_oflag
& OPOST
) == 0)
448 rltty_warning ("turning on OPOST for terminal\r");
449 tp
->c_oflag
|= OPOST
|ONLCR
;
455 _get_tty_settings (tty
, tiop
)
463 ioctl_ret
= GETATTR (tty
, tiop
);
471 if (OUTPUT_BEING_FLUSHED (tiop
))
473 #if defined (FLUSHO) && defined (_AIX41)
474 rltty_warning ("turning off output flushing");
475 tiop
->c_lflag
&= ~FLUSHO
;
488 get_tty_settings (tty
, tiop
)
494 if (_get_tty_settings (tty
, tiop
) < 0)
505 _set_tty_settings (tty
, tiop
)
509 while (SETATTR (tty
, tiop
) < 0)
519 set_tty_settings (tty
, tiop
)
523 if (_set_tty_settings (tty
, tiop
) < 0)
528 #if defined (TERMIOS_TTY_DRIVER)
529 # if defined (__ksr1__)
536 tcflow (tty
, TCOON
); /* Simulate a ^Q. */
539 ioctl (tty
, TCXONC
, 1); /* Simulate a ^Q. */
540 #endif /* !TERMIOS_TTY_DRIVER */
548 prepare_terminal_settings (meta_flag
, otio
, tiop
)
552 readline_echoing_p
= (otio
.c_lflag
& ECHO
);
554 tiop
->c_lflag
&= ~(ICANON
| ECHO
);
556 if ((unsigned char) otio
.c_cc
[VEOF
] != (unsigned char) _POSIX_VDISABLE
)
557 _rl_eof_char
= otio
.c_cc
[VEOF
];
559 #if defined (USE_XON_XOFF)
561 tiop
->c_iflag
&= ~(IXON
| IXOFF
| IXANY
);
563 /* `strict' Posix systems do not define IXANY. */
564 tiop
->c_iflag
&= ~(IXON
| IXOFF
);
566 #endif /* USE_XON_XOFF */
568 /* Only turn this off if we are using all 8 bits. */
569 if (((tiop
->c_cflag
& CSIZE
) == CS8
) || meta_flag
)
570 tiop
->c_iflag
&= ~(ISTRIP
| INPCK
);
572 /* Make sure we differentiate between CR and NL on input. */
573 tiop
->c_iflag
&= ~(ICRNL
| INLCR
);
575 #if !defined (HANDLE_SIGNALS)
576 tiop
->c_lflag
&= ~ISIG
;
578 tiop
->c_lflag
|= ISIG
;
581 tiop
->c_cc
[VMIN
] = 1;
582 tiop
->c_cc
[VTIME
] = 0;
585 if (OUTPUT_BEING_FLUSHED (tiop
))
587 tiop
->c_lflag
&= ~FLUSHO
;
588 otio
.c_lflag
&= ~FLUSHO
;
592 /* Turn off characters that we need on Posix systems with job control,
593 just to be sure. This includes ^Y and ^V. This should not really
595 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
598 tiop
->c_cc
[VLNEXT
] = _POSIX_VDISABLE
;
602 tiop
->c_cc
[VDSUSP
] = _POSIX_VDISABLE
;
605 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
607 #endif /* NEW_TTY_DRIVER */
609 /* Put the terminal in CBREAK mode so that we can detect key presses. */
611 rl_prep_terminal (meta_flag
)
617 if (terminal_prepped
)
620 /* Try to keep this function from being INTerrupted. */
623 tty
= fileno (rl_instream
);
625 if (get_tty_settings (tty
, &tio
) < 0)
633 save_tty_chars (&otio
);
635 prepare_terminal_settings (meta_flag
, otio
, &tio
);
637 if (set_tty_settings (tty
, &tio
) < 0)
643 if (_rl_enable_keypad
)
644 _rl_control_keypad (1);
646 fflush (rl_outstream
);
647 terminal_prepped
= 1;
652 /* Restore the terminal's normal settings and modes. */
654 rl_deprep_terminal ()
658 if (!terminal_prepped
)
661 /* Try to keep this function from being interrupted. */
664 tty
= fileno (rl_instream
);
666 if (_rl_enable_keypad
)
667 _rl_control_keypad (0);
669 fflush (rl_outstream
);
671 if (set_tty_settings (tty
, &otio
) < 0)
677 terminal_prepped
= 0;
682 /* **************************************************************** */
684 /* Bogus Flow Control */
686 /* **************************************************************** */
689 rl_restart_output (count
, key
)
692 int fildes
= fileno (rl_outstream
);
693 #if defined (TIOCSTART)
695 ioctl (&fildes
, TIOCSTART
, 0);
697 ioctl (fildes
, TIOCSTART
, 0);
700 #else /* !TIOCSTART */
701 # if defined (TERMIOS_TTY_DRIVER)
702 # if defined (__ksr1__)
706 tcflow (fildes
, TCOON
);
709 tcflow (fildes
, TCOON
); /* Simulate a ^Q. */
711 # else /* !TERMIOS_TTY_DRIVER */
712 # if defined (TCXONC)
713 ioctl (fildes
, TCXONC
, TCOON
);
715 # endif /* !TERMIOS_TTY_DRIVER */
716 #endif /* !TIOCSTART */
722 rl_stop_output (count
, key
)
725 int fildes
= fileno (rl_instream
);
727 #if defined (TIOCSTOP)
728 # if defined (apollo)
729 ioctl (&fildes
, TIOCSTOP
, 0);
731 ioctl (fildes
, TIOCSTOP
, 0);
733 #else /* !TIOCSTOP */
734 # if defined (TERMIOS_TTY_DRIVER)
735 # if defined (__ksr1__)
738 tcflow (fildes
, TCOOFF
);
740 # if defined (TCXONC)
741 ioctl (fildes
, TCXONC
, TCOON
);
743 # endif /* !TERMIOS_TTY_DRIVER */
744 #endif /* !TIOCSTOP */
749 /* **************************************************************** */
751 /* Default Key Bindings */
753 /* **************************************************************** */
755 rltty_set_default_bindings (kmap
)
759 int tty
= fileno (rl_instream
);
761 #if defined (NEW_TTY_DRIVER)
763 #define SET_SPECIAL(sc, func) \
768 if (ic != -1 && kmap[ic].type == ISFUNC) \
769 kmap[ic].function = func; \
773 if (get_tty_settings (tty
, &ttybuff
) == 0)
775 if (ttybuff
.flags
& SGTTY_SET
)
777 SET_SPECIAL (ttybuff
.sgttyb
.sg_erase
, rl_rubout
);
778 SET_SPECIAL (ttybuff
.sgttyb
.sg_kill
, rl_unix_line_discard
);
781 # if defined (TIOCGLTC)
782 if (ttybuff
.flags
& LTCHARS_SET
)
784 SET_SPECIAL (ttybuff
.ltchars
.t_werasc
, rl_unix_word_rubout
);
785 SET_SPECIAL (ttybuff
.ltchars
.t_lnextc
, rl_quoted_insert
);
787 # endif /* TIOCGLTC */
790 #else /* !NEW_TTY_DRIVER */
792 #define SET_SPECIAL(sc, func) \
796 uc = ttybuff.c_cc[sc]; \
797 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
798 kmap[uc].function = func; \
802 if (get_tty_settings (tty
, &ttybuff
) == 0)
804 SET_SPECIAL (VERASE
, rl_rubout
);
805 SET_SPECIAL (VKILL
, rl_unix_line_discard
);
807 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
808 SET_SPECIAL (VLNEXT
, rl_quoted_insert
);
809 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
811 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
812 SET_SPECIAL (VWERASE
, rl_unix_word_rubout
);
813 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
815 #endif /* !NEW_TTY_DRIVER */
818 #if defined (HANDLE_SIGNALS)
820 #if defined (NEW_TTY_DRIVER)
822 _rl_disable_tty_signals ()
828 _rl_restore_tty_signals ()
834 static TIOTYPE sigstty
, nosigstty
;
835 static int tty_sigs_disabled
= 0;
838 _rl_disable_tty_signals ()
840 if (tty_sigs_disabled
)
843 if (_get_tty_settings (fileno (rl_instream
), &sigstty
) < 0)
848 nosigstty
.c_lflag
&= ~ISIG
;
850 if (_set_tty_settings (fileno (rl_instream
), &nosigstty
) < 0)
851 return (_set_tty_settings (fileno (rl_instream
), &sigstty
));
853 tty_sigs_disabled
= 1;
858 _rl_restore_tty_signals ()
860 if (tty_sigs_disabled
== 0)
863 return (_set_tty_settings (fileno (rl_instream
), &sigstty
));
865 #endif /* !NEW_TTY_DRIVER */
867 #endif /* HANDLE_SIGNALS */