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 #include <sys/types.h>
28 #if defined (HAVE_UNISTD_H)
30 #endif /* HAVE_UNISTD_H */
39 extern int readline_echoing_p;
40 extern int _rl_eof_char;
44 # undef HANDLE_SIGNALS
47 /* **************************************************************** */
49 /* Signal Management */
51 /* **************************************************************** */
53 #if defined (HAVE_POSIX_SIGNALS)
54 static sigset_t sigint_set, sigint_oset;
55 #else /* !HAVE_POSIX_SIGNALS */
56 # if defined (HAVE_BSD_SIGNALS)
57 static int sigint_oldmask;
58 # endif /* HAVE_BSD_SIGNALS */
59 #endif /* !HAVE_POSIX_SIGNALS */
61 static int sigint_blocked = 0;
63 /* Cause SIGINT to not be delivered until the corresponding call to
71 #if defined (HAVE_POSIX_SIGNALS)
72 sigemptyset (&sigint_set);
73 sigemptyset (&sigint_oset);
74 sigaddset (&sigint_set, SIGINT);
75 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
76 #else /* !HAVE_POSIX_SIGNALS */
77 # if defined (HAVE_BSD_SIGNALS)
78 sigint_oldmask = sigblock (sigmask (SIGINT));
79 # else /* !HAVE_BSD_SIGNALS */
80 # if defined (HAVE_USG_SIGHOLD)
82 # endif /* HAVE_USG_SIGHOLD */
83 # endif /* !HAVE_BSD_SIGNALS */
84 #endif /* !HAVE_POSIX_SIGNALS */
88 /* Allow SIGINT to be delivered. */
95 #if defined (HAVE_POSIX_SIGNALS)
96 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
98 # if defined (HAVE_BSD_SIGNALS)
99 sigsetmask (sigint_oldmask);
100 # else /* !HAVE_BSD_SIGNALS */
101 # if defined (HAVE_USG_SIGHOLD)
103 # endif /* HAVE_USG_SIGHOLD */
104 # endif /* !HAVE_BSD_SIGNALS */
105 #endif /* !HAVE_POSIX_SIGNALS */
110 /* **************************************************************** */
112 /* Controlling the Meta Key */
114 /* **************************************************************** */
116 extern int term_has_meta;
117 extern char *term_mm;
118 extern char *term_mo;
124 putc (c, rl_outstream);
127 /* Turn on/off the meta key depending on ON. */
129 control_meta_key (on)
135 tputs (term_mm, 1, outchar);
136 else if (!on && term_mo)
137 tputs (term_mo, 1, outchar);
141 /* **************************************************************** */
143 /* Saving and Restoring the TTY */
145 /* **************************************************************** */
147 /* Non-zero means that the terminal is in a prepped state. */
148 static int terminal_prepped = 0;
150 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
151 and output is suspended. */
152 #if defined (__ksr1__)
153 static int ksrflow = 0;
155 #if defined (NEW_TTY_DRIVER)
157 /* Values for the `flags' field of a struct bsdtty. This tells which
158 elements of the struct bsdtty have been fetched from the system and
160 #define SGTTY_SET 0x01
161 #define LFLAG_SET 0x02
162 #define TCHARS_SET 0x04
163 #define LTCHARS_SET 0x08
166 struct sgttyb sgttyb; /* Basic BSD tty driver information. */
167 int lflag; /* Local mode flags, like LPASS8. */
168 #if defined (TIOCGETC)
169 struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
171 #if defined (TIOCGLTC)
172 struct ltchars ltchars; /* 4.2 BSD editing characters */
174 int flags; /* Bitmap saying which parts of the struct are valid. */
177 #define TIOTYPE struct bsdtty
182 get_tty_settings (tty, tiop)
186 tiop->flags = tiop->lflag = 0;
188 ioctl (tty, TIOCGETP, &(tiop->sgttyb));
189 tiop->flags |= SGTTY_SET;
191 #if defined (TIOCLGET)
192 ioctl (tty, TIOCLGET, &(tiop->lflag));
193 tiop->flags |= LFLAG_SET;
196 #if defined (TIOCGETC)
197 ioctl (tty, TIOCGETC, &(tiop->tchars));
198 tiop->flags |= TCHARS_SET;
201 #if defined (TIOCGLTC)
202 ioctl (tty, TIOCGLTC, &(tiop->ltchars));
203 tiop->flags |= LTCHARS_SET;
209 set_tty_settings (tty, tiop)
213 if (tiop->flags & SGTTY_SET)
215 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
216 tiop->flags &= ~SGTTY_SET;
218 readline_echoing_p = 1;
220 #if defined (TIOCLSET)
221 if (tiop->flags & LFLAG_SET)
223 ioctl (tty, TIOCLSET, &(tiop->lflag));
224 tiop->flags &= ~LFLAG_SET;
228 #if defined (TIOCSETC)
229 if (tiop->flags & TCHARS_SET)
231 ioctl (tty, TIOCSETC, &(tiop->tchars));
232 tiop->flags &= ~TCHARS_SET;
236 #if defined (TIOCSLTC)
237 if (tiop->flags & LTCHARS_SET)
239 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
240 tiop->flags &= ~LTCHARS_SET;
248 prepare_terminal_settings (meta_flag, otio, tiop)
252 #if !defined (_GO32_)
253 readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
255 /* Copy the original settings to the structure we're going to use for
257 tiop->sgttyb = otio.sgttyb;
258 tiop->lflag = otio.lflag;
259 #if defined (TIOCGETC)
260 tiop->tchars = otio.tchars;
262 #if defined (TIOCGLTC)
263 tiop->ltchars = otio.ltchars;
265 tiop->flags = otio.flags;
267 /* First, the basic settings to put us into character-at-a-time, no-echo
269 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
270 tiop->sgttyb.sg_flags |= CBREAK;
272 /* If this terminal doesn't care how the 8th bit is used, then we can
273 use it for the meta-key. If only one of even or odd parity is
274 specified, then the terminal is using parity, and we cannot. */
276 # define ANYP (EVENP | ODDP)
278 if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
279 ((otio.sgttyb.sg_flags & ANYP) == 0))
281 tiop->sgttyb.sg_flags |= ANYP;
283 /* Hack on local mode flags if we can. */
284 #if defined (TIOCLGET)
285 # if defined (LPASS8)
286 tiop->lflag |= LPASS8;
288 #endif /* TIOCLGET */
291 #if defined (TIOCGETC)
292 # if defined (USE_XON_XOFF)
293 /* Get rid of terminal output start and stop characters. */
294 tiop->tchars.t_stopc = -1; /* C-s */
295 tiop->tchars.t_startc = -1; /* C-q */
297 /* If there is an XON character, bind it to restart the output. */
298 if (otio.tchars.t_startc != -1)
299 rl_bind_key (otio.tchars.t_startc, rl_restart_output);
300 # endif /* USE_XON_XOFF */
302 /* If there is an EOF char, bind _rl_eof_char to it. */
303 if (otio.tchars.t_eofc != -1)
304 _rl_eof_char = otio.tchars.t_eofc;
306 # if defined (NO_KILL_INTR)
307 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
308 tiop->tchars.t_quitc = -1; /* C-\ */
309 tiop->tchars.t_intrc = -1; /* C-c */
310 # endif /* NO_KILL_INTR */
311 #endif /* TIOCGETC */
313 #if defined (TIOCGLTC)
314 /* Make the interrupt keys go away. Just enough to make people happy. */
315 tiop->ltchars.t_dsuspc = -1; /* C-y */
316 tiop->ltchars.t_lnextc = -1; /* C-v */
317 #endif /* TIOCGLTC */
320 #endif /* defined (NEW_TTY_DRIVER) */
322 #if !defined (NEW_TTY_DRIVER) && !defined(_GO32_)
332 #if defined (TERMIOS_TTY_DRIVER)
333 # define TIOTYPE struct termios
334 # define DRAIN_OUTPUT(fd) tcdrain (fd)
335 # define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
336 # define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
338 # define TIOTYPE struct termio
339 # define DRAIN_OUTPUT(fd)
340 # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
341 # define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
342 #endif /* !TERMIOS_TTY_DRIVER */
347 get_tty_settings (tty, tiop)
351 while (GETATTR (tty, tiop) < 0)
361 set_tty_settings (tty, tiop)
365 while (SETATTR (tty, tiop) < 0)
374 #if defined (TERMIOS_TTY_DRIVER)
375 # if defined (__ksr1__)
382 tcflow (tty, TCOON); /* Simulate a ^Q. */
385 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
386 #endif /* !TERMIOS_TTY_DRIVER */
394 prepare_terminal_settings (meta_flag, otio, tiop)
398 readline_echoing_p = (otio.c_lflag & ECHO);
400 tiop->c_lflag &= ~(ICANON | ECHO);
402 if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
403 _rl_eof_char = otio.c_cc[VEOF];
405 #if defined (USE_XON_XOFF)
407 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
409 /* `strict' Posix systems do not define IXANY. */
410 tiop->c_iflag &= ~(IXON | IXOFF);
412 #endif /* USE_XON_XOFF */
414 /* Only turn this off if we are using all 8 bits. */
415 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
416 tiop->c_iflag &= ~(ISTRIP | INPCK);
418 /* Make sure we differentiate between CR and NL on input. */
419 tiop->c_iflag &= ~(ICRNL | INLCR);
421 #if !defined (HANDLE_SIGNALS)
422 tiop->c_lflag &= ~ISIG;
424 tiop->c_lflag |= ISIG;
427 tiop->c_cc[VMIN] = 1;
428 tiop->c_cc[VTIME] = 0;
430 /* Turn off characters that we need on Posix systems with job control,
431 just to be sure. This includes ^Y and ^V. This should not really
433 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
436 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
440 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
443 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
445 #endif /* !defined (NEW_TTY_DRIVER) && !defined(_GO32_) */
447 /* Put the terminal in CBREAK mode so that we can detect key presses. */
449 rl_prep_terminal (meta_flag)
452 #if !defined (_GO32_)
453 int tty = fileno (rl_instream);
456 if (terminal_prepped)
459 /* Try to keep this function from being INTerrupted. */
462 if (get_tty_settings (tty, &tio) < 0)
470 prepare_terminal_settings (meta_flag, otio, &tio);
472 if (set_tty_settings (tty, &tio) < 0)
478 control_meta_key (1);
479 terminal_prepped = 1;
485 /* Restore the terminal's normal settings and modes. */
487 rl_deprep_terminal ()
489 #if !defined (_GO32_)
490 int tty = fileno (rl_instream);
492 if (!terminal_prepped)
495 /* Try to keep this function from being INTerrupted. */
498 if (set_tty_settings (tty, &otio) < 0)
504 control_meta_key (0);
505 terminal_prepped = 0;
511 /* **************************************************************** */
513 /* Bogus Flow Control */
515 /* **************************************************************** */
517 rl_restart_output (count, key)
520 int fildes = fileno (rl_outstream);
521 #if defined (TIOCSTART)
523 ioctl (&fildes, TIOCSTART, 0);
525 ioctl (fildes, TIOCSTART, 0);
528 #else /* !TIOCSTART */
529 # if defined (TERMIOS_TTY_DRIVER)
530 # if defined (__ksr1__)
534 tcflow (fildes, TCOON);
537 tcflow (fildes, TCOON); /* Simulate a ^Q. */
539 # else /* !TERMIOS_TTY_DRIVER */
540 # if defined (TCXONC)
541 ioctl (fildes, TCXONC, TCOON);
543 # endif /* !TERMIOS_TTY_DRIVER */
544 #endif /* !TIOCSTART */
547 rl_stop_output (count, key)
550 int fildes = fileno (rl_instream);
552 #if defined (TIOCSTOP)
553 # if defined (apollo)
554 ioctl (&fildes, TIOCSTOP, 0);
556 ioctl (fildes, TIOCSTOP, 0);
558 #else /* !TIOCSTOP */
559 # if defined (TERMIOS_TTY_DRIVER)
560 # if defined (__ksr1__)
563 tcflow (fildes, TCOOFF);
565 # if defined (TCXONC)
566 ioctl (fildes, TCXONC, TCOON);
568 # endif /* !TERMIOS_TTY_DRIVER */
569 #endif /* !TIOCSTOP */
572 /* **************************************************************** */
574 /* Default Key Bindings */
576 /* **************************************************************** */
578 rltty_set_default_bindings (kmap)
582 int tty = fileno (rl_instream);
584 #if defined (NEW_TTY_DRIVER)
586 if (get_tty_settings (tty, &ttybuff) == 0)
588 if (ttybuff.flags & SGTTY_SET)
592 erase = ttybuff.sgttyb.sg_erase;
593 kill = ttybuff.sgttyb.sg_kill;
595 if (erase != -1 && kmap[erase].type == ISFUNC)
596 kmap[erase].function = rl_rubout;
598 if (kill != -1 && kmap[kill].type == ISFUNC)
599 kmap[kill].function = rl_unix_line_discard;
602 # if defined (TIOCGLTC)
604 if (ttybuff.flags & LTCHARS_SET)
608 werase = ttybuff.ltchars.t_werasc;
609 nextc = ttybuff.ltchars.t_lnextc;
611 if (werase != -1 && kmap[werase].type == ISFUNC)
612 kmap[werase].function = rl_unix_word_rubout;
614 if (nextc != -1 && kmap[nextc].type == ISFUNC)
615 kmap[nextc].function = rl_quoted_insert;
618 # endif /* TIOCGLTC */
620 #else /* !NEW_TTY_DRIVER */
622 if (get_tty_settings (tty, &ttybuff) == 0)
624 unsigned char erase, kill;
626 erase = ttybuff.c_cc[VERASE];
627 kill = ttybuff.c_cc[VKILL];
629 if (erase != (unsigned char)_POSIX_VDISABLE &&
630 kmap[erase].type == ISFUNC)
631 kmap[erase].function = rl_rubout;
633 if (kill != (unsigned char)_POSIX_VDISABLE &&
634 kmap[kill].type == ISFUNC)
635 kmap[kill].function = rl_unix_line_discard;
637 # if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
641 nextc = ttybuff.c_cc[VLNEXT];
643 if (nextc != (unsigned char)_POSIX_VDISABLE &&
644 kmap[nextc].type == ISFUNC)
645 kmap[nextc].function = rl_quoted_insert;
647 # endif /* VLNEXT && TERMIOS_TTY_DRIVER */
649 # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
651 unsigned char werase;
653 werase = ttybuff.c_cc[VWERASE];
655 if (werase != (unsigned char)_POSIX_VDISABLE &&
656 kmap[werase].type == ISFUNC)
657 kmap[werase].function = rl_unix_word_rubout;
659 # endif /* VWERASE && TERMIOS_TTY_DRIVER */
661 #endif /* !NEW_TTY_DRIVER */