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 */
45 extern int readline_echoing_p;
46 extern int _rl_eof_char;
48 #if defined (__GO32__)
50 # undef HANDLE_SIGNALS
53 /* **************************************************************** */
55 /* Signal Management */
57 /* **************************************************************** */
59 #if defined (HAVE_POSIX_SIGNALS)
60 static sigset_t sigint_set, sigint_oset;
61 #else /* !HAVE_POSIX_SIGNALS */
62 # if defined (HAVE_BSD_SIGNALS)
63 static int sigint_oldmask;
64 # endif /* HAVE_BSD_SIGNALS */
65 #endif /* !HAVE_POSIX_SIGNALS */
67 static int sigint_blocked = 0;
69 /* Cause SIGINT to not be delivered until the corresponding call to
77 #if defined (HAVE_POSIX_SIGNALS)
78 sigemptyset (&sigint_set);
79 sigemptyset (&sigint_oset);
80 sigaddset (&sigint_set, SIGINT);
81 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
82 #else /* !HAVE_POSIX_SIGNALS */
83 # if defined (HAVE_BSD_SIGNALS)
84 sigint_oldmask = sigblock (sigmask (SIGINT));
85 # else /* !HAVE_BSD_SIGNALS */
86 # if defined (HAVE_USG_SIGHOLD)
88 # endif /* HAVE_USG_SIGHOLD */
89 # endif /* !HAVE_BSD_SIGNALS */
90 #endif /* !HAVE_POSIX_SIGNALS */
94 /* Allow SIGINT to be delivered. */
101 #if defined (HAVE_POSIX_SIGNALS)
102 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
104 # if defined (HAVE_BSD_SIGNALS)
105 sigsetmask (sigint_oldmask);
106 # else /* !HAVE_BSD_SIGNALS */
107 # if defined (HAVE_USG_SIGHOLD)
109 # endif /* HAVE_USG_SIGHOLD */
110 # endif /* !HAVE_BSD_SIGNALS */
111 #endif /* !HAVE_POSIX_SIGNALS */
116 /* **************************************************************** */
118 /* Controlling the Meta Key and Keypad */
120 /* **************************************************************** */
122 extern int term_has_meta;
123 extern char *term_mm;
124 extern char *term_mo;
126 extern char *term_ks;
127 extern char *term_ke;
133 return putc (c, rl_outstream);
136 /* Turn on/off the meta key depending on ON. */
138 control_meta_key (on)
144 tputs (term_mm, 1, outchar);
145 else if (!on && term_mo)
146 tputs (term_mo, 1, outchar);
156 tputs (term_ks, 1, outchar);
157 else if (!on && term_ke)
158 tputs (term_ke, 1, outchar);
162 /* **************************************************************** */
164 /* Saving and Restoring the TTY */
166 /* **************************************************************** */
168 /* Non-zero means that the terminal is in a prepped state. */
169 static int terminal_prepped = 0;
171 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
172 and output is suspended. */
173 #if defined (__ksr1__)
174 static int ksrflow = 0;
176 #if defined (NEW_TTY_DRIVER)
178 /* Values for the `flags' field of a struct bsdtty. This tells which
179 elements of the struct bsdtty have been fetched from the system and
181 #define SGTTY_SET 0x01
182 #define LFLAG_SET 0x02
183 #define TCHARS_SET 0x04
184 #define LTCHARS_SET 0x08
187 struct sgttyb sgttyb; /* Basic BSD tty driver information. */
188 int lflag; /* Local mode flags, like LPASS8. */
189 #if defined (TIOCGETC)
190 struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
192 #if defined (TIOCGLTC)
193 struct ltchars ltchars; /* 4.2 BSD editing characters */
195 int flags; /* Bitmap saying which parts of the struct are valid. */
198 #define TIOTYPE struct bsdtty
203 get_tty_settings (tty, tiop)
207 #if !defined (SHELL) && defined (TIOCGWINSZ)
210 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
211 (void) ioctl (tty, TIOCSWINSZ, &w);
214 tiop->flags = tiop->lflag = 0;
216 ioctl (tty, TIOCGETP, &(tiop->sgttyb));
217 tiop->flags |= SGTTY_SET;
219 #if defined (TIOCLGET)
220 ioctl (tty, TIOCLGET, &(tiop->lflag));
221 tiop->flags |= LFLAG_SET;
224 #if defined (TIOCGETC)
225 ioctl (tty, TIOCGETC, &(tiop->tchars));
226 tiop->flags |= TCHARS_SET;
229 #if defined (TIOCGLTC)
230 ioctl (tty, TIOCGLTC, &(tiop->ltchars));
231 tiop->flags |= LTCHARS_SET;
237 set_tty_settings (tty, tiop)
241 if (tiop->flags & SGTTY_SET)
243 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
244 tiop->flags &= ~SGTTY_SET;
246 readline_echoing_p = 1;
248 #if defined (TIOCLSET)
249 if (tiop->flags & LFLAG_SET)
251 ioctl (tty, TIOCLSET, &(tiop->lflag));
252 tiop->flags &= ~LFLAG_SET;
256 #if defined (TIOCSETC)
257 if (tiop->flags & TCHARS_SET)
259 ioctl (tty, TIOCSETC, &(tiop->tchars));
260 tiop->flags &= ~TCHARS_SET;
264 #if defined (TIOCSLTC)
265 if (tiop->flags & LTCHARS_SET)
267 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
268 tiop->flags &= ~LTCHARS_SET;
276 prepare_terminal_settings (meta_flag, otio, tiop)
280 #if !defined (__GO32__)
281 readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
283 /* Copy the original settings to the structure we're going to use for
285 tiop->sgttyb = otio.sgttyb;
286 tiop->lflag = otio.lflag;
287 #if defined (TIOCGETC)
288 tiop->tchars = otio.tchars;
290 #if defined (TIOCGLTC)
291 tiop->ltchars = otio.ltchars;
293 tiop->flags = otio.flags;
295 /* First, the basic settings to put us into character-at-a-time, no-echo
297 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
298 tiop->sgttyb.sg_flags |= CBREAK;
300 /* If this terminal doesn't care how the 8th bit is used, then we can
301 use it for the meta-key. If only one of even or odd parity is
302 specified, then the terminal is using parity, and we cannot. */
304 # define ANYP (EVENP | ODDP)
306 if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
307 ((otio.sgttyb.sg_flags & ANYP) == 0))
309 tiop->sgttyb.sg_flags |= ANYP;
311 /* Hack on local mode flags if we can. */
312 #if defined (TIOCLGET)
313 # if defined (LPASS8)
314 tiop->lflag |= LPASS8;
316 #endif /* TIOCLGET */
319 #if defined (TIOCGETC)
320 # if defined (USE_XON_XOFF)
321 /* Get rid of terminal output start and stop characters. */
322 tiop->tchars.t_stopc = -1; /* C-s */
323 tiop->tchars.t_startc = -1; /* C-q */
325 /* If there is an XON character, bind it to restart the output. */
326 if (otio.tchars.t_startc != -1)
327 rl_bind_key (otio.tchars.t_startc, rl_restart_output);
328 # endif /* USE_XON_XOFF */
330 /* If there is an EOF char, bind _rl_eof_char to it. */
331 if (otio.tchars.t_eofc != -1)
332 _rl_eof_char = otio.tchars.t_eofc;
334 # if defined (NO_KILL_INTR)
335 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
336 tiop->tchars.t_quitc = -1; /* C-\ */
337 tiop->tchars.t_intrc = -1; /* C-c */
338 # endif /* NO_KILL_INTR */
339 #endif /* TIOCGETC */
341 #if defined (TIOCGLTC)
342 /* Make the interrupt keys go away. Just enough to make people happy. */
343 tiop->ltchars.t_dsuspc = -1; /* C-y */
344 tiop->ltchars.t_lnextc = -1; /* C-v */
345 #endif /* TIOCGLTC */
346 #endif /* !__GO32__ */
349 #else /* !defined (NEW_TTY_DRIVER) */
359 #if defined (TERMIOS_TTY_DRIVER)
360 # define TIOTYPE struct termios
361 # define DRAIN_OUTPUT(fd) tcdrain (fd)
362 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
363 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
365 # define TIOTYPE struct termio
366 # define DRAIN_OUTPUT(fd)
367 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
368 # define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
369 #endif /* !TERMIOS_TTY_DRIVER */
374 # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
376 # define OUTPUT_BEING_FLUSHED(tp) 0
380 get_tty_settings (tty, tiop)
385 #if !defined (SHELL) && defined (TIOCGWINSZ)
388 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
389 (void) ioctl (tty, TIOCSWINSZ, &w);
392 /* Keep looping if output is being flushed after a ^O (or whatever
393 the flush character is). */
394 while ((ioctl_ret = GETATTR (tty, tiop)) < 0 || OUTPUT_BEING_FLUSHED (tiop))
396 if (ioctl_ret < 0 && errno != EINTR)
398 if (OUTPUT_BEING_FLUSHED (tiop))
406 set_tty_settings (tty, tiop)
410 while (SETATTR (tty, tiop) < 0)
419 #if defined (TERMIOS_TTY_DRIVER)
420 # if defined (__ksr1__)
427 tcflow (tty, TCOON); /* Simulate a ^Q. */
430 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
431 #endif /* !TERMIOS_TTY_DRIVER */
439 prepare_terminal_settings (meta_flag, otio, tiop)
443 readline_echoing_p = (otio.c_lflag & ECHO);
445 tiop->c_lflag &= ~(ICANON | ECHO);
447 if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
448 _rl_eof_char = otio.c_cc[VEOF];
450 #if defined (USE_XON_XOFF)
452 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
454 /* `strict' Posix systems do not define IXANY. */
455 tiop->c_iflag &= ~(IXON | IXOFF);
457 #endif /* USE_XON_XOFF */
459 /* Only turn this off if we are using all 8 bits. */
460 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
461 tiop->c_iflag &= ~(ISTRIP | INPCK);
463 /* Make sure we differentiate between CR and NL on input. */
464 tiop->c_iflag &= ~(ICRNL | INLCR);
466 #if !defined (HANDLE_SIGNALS)
467 tiop->c_lflag &= ~ISIG;
469 tiop->c_lflag |= ISIG;
472 tiop->c_cc[VMIN] = 1;
473 tiop->c_cc[VTIME] = 0;
476 if (OUTPUT_BEING_FLUSHED (tiop))
478 tiop->c_lflag &= ~FLUSHO;
479 otio.c_lflag &= ~FLUSHO;
483 /* Turn off characters that we need on Posix systems with job control,
484 just to be sure. This includes ^Y and ^V. This should not really
486 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
489 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
493 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
496 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
498 #endif /* NEW_TTY_DRIVER */
500 /* Put the terminal in CBREAK mode so that we can detect key presses. */
502 rl_prep_terminal (meta_flag)
505 #if !defined (__GO32__)
506 int tty = fileno (rl_instream);
509 if (terminal_prepped)
512 /* Try to keep this function from being INTerrupted. */
515 if (get_tty_settings (tty, &tio) < 0)
523 prepare_terminal_settings (meta_flag, otio, &tio);
525 if (set_tty_settings (tty, &tio) < 0)
531 control_meta_key (1);
535 fflush (rl_outstream);
536 terminal_prepped = 1;
539 #endif /* !__GO32__ */
542 /* Restore the terminal's normal settings and modes. */
544 rl_deprep_terminal ()
546 #if !defined (__GO32__)
547 int tty = fileno (rl_instream);
549 if (!terminal_prepped)
552 /* Try to keep this function from being INTerrupted. */
555 control_meta_key (0);
559 fflush (rl_outstream);
561 if (set_tty_settings (tty, &otio) < 0)
567 terminal_prepped = 0;
570 #endif /* !__GO32__ */
573 /* **************************************************************** */
575 /* Bogus Flow Control */
577 /* **************************************************************** */
579 rl_restart_output (count, key)
582 int fildes = fileno (rl_outstream);
583 #if defined (TIOCSTART)
585 ioctl (&fildes, TIOCSTART, 0);
587 ioctl (fildes, TIOCSTART, 0);
590 #else /* !TIOCSTART */
591 # if defined (TERMIOS_TTY_DRIVER)
592 # if defined (__ksr1__)
596 tcflow (fildes, TCOON);
599 tcflow (fildes, TCOON); /* Simulate a ^Q. */
601 # else /* !TERMIOS_TTY_DRIVER */
602 # if defined (TCXONC)
603 ioctl (fildes, TCXONC, TCOON);
605 # endif /* !TERMIOS_TTY_DRIVER */
606 #endif /* !TIOCSTART */
611 rl_stop_output (count, key)
614 int fildes = fileno (rl_instream);
616 #if defined (TIOCSTOP)
617 # if defined (apollo)
618 ioctl (&fildes, TIOCSTOP, 0);
620 ioctl (fildes, TIOCSTOP, 0);
622 #else /* !TIOCSTOP */
623 # if defined (TERMIOS_TTY_DRIVER)
624 # if defined (__ksr1__)
627 tcflow (fildes, TCOOFF);
629 # if defined (TCXONC)
630 ioctl (fildes, TCXONC, TCOON);
632 # endif /* !TERMIOS_TTY_DRIVER */
633 #endif /* !TIOCSTOP */
638 /* **************************************************************** */
640 /* Default Key Bindings */
642 /* **************************************************************** */
644 rltty_set_default_bindings (kmap)
648 int tty = fileno (rl_instream);
650 #if defined (NEW_TTY_DRIVER)
652 #define SET_SPECIAL(sc, func) \
657 if (ic != -1 && kmap[ic].type == ISFUNC) \
658 kmap[ic].function = func; \
662 if (get_tty_settings (tty, &ttybuff) == 0)
664 if (ttybuff.flags & SGTTY_SET)
666 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
667 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
670 # if defined (TIOCGLTC)
671 if (ttybuff.flags & LTCHARS_SET)
673 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
674 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
676 # endif /* TIOCGLTC */
679 #else /* !NEW_TTY_DRIVER */
681 #define SET_SPECIAL(sc, func) \
685 uc = ttybuff.c_cc[sc]; \
686 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
687 kmap[uc].function = func; \
691 if (get_tty_settings (tty, &ttybuff) == 0)
693 SET_SPECIAL (VERASE, rl_rubout);
694 SET_SPECIAL (VKILL, rl_unix_line_discard);
696 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
697 SET_SPECIAL (VLNEXT, rl_quoted_insert);
698 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
700 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
701 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
702 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
704 #endif /* !NEW_TTY_DRIVER */