8312963abcbf85d00d2b8166679b9e464a543dd7
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 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 (SHELL) && 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 #else /* SHELL || !TIOCGWINSZ */
160 # define set_winsize(tty)
161 #endif /* SHELL || !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
)
196 tiop
->flags
= tiop
->lflag
= 0;
198 ioctl (tty
, TIOCGETP
, &(tiop
->sgttyb
));
199 tiop
->flags
|= SGTTY_SET
;
201 #if defined (TIOCLGET)
202 ioctl (tty
, TIOCLGET
, &(tiop
->lflag
));
203 tiop
->flags
|= LFLAG_SET
;
206 #if defined (TIOCGETC)
207 ioctl (tty
, TIOCGETC
, &(tiop
->tchars
));
208 tiop
->flags
|= TCHARS_SET
;
211 #if defined (TIOCGLTC)
212 ioctl (tty
, TIOCGLTC
, &(tiop
->ltchars
));
213 tiop
->flags
|= LTCHARS_SET
;
220 set_tty_settings (tty
, tiop
)
224 if (tiop
->flags
& SGTTY_SET
)
226 ioctl (tty
, TIOCSETN
, &(tiop
->sgttyb
));
227 tiop
->flags
&= ~SGTTY_SET
;
229 readline_echoing_p
= 1;
231 #if defined (TIOCLSET)
232 if (tiop
->flags
& LFLAG_SET
)
234 ioctl (tty
, TIOCLSET
, &(tiop
->lflag
));
235 tiop
->flags
&= ~LFLAG_SET
;
239 #if defined (TIOCSETC)
240 if (tiop
->flags
& TCHARS_SET
)
242 ioctl (tty
, TIOCSETC
, &(tiop
->tchars
));
243 tiop
->flags
&= ~TCHARS_SET
;
247 #if defined (TIOCSLTC)
248 if (tiop
->flags
& LTCHARS_SET
)
250 ioctl (tty
, TIOCSLTC
, &(tiop
->ltchars
));
251 tiop
->flags
&= ~LTCHARS_SET
;
259 prepare_terminal_settings (meta_flag
, otio
, tiop
)
263 #if !defined (__GO32__)
264 readline_echoing_p
= (otio
.sgttyb
.sg_flags
& ECHO
);
266 /* Copy the original settings to the structure we're going to use for
268 tiop
->sgttyb
= otio
.sgttyb
;
269 tiop
->lflag
= otio
.lflag
;
270 #if defined (TIOCGETC)
271 tiop
->tchars
= otio
.tchars
;
273 #if defined (TIOCGLTC)
274 tiop
->ltchars
= otio
.ltchars
;
276 tiop
->flags
= otio
.flags
;
278 /* First, the basic settings to put us into character-at-a-time, no-echo
280 tiop
->sgttyb
.sg_flags
&= ~(ECHO
| CRMOD
);
281 tiop
->sgttyb
.sg_flags
|= CBREAK
;
283 /* If this terminal doesn't care how the 8th bit is used, then we can
284 use it for the meta-key. If only one of even or odd parity is
285 specified, then the terminal is using parity, and we cannot. */
287 # define ANYP (EVENP | ODDP)
289 if (((otio
.sgttyb
.sg_flags
& ANYP
) == ANYP
) ||
290 ((otio
.sgttyb
.sg_flags
& ANYP
) == 0))
292 tiop
->sgttyb
.sg_flags
|= ANYP
;
294 /* Hack on local mode flags if we can. */
295 #if defined (TIOCLGET)
296 # if defined (LPASS8)
297 tiop
->lflag
|= LPASS8
;
299 #endif /* TIOCLGET */
302 #if defined (TIOCGETC)
303 # if defined (USE_XON_XOFF)
304 /* Get rid of terminal output start and stop characters. */
305 tiop
->tchars
.t_stopc
= -1; /* C-s */
306 tiop
->tchars
.t_startc
= -1; /* C-q */
308 /* If there is an XON character, bind it to restart the output. */
309 if (otio
.tchars
.t_startc
!= -1)
310 rl_bind_key (otio
.tchars
.t_startc
, rl_restart_output
);
311 # endif /* USE_XON_XOFF */
313 /* If there is an EOF char, bind _rl_eof_char to it. */
314 if (otio
.tchars
.t_eofc
!= -1)
315 _rl_eof_char
= otio
.tchars
.t_eofc
;
317 # if defined (NO_KILL_INTR)
318 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
319 tiop
->tchars
.t_quitc
= -1; /* C-\ */
320 tiop
->tchars
.t_intrc
= -1; /* C-c */
321 # endif /* NO_KILL_INTR */
322 #endif /* TIOCGETC */
324 #if defined (TIOCGLTC)
325 /* Make the interrupt keys go away. Just enough to make people happy. */
326 tiop
->ltchars
.t_dsuspc
= -1; /* C-y */
327 tiop
->ltchars
.t_lnextc
= -1; /* C-v */
328 #endif /* TIOCGLTC */
329 #endif /* !__GO32__ */
332 #else /* !defined (NEW_TTY_DRIVER) */
342 #if defined (TERMIOS_TTY_DRIVER)
343 # define TIOTYPE struct termios
344 # define DRAIN_OUTPUT(fd) tcdrain (fd)
345 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
347 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
349 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
350 # endif /* !M_UNIX */
352 # define TIOTYPE struct termio
353 # define DRAIN_OUTPUT(fd)
354 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
355 # define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
356 #endif /* !TERMIOS_TTY_DRIVER */
361 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
363 # define OUTPUT_BEING_FLUSHED(tp) 0
370 fprintf (stderr
, "readline: warning: %s\n", msg
);
378 if ((tp
->c_oflag
& OPOST
) == 0)
380 rltty_warning ("turning on OPOST for terminal\r");
381 tp
->c_oflag
|= OPOST
|ONLCR
;
387 get_tty_settings (tty
, tiop
)
396 ioctl_ret
= GETATTR (tty
, tiop
);
404 if (OUTPUT_BEING_FLUSHED (tiop
))
406 #if defined (FLUSHO) && defined (_AIX41)
407 rltty_warning ("turning off output flushing");
408 tiop
->c_lflag
&= ~FLUSHO
;
425 set_tty_settings (tty
, tiop
)
429 while (SETATTR (tty
, tiop
) < 0)
438 #if defined (TERMIOS_TTY_DRIVER)
439 # if defined (__ksr1__)
446 tcflow (tty
, TCOON
); /* Simulate a ^Q. */
449 ioctl (tty
, TCXONC
, 1); /* Simulate a ^Q. */
450 #endif /* !TERMIOS_TTY_DRIVER */
458 prepare_terminal_settings (meta_flag
, otio
, tiop
)
462 readline_echoing_p
= (otio
.c_lflag
& ECHO
);
464 tiop
->c_lflag
&= ~(ICANON
| ECHO
);
466 if ((unsigned char) otio
.c_cc
[VEOF
] != (unsigned char) _POSIX_VDISABLE
)
467 _rl_eof_char
= otio
.c_cc
[VEOF
];
469 #if defined (USE_XON_XOFF)
471 tiop
->c_iflag
&= ~(IXON
| IXOFF
| IXANY
);
473 /* `strict' Posix systems do not define IXANY. */
474 tiop
->c_iflag
&= ~(IXON
| IXOFF
);
476 #endif /* USE_XON_XOFF */
478 /* Only turn this off if we are using all 8 bits. */
479 if (((tiop
->c_cflag
& CSIZE
) == CS8
) || meta_flag
)
480 tiop
->c_iflag
&= ~(ISTRIP
| INPCK
);
482 /* Make sure we differentiate between CR and NL on input. */
483 tiop
->c_iflag
&= ~(ICRNL
| INLCR
);
485 #if !defined (HANDLE_SIGNALS)
486 tiop
->c_lflag
&= ~ISIG
;
488 tiop
->c_lflag
|= ISIG
;
491 tiop
->c_cc
[VMIN
] = 1;
492 tiop
->c_cc
[VTIME
] = 0;
495 if (OUTPUT_BEING_FLUSHED (tiop
))
497 tiop
->c_lflag
&= ~FLUSHO
;
498 otio
.c_lflag
&= ~FLUSHO
;
502 /* Turn off characters that we need on Posix systems with job control,
503 just to be sure. This includes ^Y and ^V. This should not really
505 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
508 tiop
->c_cc
[VLNEXT
] = _POSIX_VDISABLE
;
512 tiop
->c_cc
[VDSUSP
] = _POSIX_VDISABLE
;
515 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
517 #endif /* NEW_TTY_DRIVER */
519 /* Put the terminal in CBREAK mode so that we can detect key presses. */
521 rl_prep_terminal (meta_flag
)
524 #if !defined (__GO32__)
528 if (terminal_prepped
)
531 /* Try to keep this function from being INTerrupted. */
534 tty
= fileno (rl_instream
);
536 if (get_tty_settings (tty
, &tio
) < 0)
544 prepare_terminal_settings (meta_flag
, otio
, &tio
);
546 if (set_tty_settings (tty
, &tio
) < 0)
552 if (_rl_enable_keypad
)
553 _rl_control_keypad (1);
555 fflush (rl_outstream
);
556 terminal_prepped
= 1;
559 #endif /* !__GO32__ */
562 /* Restore the terminal's normal settings and modes. */
564 rl_deprep_terminal ()
566 #if !defined (__GO32__)
569 if (!terminal_prepped
)
572 /* Try to keep this function from being interrupted. */
575 tty
= fileno (rl_instream
);
577 if (_rl_enable_keypad
)
578 _rl_control_keypad (0);
580 fflush (rl_outstream
);
582 if (set_tty_settings (tty
, &otio
) < 0)
588 terminal_prepped
= 0;
591 #endif /* !__GO32__ */
594 /* **************************************************************** */
596 /* Bogus Flow Control */
598 /* **************************************************************** */
601 rl_restart_output (count
, key
)
604 int fildes
= fileno (rl_outstream
);
605 #if defined (TIOCSTART)
607 ioctl (&fildes
, TIOCSTART
, 0);
609 ioctl (fildes
, TIOCSTART
, 0);
612 #else /* !TIOCSTART */
613 # if defined (TERMIOS_TTY_DRIVER)
614 # if defined (__ksr1__)
618 tcflow (fildes
, TCOON
);
621 tcflow (fildes
, TCOON
); /* Simulate a ^Q. */
623 # else /* !TERMIOS_TTY_DRIVER */
624 # if defined (TCXONC)
625 ioctl (fildes
, TCXONC
, TCOON
);
627 # endif /* !TERMIOS_TTY_DRIVER */
628 #endif /* !TIOCSTART */
634 rl_stop_output (count
, key
)
637 int fildes
= fileno (rl_instream
);
639 #if defined (TIOCSTOP)
640 # if defined (apollo)
641 ioctl (&fildes
, TIOCSTOP
, 0);
643 ioctl (fildes
, TIOCSTOP
, 0);
645 #else /* !TIOCSTOP */
646 # if defined (TERMIOS_TTY_DRIVER)
647 # if defined (__ksr1__)
650 tcflow (fildes
, TCOOFF
);
652 # if defined (TCXONC)
653 ioctl (fildes
, TCXONC
, TCOON
);
655 # endif /* !TERMIOS_TTY_DRIVER */
656 #endif /* !TIOCSTOP */
661 /* **************************************************************** */
663 /* Default Key Bindings */
665 /* **************************************************************** */
667 rltty_set_default_bindings (kmap
)
671 int tty
= fileno (rl_instream
);
673 #if defined (NEW_TTY_DRIVER)
675 #define SET_SPECIAL(sc, func) \
680 if (ic != -1 && kmap[ic].type == ISFUNC) \
681 kmap[ic].function = func; \
685 if (get_tty_settings (tty
, &ttybuff
) == 0)
687 if (ttybuff
.flags
& SGTTY_SET
)
689 SET_SPECIAL (ttybuff
.sgttyb
.sg_erase
, rl_rubout
);
690 SET_SPECIAL (ttybuff
.sgttyb
.sg_kill
, rl_unix_line_discard
);
693 # if defined (TIOCGLTC)
694 if (ttybuff
.flags
& LTCHARS_SET
)
696 SET_SPECIAL (ttybuff
.ltchars
.t_werasc
, rl_unix_word_rubout
);
697 SET_SPECIAL (ttybuff
.ltchars
.t_lnextc
, rl_quoted_insert
);
699 # endif /* TIOCGLTC */
702 #else /* !NEW_TTY_DRIVER */
704 #define SET_SPECIAL(sc, func) \
708 uc = ttybuff.c_cc[sc]; \
709 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
710 kmap[uc].function = func; \
714 if (get_tty_settings (tty
, &ttybuff
) == 0)
716 SET_SPECIAL (VERASE
, rl_rubout
);
717 SET_SPECIAL (VKILL
, rl_unix_line_discard
);
719 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
720 SET_SPECIAL (VLNEXT
, rl_quoted_insert
);
721 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
723 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
724 SET_SPECIAL (VWERASE
, rl_unix_word_rubout
);
725 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
727 #endif /* !NEW_TTY_DRIVER */