121308Sache/* rltty.c -- functions to prepare and restore the terminal for readline's 221308Sache use. */ 321308Sache 4157184Sache/* Copyright (C) 1992-2005 Free Software Foundation, Inc. 521308Sache 621308Sache This file is part of the GNU Readline Library, a library for 721308Sache reading lines of text with interactive input and history editing. 821308Sache 921308Sache The GNU Readline Library is free software; you can redistribute it 1021308Sache and/or modify it under the terms of the GNU General Public License 1158310Sache as published by the Free Software Foundation; either version 2, or 1221308Sache (at your option) any later version. 1321308Sache 1421308Sache The GNU Readline Library is distributed in the hope that it will be 1521308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1621308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1721308Sache GNU General Public License for more details. 1821308Sache 1921308Sache The GNU General Public License is often shipped with GNU software, and 2021308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2121308Sache have a copy of the license, write to the Free Software Foundation, 2258310Sache 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 2321308Sache#define READLINE_LIBRARY 2421308Sache 2521308Sache#if defined (HAVE_CONFIG_H) 2621308Sache# include <config.h> 2721308Sache#endif 2821308Sache 2921308Sache#include <sys/types.h> 3021308Sache#include <signal.h> 3121308Sache#include <errno.h> 3221308Sache#include <stdio.h> 3321308Sache 3421308Sache#if defined (HAVE_UNISTD_H) 3521308Sache# include <unistd.h> 3621308Sache#endif /* HAVE_UNISTD_H */ 3721308Sache 3821308Sache#include "rldefs.h" 3921308Sache 4047558Sache#if defined (GWINSZ_IN_SYS_IOCTL) 4121308Sache# include <sys/ioctl.h> 4247558Sache#endif /* GWINSZ_IN_SYS_IOCTL */ 4321308Sache 4421308Sache#include "rltty.h" 4521308Sache#include "readline.h" 4658310Sache#include "rlprivate.h" 4721308Sache 4821308Sache#if !defined (errno) 4921308Sacheextern int errno; 5021308Sache#endif /* !errno */ 5121308Sache 5275406Sacherl_vintfunc_t *rl_prep_term_function = rl_prep_terminal; 5375406Sacherl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal; 5421308Sache 55119610Sachestatic void block_sigint PARAMS((void)); 56119610Sachestatic void release_sigint PARAMS((void)); 57119610Sache 58119610Sachestatic void set_winsize PARAMS((int)); 59119610Sache 6021308Sache/* **************************************************************** */ 6121308Sache/* */ 6221308Sache/* Signal Management */ 6321308Sache/* */ 6421308Sache/* **************************************************************** */ 6521308Sache 6621308Sache#if defined (HAVE_POSIX_SIGNALS) 6721308Sachestatic sigset_t sigint_set, sigint_oset; 6821308Sache#else /* !HAVE_POSIX_SIGNALS */ 6921308Sache# if defined (HAVE_BSD_SIGNALS) 7021308Sachestatic int sigint_oldmask; 7121308Sache# endif /* HAVE_BSD_SIGNALS */ 7221308Sache#endif /* !HAVE_POSIX_SIGNALS */ 7321308Sache 7421308Sachestatic int sigint_blocked; 7521308Sache 7621308Sache/* Cause SIGINT to not be delivered until the corresponding call to 7721308Sache release_sigint(). */ 7821308Sachestatic void 7921308Sacheblock_sigint () 8021308Sache{ 8121308Sache if (sigint_blocked) 8221308Sache return; 8321308Sache 8421308Sache#if defined (HAVE_POSIX_SIGNALS) 8521308Sache sigemptyset (&sigint_set); 8621308Sache sigemptyset (&sigint_oset); 8721308Sache sigaddset (&sigint_set, SIGINT); 8821308Sache sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset); 8921308Sache#else /* !HAVE_POSIX_SIGNALS */ 9021308Sache# if defined (HAVE_BSD_SIGNALS) 9121308Sache sigint_oldmask = sigblock (sigmask (SIGINT)); 9221308Sache# else /* !HAVE_BSD_SIGNALS */ 9321308Sache# if defined (HAVE_USG_SIGHOLD) 9421308Sache sighold (SIGINT); 9521308Sache# endif /* HAVE_USG_SIGHOLD */ 9621308Sache# endif /* !HAVE_BSD_SIGNALS */ 9721308Sache#endif /* !HAVE_POSIX_SIGNALS */ 9858310Sache 9921308Sache sigint_blocked = 1; 10021308Sache} 10121308Sache 10221308Sache/* Allow SIGINT to be delivered. */ 10321308Sachestatic void 10421308Sacherelease_sigint () 10521308Sache{ 10658310Sache if (sigint_blocked == 0) 10721308Sache return; 10821308Sache 10921308Sache#if defined (HAVE_POSIX_SIGNALS) 11021308Sache sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL); 11121308Sache#else 11221308Sache# if defined (HAVE_BSD_SIGNALS) 11321308Sache sigsetmask (sigint_oldmask); 11421308Sache# else /* !HAVE_BSD_SIGNALS */ 11521308Sache# if defined (HAVE_USG_SIGHOLD) 11621308Sache sigrelse (SIGINT); 11721308Sache# endif /* HAVE_USG_SIGHOLD */ 11821308Sache# endif /* !HAVE_BSD_SIGNALS */ 11921308Sache#endif /* !HAVE_POSIX_SIGNALS */ 12021308Sache 12121308Sache sigint_blocked = 0; 12221308Sache} 12321308Sache 12421308Sache/* **************************************************************** */ 12521308Sache/* */ 12621308Sache/* Saving and Restoring the TTY */ 12721308Sache/* */ 12821308Sache/* **************************************************************** */ 12921308Sache 13021308Sache/* Non-zero means that the terminal is in a prepped state. */ 13121308Sachestatic int terminal_prepped; 13221308Sache 13358310Sachestatic _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars; 13458310Sache 13521308Sache/* If non-zero, means that this process has called tcflow(fd, TCOOFF) 13621308Sache and output is suspended. */ 13721308Sache#if defined (__ksr1__) 13821308Sachestatic int ksrflow; 13921308Sache#endif 14021308Sache 14121308Sache/* Dummy call to force a backgrounded readline to stop before it tries 14221308Sache to get the tty settings. */ 14321308Sachestatic void 14421308Sacheset_winsize (tty) 14521308Sache int tty; 14621308Sache{ 14758310Sache#if defined (TIOCGWINSZ) 14821308Sache struct winsize w; 14921308Sache 15021308Sache if (ioctl (tty, TIOCGWINSZ, &w) == 0) 15121308Sache (void) ioctl (tty, TIOCSWINSZ, &w); 15258310Sache#endif /* TIOCGWINSZ */ 15321308Sache} 15421308Sache 155157184Sache#if defined (NO_TTY_DRIVER) 156157184Sache/* Nothing */ 157157184Sache#elif defined (NEW_TTY_DRIVER) 15821308Sache 15921308Sache/* Values for the `flags' field of a struct bsdtty. This tells which 16021308Sache elements of the struct bsdtty have been fetched from the system and 16121308Sache are valid. */ 16221308Sache#define SGTTY_SET 0x01 16321308Sache#define LFLAG_SET 0x02 16421308Sache#define TCHARS_SET 0x04 16521308Sache#define LTCHARS_SET 0x08 16621308Sache 16721308Sachestruct bsdtty { 16821308Sache struct sgttyb sgttyb; /* Basic BSD tty driver information. */ 16921308Sache int lflag; /* Local mode flags, like LPASS8. */ 17021308Sache#if defined (TIOCGETC) 17121308Sache struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */ 17221308Sache#endif 17321308Sache#if defined (TIOCGLTC) 17421308Sache struct ltchars ltchars; /* 4.2 BSD editing characters */ 17521308Sache#endif 17621308Sache int flags; /* Bitmap saying which parts of the struct are valid. */ 17721308Sache}; 17821308Sache 17921308Sache#define TIOTYPE struct bsdtty 18021308Sache 18121308Sachestatic TIOTYPE otio; 18221308Sache 183119610Sachestatic void save_tty_chars PARAMS((TIOTYPE *)); 184119610Sachestatic int _get_tty_settings PARAMS((int, TIOTYPE *)); 185119610Sachestatic int get_tty_settings PARAMS((int, TIOTYPE *)); 186119610Sachestatic int _set_tty_settings PARAMS((int, TIOTYPE *)); 187119610Sachestatic int set_tty_settings PARAMS((int, TIOTYPE *)); 188119610Sache 189119610Sachestatic void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); 190119610Sache 191136644Sachestatic void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t)); 192136644Sache 19358310Sachestatic void 19458310Sachesave_tty_chars (tiop) 19558310Sache TIOTYPE *tiop; 19658310Sache{ 19758310Sache _rl_last_tty_chars = _rl_tty_chars; 19858310Sache 19958310Sache if (tiop->flags & SGTTY_SET) 20058310Sache { 20158310Sache _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase; 20258310Sache _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill; 20358310Sache } 20458310Sache 20558310Sache if (tiop->flags & TCHARS_SET) 20658310Sache { 20758310Sache _rl_tty_chars.t_intr = tiop->tchars.t_intrc; 20858310Sache _rl_tty_chars.t_quit = tiop->tchars.t_quitc; 20958310Sache _rl_tty_chars.t_start = tiop->tchars.t_startc; 21075406Sache _rl_tty_chars.t_stop = tiop->tchars.t_stopc; 21158310Sache _rl_tty_chars.t_eof = tiop->tchars.t_eofc; 21258310Sache _rl_tty_chars.t_eol = '\n'; 21358310Sache _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc; 21458310Sache } 21558310Sache 21658310Sache if (tiop->flags & LTCHARS_SET) 21758310Sache { 21858310Sache _rl_tty_chars.t_susp = tiop->ltchars.t_suspc; 21958310Sache _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc; 22058310Sache _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc; 22158310Sache _rl_tty_chars.t_flush = tiop->ltchars.t_flushc; 22258310Sache _rl_tty_chars.t_werase = tiop->ltchars.t_werasc; 22358310Sache _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc; 22458310Sache } 22558310Sache 22658310Sache _rl_tty_chars.t_status = -1; 22758310Sache} 22858310Sache 22921308Sachestatic int 23021308Sacheget_tty_settings (tty, tiop) 23121308Sache int tty; 23221308Sache TIOTYPE *tiop; 23321308Sache{ 23421308Sache set_winsize (tty); 23521308Sache 23621308Sache tiop->flags = tiop->lflag = 0; 23721308Sache 238157184Sache errno = 0; 23975406Sache if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0) 24075406Sache return -1; 24121308Sache tiop->flags |= SGTTY_SET; 24221308Sache 24321308Sache#if defined (TIOCLGET) 24475406Sache if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0) 24575406Sache tiop->flags |= LFLAG_SET; 24621308Sache#endif 24721308Sache 24821308Sache#if defined (TIOCGETC) 24975406Sache if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0) 25075406Sache tiop->flags |= TCHARS_SET; 25121308Sache#endif 25221308Sache 25321308Sache#if defined (TIOCGLTC) 25475406Sache if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0) 25575406Sache tiop->flags |= LTCHARS_SET; 25621308Sache#endif 25721308Sache 25821308Sache return 0; 25921308Sache} 26021308Sache 26121308Sachestatic int 26221308Sacheset_tty_settings (tty, tiop) 26321308Sache int tty; 26421308Sache TIOTYPE *tiop; 26521308Sache{ 26621308Sache if (tiop->flags & SGTTY_SET) 26721308Sache { 26821308Sache ioctl (tty, TIOCSETN, &(tiop->sgttyb)); 26921308Sache tiop->flags &= ~SGTTY_SET; 27021308Sache } 27121308Sache readline_echoing_p = 1; 27221308Sache 27321308Sache#if defined (TIOCLSET) 27421308Sache if (tiop->flags & LFLAG_SET) 27521308Sache { 27621308Sache ioctl (tty, TIOCLSET, &(tiop->lflag)); 27721308Sache tiop->flags &= ~LFLAG_SET; 27821308Sache } 27921308Sache#endif 28021308Sache 28121308Sache#if defined (TIOCSETC) 28221308Sache if (tiop->flags & TCHARS_SET) 28321308Sache { 28421308Sache ioctl (tty, TIOCSETC, &(tiop->tchars)); 28521308Sache tiop->flags &= ~TCHARS_SET; 28621308Sache } 28721308Sache#endif 28821308Sache 28921308Sache#if defined (TIOCSLTC) 29021308Sache if (tiop->flags & LTCHARS_SET) 29121308Sache { 29221308Sache ioctl (tty, TIOCSLTC, &(tiop->ltchars)); 29321308Sache tiop->flags &= ~LTCHARS_SET; 29421308Sache } 29521308Sache#endif 29621308Sache 29721308Sache return 0; 29821308Sache} 29921308Sache 30021308Sachestatic void 30175406Sacheprepare_terminal_settings (meta_flag, oldtio, tiop) 30221308Sache int meta_flag; 30375406Sache TIOTYPE oldtio, *tiop; 30421308Sache{ 30575406Sache readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO); 30621308Sache 30721308Sache /* Copy the original settings to the structure we're going to use for 30821308Sache our settings. */ 30975406Sache tiop->sgttyb = oldtio.sgttyb; 31075406Sache tiop->lflag = oldtio.lflag; 31121308Sache#if defined (TIOCGETC) 31275406Sache tiop->tchars = oldtio.tchars; 31321308Sache#endif 31421308Sache#if defined (TIOCGLTC) 31575406Sache tiop->ltchars = oldtio.ltchars; 31621308Sache#endif 31775406Sache tiop->flags = oldtio.flags; 31821308Sache 31921308Sache /* First, the basic settings to put us into character-at-a-time, no-echo 32021308Sache input mode. */ 32121308Sache tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD); 32221308Sache tiop->sgttyb.sg_flags |= CBREAK; 32321308Sache 32421308Sache /* If this terminal doesn't care how the 8th bit is used, then we can 32521308Sache use it for the meta-key. If only one of even or odd parity is 32621308Sache specified, then the terminal is using parity, and we cannot. */ 32721308Sache#if !defined (ANYP) 32821308Sache# define ANYP (EVENP | ODDP) 32921308Sache#endif 33075406Sache if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) || 33175406Sache ((oldtio.sgttyb.sg_flags & ANYP) == 0)) 33221308Sache { 33321308Sache tiop->sgttyb.sg_flags |= ANYP; 33421308Sache 33521308Sache /* Hack on local mode flags if we can. */ 33621308Sache#if defined (TIOCLGET) 33721308Sache# if defined (LPASS8) 33821308Sache tiop->lflag |= LPASS8; 33921308Sache# endif /* LPASS8 */ 34021308Sache#endif /* TIOCLGET */ 34121308Sache } 34221308Sache 34321308Sache#if defined (TIOCGETC) 34421308Sache# if defined (USE_XON_XOFF) 34521308Sache /* Get rid of terminal output start and stop characters. */ 34621308Sache tiop->tchars.t_stopc = -1; /* C-s */ 34721308Sache tiop->tchars.t_startc = -1; /* C-q */ 34821308Sache 34921308Sache /* If there is an XON character, bind it to restart the output. */ 35075406Sache if (oldtio.tchars.t_startc != -1) 35175406Sache rl_bind_key (oldtio.tchars.t_startc, rl_restart_output); 35221308Sache# endif /* USE_XON_XOFF */ 35321308Sache 35421308Sache /* If there is an EOF char, bind _rl_eof_char to it. */ 35575406Sache if (oldtio.tchars.t_eofc != -1) 35675406Sache _rl_eof_char = oldtio.tchars.t_eofc; 35721308Sache 35821308Sache# if defined (NO_KILL_INTR) 35921308Sache /* Get rid of terminal-generated SIGQUIT and SIGINT. */ 36021308Sache tiop->tchars.t_quitc = -1; /* C-\ */ 36121308Sache tiop->tchars.t_intrc = -1; /* C-c */ 36221308Sache# endif /* NO_KILL_INTR */ 36321308Sache#endif /* TIOCGETC */ 36421308Sache 36521308Sache#if defined (TIOCGLTC) 36621308Sache /* Make the interrupt keys go away. Just enough to make people happy. */ 36721308Sache tiop->ltchars.t_dsuspc = -1; /* C-y */ 36821308Sache tiop->ltchars.t_lnextc = -1; /* C-v */ 36921308Sache#endif /* TIOCGLTC */ 37021308Sache} 37121308Sache 37221308Sache#else /* !defined (NEW_TTY_DRIVER) */ 37321308Sache 37421308Sache#if !defined (VMIN) 37521308Sache# define VMIN VEOF 37621308Sache#endif 37721308Sache 37821308Sache#if !defined (VTIME) 37921308Sache# define VTIME VEOL 38021308Sache#endif 38121308Sache 38221308Sache#if defined (TERMIOS_TTY_DRIVER) 38321308Sache# define TIOTYPE struct termios 38421308Sache# define DRAIN_OUTPUT(fd) tcdrain (fd) 38521308Sache# define GETATTR(tty, tiop) (tcgetattr (tty, tiop)) 38621308Sache# ifdef M_UNIX 38721308Sache# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop)) 38821308Sache# else 38921308Sache# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop)) 39021308Sache# endif /* !M_UNIX */ 39121308Sache#else 39221308Sache# define TIOTYPE struct termio 39321308Sache# define DRAIN_OUTPUT(fd) 39421308Sache# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop)) 39575406Sache# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop)) 39621308Sache#endif /* !TERMIOS_TTY_DRIVER */ 39721308Sache 39821308Sachestatic TIOTYPE otio; 39921308Sache 400119610Sachestatic void save_tty_chars PARAMS((TIOTYPE *)); 401119610Sachestatic int _get_tty_settings PARAMS((int, TIOTYPE *)); 402119610Sachestatic int get_tty_settings PARAMS((int, TIOTYPE *)); 403119610Sachestatic int _set_tty_settings PARAMS((int, TIOTYPE *)); 404119610Sachestatic int set_tty_settings PARAMS((int, TIOTYPE *)); 405119610Sache 406119610Sachestatic void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); 407119610Sache 408136644Sachestatic void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t)); 409136644Sachestatic void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE)); 410136644Sache 41121308Sache#if defined (FLUSHO) 41221308Sache# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) 41321308Sache#else 41421308Sache# define OUTPUT_BEING_FLUSHED(tp) 0 41521308Sache#endif 41621308Sache 41721308Sachestatic void 41858310Sachesave_tty_chars (tiop) 41958310Sache TIOTYPE *tiop; 42058310Sache{ 42158310Sache _rl_last_tty_chars = _rl_tty_chars; 42258310Sache 42358310Sache _rl_tty_chars.t_eof = tiop->c_cc[VEOF]; 42458310Sache _rl_tty_chars.t_eol = tiop->c_cc[VEOL]; 42558310Sache#ifdef VEOL2 42658310Sache _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2]; 42758310Sache#endif 42858310Sache _rl_tty_chars.t_erase = tiop->c_cc[VERASE]; 42958310Sache#ifdef VWERASE 43058310Sache _rl_tty_chars.t_werase = tiop->c_cc[VWERASE]; 43158310Sache#endif 43258310Sache _rl_tty_chars.t_kill = tiop->c_cc[VKILL]; 43358310Sache#ifdef VREPRINT 43458310Sache _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT]; 43558310Sache#endif 43658310Sache _rl_tty_chars.t_intr = tiop->c_cc[VINTR]; 43758310Sache _rl_tty_chars.t_quit = tiop->c_cc[VQUIT]; 43858310Sache#ifdef VSUSP 43958310Sache _rl_tty_chars.t_susp = tiop->c_cc[VSUSP]; 44058310Sache#endif 44158310Sache#ifdef VDSUSP 44258310Sache _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP]; 44358310Sache#endif 44458310Sache#ifdef VSTART 44558310Sache _rl_tty_chars.t_start = tiop->c_cc[VSTART]; 44658310Sache#endif 44758310Sache#ifdef VSTOP 44858310Sache _rl_tty_chars.t_stop = tiop->c_cc[VSTOP]; 44958310Sache#endif 45058310Sache#ifdef VLNEXT 45158310Sache _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT]; 45258310Sache#endif 45358310Sache#ifdef VDISCARD 45458310Sache _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD]; 45558310Sache#endif 45658310Sache#ifdef VSTATUS 45758310Sache _rl_tty_chars.t_status = tiop->c_cc[VSTATUS]; 45858310Sache#endif 45958310Sache} 46058310Sache 46158310Sache#if defined (_AIX) || defined (_AIX41) 46258310Sache/* Currently this is only used on AIX */ 46358310Sachestatic void 46421308Sacherltty_warning (msg) 46521308Sache char *msg; 46621308Sache{ 46721308Sache fprintf (stderr, "readline: warning: %s\n", msg); 46821308Sache} 46958310Sache#endif 47021308Sache 47121308Sache#if defined (_AIX) 47221308Sachevoid 47321308Sachesetopost(tp) 47421308SacheTIOTYPE *tp; 47521308Sache{ 47621308Sache if ((tp->c_oflag & OPOST) == 0) 47721308Sache { 47821308Sache rltty_warning ("turning on OPOST for terminal\r"); 47921308Sache tp->c_oflag |= OPOST|ONLCR; 48021308Sache } 48121308Sache} 48221308Sache#endif 48321308Sache 48421308Sachestatic int 48558310Sache_get_tty_settings (tty, tiop) 48621308Sache int tty; 48721308Sache TIOTYPE *tiop; 48821308Sache{ 48921308Sache int ioctl_ret; 49047558Sache 49121308Sache while (1) 49221308Sache { 49321308Sache ioctl_ret = GETATTR (tty, tiop); 49421308Sache if (ioctl_ret < 0) 49521308Sache { 49621308Sache if (errno != EINTR) 49721308Sache return -1; 49821308Sache else 49921308Sache continue; 50021308Sache } 50121308Sache if (OUTPUT_BEING_FLUSHED (tiop)) 50221308Sache { 50321308Sache#if defined (FLUSHO) && defined (_AIX41) 50421308Sache rltty_warning ("turning off output flushing"); 50521308Sache tiop->c_lflag &= ~FLUSHO; 50621308Sache break; 50721308Sache#else 50821308Sache continue; 50921308Sache#endif 51021308Sache } 51121308Sache break; 51221308Sache } 51321308Sache 51458310Sache return 0; 51558310Sache} 51658310Sache 51758310Sachestatic int 51858310Sacheget_tty_settings (tty, tiop) 51958310Sache int tty; 52058310Sache TIOTYPE *tiop; 52158310Sache{ 52258310Sache set_winsize (tty); 52358310Sache 524157184Sache errno = 0; 52558310Sache if (_get_tty_settings (tty, tiop) < 0) 52658310Sache return -1; 52758310Sache 52821308Sache#if defined (_AIX) 52921308Sache setopost(tiop); 53021308Sache#endif 53121308Sache 53221308Sache return 0; 53321308Sache} 53421308Sache 53521308Sachestatic int 53658310Sache_set_tty_settings (tty, tiop) 53721308Sache int tty; 53821308Sache TIOTYPE *tiop; 53921308Sache{ 54021308Sache while (SETATTR (tty, tiop) < 0) 54121308Sache { 54221308Sache if (errno != EINTR) 54321308Sache return -1; 54421308Sache errno = 0; 54521308Sache } 54658310Sache return 0; 54758310Sache} 54821308Sache 54958310Sachestatic int 55058310Sacheset_tty_settings (tty, tiop) 55158310Sache int tty; 55258310Sache TIOTYPE *tiop; 55358310Sache{ 55458310Sache if (_set_tty_settings (tty, tiop) < 0) 55558310Sache return -1; 55658310Sache 55721308Sache#if 0 55821308Sache 55921308Sache#if defined (TERMIOS_TTY_DRIVER) 56021308Sache# if defined (__ksr1__) 56121308Sache if (ksrflow) 56221308Sache { 56321308Sache ksrflow = 0; 56421308Sache tcflow (tty, TCOON); 56521308Sache } 56621308Sache# else /* !ksr1 */ 56721308Sache tcflow (tty, TCOON); /* Simulate a ^Q. */ 56821308Sache# endif /* !ksr1 */ 56921308Sache#else 57021308Sache ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */ 57121308Sache#endif /* !TERMIOS_TTY_DRIVER */ 57221308Sache 57358310Sache#endif /* 0 */ 57421308Sache 57521308Sache return 0; 57621308Sache} 57721308Sache 57821308Sachestatic void 57975406Sacheprepare_terminal_settings (meta_flag, oldtio, tiop) 58021308Sache int meta_flag; 58175406Sache TIOTYPE oldtio, *tiop; 58221308Sache{ 58375406Sache readline_echoing_p = (oldtio.c_lflag & ECHO); 58421308Sache 58521308Sache tiop->c_lflag &= ~(ICANON | ECHO); 58621308Sache 58775406Sache if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE) 58875406Sache _rl_eof_char = oldtio.c_cc[VEOF]; 58921308Sache 59021308Sache#if defined (USE_XON_XOFF) 59121308Sache#if defined (IXANY) 59221308Sache tiop->c_iflag &= ~(IXON | IXOFF | IXANY); 59321308Sache#else 59421308Sache /* `strict' Posix systems do not define IXANY. */ 59521308Sache tiop->c_iflag &= ~(IXON | IXOFF); 59621308Sache#endif /* IXANY */ 59721308Sache#endif /* USE_XON_XOFF */ 59821308Sache 59921308Sache /* Only turn this off if we are using all 8 bits. */ 60021308Sache if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag) 60121308Sache tiop->c_iflag &= ~(ISTRIP | INPCK); 60221308Sache 60321308Sache /* Make sure we differentiate between CR and NL on input. */ 60421308Sache tiop->c_iflag &= ~(ICRNL | INLCR); 60521308Sache 60621308Sache#if !defined (HANDLE_SIGNALS) 60721308Sache tiop->c_lflag &= ~ISIG; 60821308Sache#else 60921308Sache tiop->c_lflag |= ISIG; 61021308Sache#endif 61121308Sache 61221308Sache tiop->c_cc[VMIN] = 1; 61321308Sache tiop->c_cc[VTIME] = 0; 61421308Sache 61521308Sache#if defined (FLUSHO) 61621308Sache if (OUTPUT_BEING_FLUSHED (tiop)) 61721308Sache { 61821308Sache tiop->c_lflag &= ~FLUSHO; 61975406Sache oldtio.c_lflag &= ~FLUSHO; 62021308Sache } 62121308Sache#endif 62221308Sache 62321308Sache /* Turn off characters that we need on Posix systems with job control, 62421308Sache just to be sure. This includes ^Y and ^V. This should not really 62521308Sache be necessary. */ 62621308Sache#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE) 62721308Sache 62821308Sache#if defined (VLNEXT) 62921308Sache tiop->c_cc[VLNEXT] = _POSIX_VDISABLE; 63021308Sache#endif 63121308Sache 63221308Sache#if defined (VDSUSP) 63321308Sache tiop->c_cc[VDSUSP] = _POSIX_VDISABLE; 63421308Sache#endif 63521308Sache 63621308Sache#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */ 63721308Sache} 638157184Sache#endif /* !NEW_TTY_DRIVER */ 63921308Sache 64021308Sache/* Put the terminal in CBREAK mode so that we can detect key presses. */ 641157184Sache#if defined (NO_TTY_DRIVER) 64221308Sachevoid 64321308Sacherl_prep_terminal (meta_flag) 64421308Sache int meta_flag; 64521308Sache{ 646157184Sache readline_echoing_p = 1; 647157184Sache} 648157184Sache 649157184Sachevoid 650157184Sacherl_deprep_terminal () 651157184Sache{ 652157184Sache} 653157184Sache 654157184Sache#else /* ! NO_TTY_DRIVER */ 655157184Sachevoid 656157184Sacherl_prep_terminal (meta_flag) 657157184Sache int meta_flag; 658157184Sache{ 65921308Sache int tty; 66021308Sache TIOTYPE tio; 66121308Sache 66221308Sache if (terminal_prepped) 66321308Sache return; 66421308Sache 66521308Sache /* Try to keep this function from being INTerrupted. */ 66621308Sache block_sigint (); 66721308Sache 66821308Sache tty = fileno (rl_instream); 66921308Sache 67021308Sache if (get_tty_settings (tty, &tio) < 0) 67121308Sache { 672157184Sache#if defined (ENOTSUP) 673157184Sache /* MacOS X, at least, lies about the value of errno if tcgetattr fails. */ 674157184Sache if (errno == ENOTTY || errno == ENOTSUP) 675157184Sache#else 676157184Sache if (errno == ENOTTY) 677157184Sache#endif 678157184Sache readline_echoing_p = 1; /* XXX */ 67921308Sache release_sigint (); 68021308Sache return; 68121308Sache } 68221308Sache 68321308Sache otio = tio; 68421308Sache 685157184Sache if (_rl_bind_stty_chars) 686157184Sache { 687157184Sache#if defined (VI_MODE) 688157184Sache /* If editing in vi mode, make sure we restore the bindings in the 689157184Sache insertion keymap no matter what keymap we ended up in. */ 690157184Sache if (rl_editing_mode == vi_mode) 691157184Sache rl_tty_unset_default_bindings (vi_insertion_keymap); 692157184Sache else 693157184Sache#endif 694157184Sache rl_tty_unset_default_bindings (_rl_keymap); 695157184Sache } 69658310Sache save_tty_chars (&otio); 697136644Sache RL_SETSTATE(RL_STATE_TTYCSAVED); 698157184Sache if (_rl_bind_stty_chars) 699157184Sache { 700157184Sache#if defined (VI_MODE) 701157184Sache /* If editing in vi mode, make sure we set the bindings in the 702157184Sache insertion keymap no matter what keymap we ended up in. */ 703157184Sache if (rl_editing_mode == vi_mode) 704157184Sache _rl_bind_tty_special_chars (vi_insertion_keymap, tio); 705157184Sache else 706157184Sache#endif 707157184Sache _rl_bind_tty_special_chars (_rl_keymap, tio); 708157184Sache } 70958310Sache 71021308Sache prepare_terminal_settings (meta_flag, otio, &tio); 71121308Sache 71221308Sache if (set_tty_settings (tty, &tio) < 0) 71321308Sache { 71421308Sache release_sigint (); 71521308Sache return; 71621308Sache } 71721308Sache 71821308Sache if (_rl_enable_keypad) 71921308Sache _rl_control_keypad (1); 72021308Sache 72121308Sache fflush (rl_outstream); 72221308Sache terminal_prepped = 1; 72375406Sache RL_SETSTATE(RL_STATE_TERMPREPPED); 72421308Sache 72521308Sache release_sigint (); 72621308Sache} 72721308Sache 72821308Sache/* Restore the terminal's normal settings and modes. */ 72921308Sachevoid 73021308Sacherl_deprep_terminal () 73121308Sache{ 73221308Sache int tty; 73321308Sache 73421308Sache if (!terminal_prepped) 73521308Sache return; 73621308Sache 73721308Sache /* Try to keep this function from being interrupted. */ 73821308Sache block_sigint (); 73921308Sache 74021308Sache tty = fileno (rl_instream); 74121308Sache 74221308Sache if (_rl_enable_keypad) 74321308Sache _rl_control_keypad (0); 74421308Sache 74521308Sache fflush (rl_outstream); 74621308Sache 74721308Sache if (set_tty_settings (tty, &otio) < 0) 74821308Sache { 74921308Sache release_sigint (); 75021308Sache return; 75121308Sache } 75221308Sache 75321308Sache terminal_prepped = 0; 75475406Sache RL_UNSETSTATE(RL_STATE_TERMPREPPED); 75521308Sache 75621308Sache release_sigint (); 75721308Sache} 758157184Sache#endif /* !NO_TTY_DRIVER */ 75921308Sache 76021308Sache/* **************************************************************** */ 76121308Sache/* */ 76221308Sache/* Bogus Flow Control */ 76321308Sache/* */ 76421308Sache/* **************************************************************** */ 76521308Sache 76621308Sacheint 76721308Sacherl_restart_output (count, key) 76821308Sache int count, key; 76921308Sache{ 770157184Sache#if defined (__MINGW32__) 771157184Sache return 0; 772157184Sache#else /* !__MING32__ */ 773157184Sache 77421308Sache int fildes = fileno (rl_outstream); 77521308Sache#if defined (TIOCSTART) 77621308Sache#if defined (apollo) 77721308Sache ioctl (&fildes, TIOCSTART, 0); 77821308Sache#else 77921308Sache ioctl (fildes, TIOCSTART, 0); 78021308Sache#endif /* apollo */ 78121308Sache 78221308Sache#else /* !TIOCSTART */ 78321308Sache# if defined (TERMIOS_TTY_DRIVER) 78421308Sache# if defined (__ksr1__) 78521308Sache if (ksrflow) 78621308Sache { 78721308Sache ksrflow = 0; 78821308Sache tcflow (fildes, TCOON); 78921308Sache } 79021308Sache# else /* !ksr1 */ 79121308Sache tcflow (fildes, TCOON); /* Simulate a ^Q. */ 79221308Sache# endif /* !ksr1 */ 79321308Sache# else /* !TERMIOS_TTY_DRIVER */ 79421308Sache# if defined (TCXONC) 79521308Sache ioctl (fildes, TCXONC, TCOON); 79621308Sache# endif /* TCXONC */ 79721308Sache# endif /* !TERMIOS_TTY_DRIVER */ 79821308Sache#endif /* !TIOCSTART */ 79921308Sache 80021308Sache return 0; 801157184Sache#endif /* !__MINGW32__ */ 80221308Sache} 80321308Sache 80421308Sacheint 80521308Sacherl_stop_output (count, key) 80621308Sache int count, key; 80721308Sache{ 808157184Sache#if defined (__MINGW32__) 809157184Sache return 0; 810157184Sache#else 811157184Sache 81221308Sache int fildes = fileno (rl_instream); 81321308Sache 81421308Sache#if defined (TIOCSTOP) 81521308Sache# if defined (apollo) 81621308Sache ioctl (&fildes, TIOCSTOP, 0); 81721308Sache# else 81821308Sache ioctl (fildes, TIOCSTOP, 0); 81921308Sache# endif /* apollo */ 82021308Sache#else /* !TIOCSTOP */ 82121308Sache# if defined (TERMIOS_TTY_DRIVER) 82221308Sache# if defined (__ksr1__) 82321308Sache ksrflow = 1; 82421308Sache# endif /* ksr1 */ 82521308Sache tcflow (fildes, TCOOFF); 82621308Sache# else 82721308Sache# if defined (TCXONC) 82821308Sache ioctl (fildes, TCXONC, TCOON); 82921308Sache# endif /* TCXONC */ 83021308Sache# endif /* !TERMIOS_TTY_DRIVER */ 83121308Sache#endif /* !TIOCSTOP */ 83221308Sache 83321308Sache return 0; 834157184Sache#endif /* !__MINGW32__ */ 83521308Sache} 83621308Sache 83721308Sache/* **************************************************************** */ 83821308Sache/* */ 83921308Sache/* Default Key Bindings */ 84021308Sache/* */ 84121308Sache/* **************************************************************** */ 84275406Sache 843157184Sache#if !defined (NO_TTY_DRIVER) 844136644Sache#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func) 845157184Sache#endif 846136644Sache 847157184Sache#if defined (NO_TTY_DRIVER) 848157184Sache 849157184Sache#define SET_SPECIAL(sc, func) 850157184Sache#define RESET_SPECIAL(c) 851157184Sache 852157184Sache#elif defined (NEW_TTY_DRIVER) 853136644Sachestatic void 854136644Sacheset_special_char (kmap, tiop, sc, func) 85521308Sache Keymap kmap; 856136644Sache TIOTYPE *tiop; 857136644Sache int sc; 858136644Sache rl_command_func_t *func; 85921308Sache{ 860136644Sache if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC) 861136644Sache kmap[(unsigned char)sc].function = func; 862136644Sache} 86321308Sache 864136644Sache#define RESET_SPECIAL(c) \ 865136644Sache if (c != -1 && kmap[(unsigned char)c].type == ISFUNC) 866136644Sache kmap[(unsigned char)c].function = rl_insert; 86721308Sache 868136644Sachestatic void 869136644Sache_rl_bind_tty_special_chars (kmap, ttybuff) 870136644Sache Keymap kmap; 871136644Sache TIOTYPE ttybuff; 872136644Sache{ 873136644Sache if (ttybuff.flags & SGTTY_SET) 87421308Sache { 875136644Sache SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout); 876136644Sache SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard); 877136644Sache } 87821308Sache 87921308Sache# if defined (TIOCGLTC) 880136644Sache if (ttybuff.flags & LTCHARS_SET) 881136644Sache { 882136644Sache SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout); 883136644Sache SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert); 884136644Sache } 88521308Sache# endif /* TIOCGLTC */ 886136644Sache} 88721308Sache 88821308Sache#else /* !NEW_TTY_DRIVER */ 889136644Sachestatic void 890136644Sacheset_special_char (kmap, tiop, sc, func) 891136644Sache Keymap kmap; 892136644Sache TIOTYPE *tiop; 893136644Sache int sc; 894136644Sache rl_command_func_t *func; 895136644Sache{ 896136644Sache unsigned char uc; 89721308Sache 898136644Sache uc = tiop->c_cc[sc]; 899136644Sache if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) 900136644Sache kmap[uc].function = func; 901136644Sache} 90221308Sache 903136644Sache/* used later */ 904136644Sache#define RESET_SPECIAL(uc) \ 905136644Sache if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \ 906136644Sache kmap[uc].function = rl_insert; 90721308Sache 908136644Sachestatic void 909136644Sache_rl_bind_tty_special_chars (kmap, ttybuff) 910136644Sache Keymap kmap; 911136644Sache TIOTYPE ttybuff; 912136644Sache{ 913136644Sache SET_SPECIAL (VERASE, rl_rubout); 914136644Sache SET_SPECIAL (VKILL, rl_unix_line_discard); 915136644Sache 91621308Sache# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER) 917136644Sache SET_SPECIAL (VLNEXT, rl_quoted_insert); 91821308Sache# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ 91921308Sache 92021308Sache# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) 921136644Sache SET_SPECIAL (VWERASE, rl_unix_word_rubout); 92221308Sache# endif /* VWERASE && TERMIOS_TTY_DRIVER */ 923136644Sache} 924136644Sache 92521308Sache#endif /* !NEW_TTY_DRIVER */ 926136644Sache 927136644Sache/* Set the system's default editing characters to their readline equivalents 928136644Sache in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */ 929136644Sachevoid 930136644Sacherltty_set_default_bindings (kmap) 931136644Sache Keymap kmap; 932136644Sache{ 933157184Sache#if !defined (NO_TTY_DRIVER) 934136644Sache TIOTYPE ttybuff; 935136644Sache int tty; 936136644Sache 937136644Sache tty = fileno (rl_instream); 938136644Sache 939136644Sache if (get_tty_settings (tty, &ttybuff) == 0) 940136644Sache _rl_bind_tty_special_chars (kmap, ttybuff); 941157184Sache#endif 94221308Sache} 94358310Sache 94475406Sache/* New public way to set the system default editing chars to their readline 94575406Sache equivalents. */ 94675406Sachevoid 94775406Sacherl_tty_set_default_bindings (kmap) 94875406Sache Keymap kmap; 94975406Sache{ 95075406Sache rltty_set_default_bindings (kmap); 95175406Sache} 95275406Sache 953136644Sache/* Rebind all of the tty special chars that readline worries about back 954136644Sache to self-insert. Call this before saving the current terminal special 955136644Sache chars with save_tty_chars(). This only works on POSIX termios or termio 956136644Sache systems. */ 957136644Sachevoid 958136644Sacherl_tty_unset_default_bindings (kmap) 959136644Sache Keymap kmap; 960136644Sache{ 961136644Sache /* Don't bother before we've saved the tty special chars at least once. */ 962136644Sache if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0) 963136644Sache return; 964136644Sache 965136644Sache RESET_SPECIAL (_rl_tty_chars.t_erase); 966136644Sache RESET_SPECIAL (_rl_tty_chars.t_kill); 967136644Sache 968136644Sache# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER) 969136644Sache RESET_SPECIAL (_rl_tty_chars.t_lnext); 970136644Sache# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ 971136644Sache 972136644Sache# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) 973136644Sache RESET_SPECIAL (_rl_tty_chars.t_werase); 974136644Sache# endif /* VWERASE && TERMIOS_TTY_DRIVER */ 975136644Sache} 976136644Sache 97758310Sache#if defined (HANDLE_SIGNALS) 97858310Sache 979157184Sache#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER) 98058310Sacheint 98158310Sache_rl_disable_tty_signals () 98258310Sache{ 98358310Sache return 0; 98458310Sache} 98558310Sache 98658310Sacheint 98758310Sache_rl_restore_tty_signals () 98858310Sache{ 98958310Sache return 0; 99058310Sache} 99158310Sache#else 99258310Sache 99358310Sachestatic TIOTYPE sigstty, nosigstty; 99458310Sachestatic int tty_sigs_disabled = 0; 99558310Sache 99658310Sacheint 99758310Sache_rl_disable_tty_signals () 99858310Sache{ 99958310Sache if (tty_sigs_disabled) 100058310Sache return 0; 100158310Sache 100258310Sache if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0) 100358310Sache return -1; 100458310Sache 100558310Sache nosigstty = sigstty; 100658310Sache 100758310Sache nosigstty.c_lflag &= ~ISIG; 1008119610Sache nosigstty.c_iflag &= ~IXON; 100958310Sache 101058310Sache if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0) 101158310Sache return (_set_tty_settings (fileno (rl_instream), &sigstty)); 101258310Sache 101358310Sache tty_sigs_disabled = 1; 101458310Sache return 0; 101558310Sache} 101658310Sache 101758310Sacheint 101858310Sache_rl_restore_tty_signals () 101958310Sache{ 1020119610Sache int r; 1021119610Sache 102258310Sache if (tty_sigs_disabled == 0) 102358310Sache return 0; 102458310Sache 1025119610Sache r = _set_tty_settings (fileno (rl_instream), &sigstty); 1026119610Sache 1027119610Sache if (r == 0) 1028119610Sache tty_sigs_disabled = 0; 1029119610Sache 1030119610Sache return r; 103158310Sache} 103258310Sache#endif /* !NEW_TTY_DRIVER */ 103358310Sache 103458310Sache#endif /* HANDLE_SIGNALS */ 1035