rltty.c revision 119610
121308Sache/* rltty.c -- functions to prepare and restore the terminal for readline's 221308Sache use. */ 321308Sache 421308Sache/* Copyright (C) 1992 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 15521308Sache#if defined (NEW_TTY_DRIVER) 15621308Sache 15721308Sache/* Values for the `flags' field of a struct bsdtty. This tells which 15821308Sache elements of the struct bsdtty have been fetched from the system and 15921308Sache are valid. */ 16021308Sache#define SGTTY_SET 0x01 16121308Sache#define LFLAG_SET 0x02 16221308Sache#define TCHARS_SET 0x04 16321308Sache#define LTCHARS_SET 0x08 16421308Sache 16521308Sachestruct bsdtty { 16621308Sache struct sgttyb sgttyb; /* Basic BSD tty driver information. */ 16721308Sache int lflag; /* Local mode flags, like LPASS8. */ 16821308Sache#if defined (TIOCGETC) 16921308Sache struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */ 17021308Sache#endif 17121308Sache#if defined (TIOCGLTC) 17221308Sache struct ltchars ltchars; /* 4.2 BSD editing characters */ 17321308Sache#endif 17421308Sache int flags; /* Bitmap saying which parts of the struct are valid. */ 17521308Sache}; 17621308Sache 17721308Sache#define TIOTYPE struct bsdtty 17821308Sache 17921308Sachestatic TIOTYPE otio; 18021308Sache 181119610Sachestatic void save_tty_chars PARAMS((TIOTYPE *)); 182119610Sachestatic int _get_tty_settings PARAMS((int, TIOTYPE *)); 183119610Sachestatic int get_tty_settings PARAMS((int, TIOTYPE *)); 184119610Sachestatic int _set_tty_settings PARAMS((int, TIOTYPE *)); 185119610Sachestatic int set_tty_settings PARAMS((int, TIOTYPE *)); 186119610Sache 187119610Sachestatic void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); 188119610Sache 18958310Sachestatic void 19058310Sachesave_tty_chars (tiop) 19158310Sache TIOTYPE *tiop; 19258310Sache{ 19358310Sache _rl_last_tty_chars = _rl_tty_chars; 19458310Sache 19558310Sache if (tiop->flags & SGTTY_SET) 19658310Sache { 19758310Sache _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase; 19858310Sache _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill; 19958310Sache } 20058310Sache 20158310Sache if (tiop->flags & TCHARS_SET) 20258310Sache { 20358310Sache _rl_tty_chars.t_intr = tiop->tchars.t_intrc; 20458310Sache _rl_tty_chars.t_quit = tiop->tchars.t_quitc; 20558310Sache _rl_tty_chars.t_start = tiop->tchars.t_startc; 20675406Sache _rl_tty_chars.t_stop = tiop->tchars.t_stopc; 20758310Sache _rl_tty_chars.t_eof = tiop->tchars.t_eofc; 20858310Sache _rl_tty_chars.t_eol = '\n'; 20958310Sache _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc; 21058310Sache } 21158310Sache 21258310Sache if (tiop->flags & LTCHARS_SET) 21358310Sache { 21458310Sache _rl_tty_chars.t_susp = tiop->ltchars.t_suspc; 21558310Sache _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc; 21658310Sache _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc; 21758310Sache _rl_tty_chars.t_flush = tiop->ltchars.t_flushc; 21858310Sache _rl_tty_chars.t_werase = tiop->ltchars.t_werasc; 21958310Sache _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc; 22058310Sache } 22158310Sache 22258310Sache _rl_tty_chars.t_status = -1; 22358310Sache} 22458310Sache 22521308Sachestatic int 22621308Sacheget_tty_settings (tty, tiop) 22721308Sache int tty; 22821308Sache TIOTYPE *tiop; 22921308Sache{ 23021308Sache set_winsize (tty); 23121308Sache 23221308Sache tiop->flags = tiop->lflag = 0; 23321308Sache 23475406Sache if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0) 23575406Sache return -1; 23621308Sache tiop->flags |= SGTTY_SET; 23721308Sache 23821308Sache#if defined (TIOCLGET) 23975406Sache if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0) 24075406Sache tiop->flags |= LFLAG_SET; 24121308Sache#endif 24221308Sache 24321308Sache#if defined (TIOCGETC) 24475406Sache if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0) 24575406Sache tiop->flags |= TCHARS_SET; 24621308Sache#endif 24721308Sache 24821308Sache#if defined (TIOCGLTC) 24975406Sache if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0) 25075406Sache tiop->flags |= LTCHARS_SET; 25121308Sache#endif 25221308Sache 25321308Sache return 0; 25421308Sache} 25521308Sache 25621308Sachestatic int 25721308Sacheset_tty_settings (tty, tiop) 25821308Sache int tty; 25921308Sache TIOTYPE *tiop; 26021308Sache{ 26121308Sache if (tiop->flags & SGTTY_SET) 26221308Sache { 26321308Sache ioctl (tty, TIOCSETN, &(tiop->sgttyb)); 26421308Sache tiop->flags &= ~SGTTY_SET; 26521308Sache } 26621308Sache readline_echoing_p = 1; 26721308Sache 26821308Sache#if defined (TIOCLSET) 26921308Sache if (tiop->flags & LFLAG_SET) 27021308Sache { 27121308Sache ioctl (tty, TIOCLSET, &(tiop->lflag)); 27221308Sache tiop->flags &= ~LFLAG_SET; 27321308Sache } 27421308Sache#endif 27521308Sache 27621308Sache#if defined (TIOCSETC) 27721308Sache if (tiop->flags & TCHARS_SET) 27821308Sache { 27921308Sache ioctl (tty, TIOCSETC, &(tiop->tchars)); 28021308Sache tiop->flags &= ~TCHARS_SET; 28121308Sache } 28221308Sache#endif 28321308Sache 28421308Sache#if defined (TIOCSLTC) 28521308Sache if (tiop->flags & LTCHARS_SET) 28621308Sache { 28721308Sache ioctl (tty, TIOCSLTC, &(tiop->ltchars)); 28821308Sache tiop->flags &= ~LTCHARS_SET; 28921308Sache } 29021308Sache#endif 29121308Sache 29221308Sache return 0; 29321308Sache} 29421308Sache 29521308Sachestatic void 29675406Sacheprepare_terminal_settings (meta_flag, oldtio, tiop) 29721308Sache int meta_flag; 29875406Sache TIOTYPE oldtio, *tiop; 29921308Sache{ 30075406Sache readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO); 30121308Sache 30221308Sache /* Copy the original settings to the structure we're going to use for 30321308Sache our settings. */ 30475406Sache tiop->sgttyb = oldtio.sgttyb; 30575406Sache tiop->lflag = oldtio.lflag; 30621308Sache#if defined (TIOCGETC) 30775406Sache tiop->tchars = oldtio.tchars; 30821308Sache#endif 30921308Sache#if defined (TIOCGLTC) 31075406Sache tiop->ltchars = oldtio.ltchars; 31121308Sache#endif 31275406Sache tiop->flags = oldtio.flags; 31321308Sache 31421308Sache /* First, the basic settings to put us into character-at-a-time, no-echo 31521308Sache input mode. */ 31621308Sache tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD); 31721308Sache tiop->sgttyb.sg_flags |= CBREAK; 31821308Sache 31921308Sache /* If this terminal doesn't care how the 8th bit is used, then we can 32021308Sache use it for the meta-key. If only one of even or odd parity is 32121308Sache specified, then the terminal is using parity, and we cannot. */ 32221308Sache#if !defined (ANYP) 32321308Sache# define ANYP (EVENP | ODDP) 32421308Sache#endif 32575406Sache if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) || 32675406Sache ((oldtio.sgttyb.sg_flags & ANYP) == 0)) 32721308Sache { 32821308Sache tiop->sgttyb.sg_flags |= ANYP; 32921308Sache 33021308Sache /* Hack on local mode flags if we can. */ 33121308Sache#if defined (TIOCLGET) 33221308Sache# if defined (LPASS8) 33321308Sache tiop->lflag |= LPASS8; 33421308Sache# endif /* LPASS8 */ 33521308Sache#endif /* TIOCLGET */ 33621308Sache } 33721308Sache 33821308Sache#if defined (TIOCGETC) 33921308Sache# if defined (USE_XON_XOFF) 34021308Sache /* Get rid of terminal output start and stop characters. */ 34121308Sache tiop->tchars.t_stopc = -1; /* C-s */ 34221308Sache tiop->tchars.t_startc = -1; /* C-q */ 34321308Sache 34421308Sache /* If there is an XON character, bind it to restart the output. */ 34575406Sache if (oldtio.tchars.t_startc != -1) 34675406Sache rl_bind_key (oldtio.tchars.t_startc, rl_restart_output); 34721308Sache# endif /* USE_XON_XOFF */ 34821308Sache 34921308Sache /* If there is an EOF char, bind _rl_eof_char to it. */ 35075406Sache if (oldtio.tchars.t_eofc != -1) 35175406Sache _rl_eof_char = oldtio.tchars.t_eofc; 35221308Sache 35321308Sache# if defined (NO_KILL_INTR) 35421308Sache /* Get rid of terminal-generated SIGQUIT and SIGINT. */ 35521308Sache tiop->tchars.t_quitc = -1; /* C-\ */ 35621308Sache tiop->tchars.t_intrc = -1; /* C-c */ 35721308Sache# endif /* NO_KILL_INTR */ 35821308Sache#endif /* TIOCGETC */ 35921308Sache 36021308Sache#if defined (TIOCGLTC) 36121308Sache /* Make the interrupt keys go away. Just enough to make people happy. */ 36221308Sache tiop->ltchars.t_dsuspc = -1; /* C-y */ 36321308Sache tiop->ltchars.t_lnextc = -1; /* C-v */ 36421308Sache#endif /* TIOCGLTC */ 36521308Sache} 36621308Sache 36721308Sache#else /* !defined (NEW_TTY_DRIVER) */ 36821308Sache 36921308Sache#if !defined (VMIN) 37021308Sache# define VMIN VEOF 37121308Sache#endif 37221308Sache 37321308Sache#if !defined (VTIME) 37421308Sache# define VTIME VEOL 37521308Sache#endif 37621308Sache 37721308Sache#if defined (TERMIOS_TTY_DRIVER) 37821308Sache# define TIOTYPE struct termios 37921308Sache# define DRAIN_OUTPUT(fd) tcdrain (fd) 38021308Sache# define GETATTR(tty, tiop) (tcgetattr (tty, tiop)) 38121308Sache# ifdef M_UNIX 38221308Sache# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop)) 38321308Sache# else 38421308Sache# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop)) 38521308Sache# endif /* !M_UNIX */ 38621308Sache#else 38721308Sache# define TIOTYPE struct termio 38821308Sache# define DRAIN_OUTPUT(fd) 38921308Sache# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop)) 39075406Sache# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop)) 39121308Sache#endif /* !TERMIOS_TTY_DRIVER */ 39221308Sache 39321308Sachestatic TIOTYPE otio; 39421308Sache 395119610Sachestatic void save_tty_chars PARAMS((TIOTYPE *)); 396119610Sachestatic int _get_tty_settings PARAMS((int, TIOTYPE *)); 397119610Sachestatic int get_tty_settings PARAMS((int, TIOTYPE *)); 398119610Sachestatic int _set_tty_settings PARAMS((int, TIOTYPE *)); 399119610Sachestatic int set_tty_settings PARAMS((int, TIOTYPE *)); 400119610Sache 401119610Sachestatic void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); 402119610Sache 40321308Sache#if defined (FLUSHO) 40421308Sache# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) 40521308Sache#else 40621308Sache# define OUTPUT_BEING_FLUSHED(tp) 0 40721308Sache#endif 40821308Sache 40921308Sachestatic void 41058310Sachesave_tty_chars (tiop) 41158310Sache TIOTYPE *tiop; 41258310Sache{ 41358310Sache _rl_last_tty_chars = _rl_tty_chars; 41458310Sache 41558310Sache _rl_tty_chars.t_eof = tiop->c_cc[VEOF]; 41658310Sache _rl_tty_chars.t_eol = tiop->c_cc[VEOL]; 41758310Sache#ifdef VEOL2 41858310Sache _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2]; 41958310Sache#endif 42058310Sache _rl_tty_chars.t_erase = tiop->c_cc[VERASE]; 42158310Sache#ifdef VWERASE 42258310Sache _rl_tty_chars.t_werase = tiop->c_cc[VWERASE]; 42358310Sache#endif 42458310Sache _rl_tty_chars.t_kill = tiop->c_cc[VKILL]; 42558310Sache#ifdef VREPRINT 42658310Sache _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT]; 42758310Sache#endif 42858310Sache _rl_tty_chars.t_intr = tiop->c_cc[VINTR]; 42958310Sache _rl_tty_chars.t_quit = tiop->c_cc[VQUIT]; 43058310Sache#ifdef VSUSP 43158310Sache _rl_tty_chars.t_susp = tiop->c_cc[VSUSP]; 43258310Sache#endif 43358310Sache#ifdef VDSUSP 43458310Sache _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP]; 43558310Sache#endif 43658310Sache#ifdef VSTART 43758310Sache _rl_tty_chars.t_start = tiop->c_cc[VSTART]; 43858310Sache#endif 43958310Sache#ifdef VSTOP 44058310Sache _rl_tty_chars.t_stop = tiop->c_cc[VSTOP]; 44158310Sache#endif 44258310Sache#ifdef VLNEXT 44358310Sache _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT]; 44458310Sache#endif 44558310Sache#ifdef VDISCARD 44658310Sache _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD]; 44758310Sache#endif 44858310Sache#ifdef VSTATUS 44958310Sache _rl_tty_chars.t_status = tiop->c_cc[VSTATUS]; 45058310Sache#endif 45158310Sache} 45258310Sache 45358310Sache#if defined (_AIX) || defined (_AIX41) 45458310Sache/* Currently this is only used on AIX */ 45558310Sachestatic void 45621308Sacherltty_warning (msg) 45721308Sache char *msg; 45821308Sache{ 45921308Sache fprintf (stderr, "readline: warning: %s\n", msg); 46021308Sache} 46158310Sache#endif 46221308Sache 46321308Sache#if defined (_AIX) 46421308Sachevoid 46521308Sachesetopost(tp) 46621308SacheTIOTYPE *tp; 46721308Sache{ 46821308Sache if ((tp->c_oflag & OPOST) == 0) 46921308Sache { 47021308Sache rltty_warning ("turning on OPOST for terminal\r"); 47121308Sache tp->c_oflag |= OPOST|ONLCR; 47221308Sache } 47321308Sache} 47421308Sache#endif 47521308Sache 47621308Sachestatic int 47758310Sache_get_tty_settings (tty, tiop) 47821308Sache int tty; 47921308Sache TIOTYPE *tiop; 48021308Sache{ 48121308Sache int ioctl_ret; 48247558Sache 48321308Sache while (1) 48421308Sache { 48521308Sache ioctl_ret = GETATTR (tty, tiop); 48621308Sache if (ioctl_ret < 0) 48721308Sache { 48821308Sache if (errno != EINTR) 48921308Sache return -1; 49021308Sache else 49121308Sache continue; 49221308Sache } 49321308Sache if (OUTPUT_BEING_FLUSHED (tiop)) 49421308Sache { 49521308Sache#if defined (FLUSHO) && defined (_AIX41) 49621308Sache rltty_warning ("turning off output flushing"); 49721308Sache tiop->c_lflag &= ~FLUSHO; 49821308Sache break; 49921308Sache#else 50021308Sache continue; 50121308Sache#endif 50221308Sache } 50321308Sache break; 50421308Sache } 50521308Sache 50658310Sache return 0; 50758310Sache} 50858310Sache 50958310Sachestatic int 51058310Sacheget_tty_settings (tty, tiop) 51158310Sache int tty; 51258310Sache TIOTYPE *tiop; 51358310Sache{ 51458310Sache set_winsize (tty); 51558310Sache 51658310Sache if (_get_tty_settings (tty, tiop) < 0) 51758310Sache return -1; 51858310Sache 51921308Sache#if defined (_AIX) 52021308Sache setopost(tiop); 52121308Sache#endif 52221308Sache 52321308Sache return 0; 52421308Sache} 52521308Sache 52621308Sachestatic int 52758310Sache_set_tty_settings (tty, tiop) 52821308Sache int tty; 52921308Sache TIOTYPE *tiop; 53021308Sache{ 53121308Sache while (SETATTR (tty, tiop) < 0) 53221308Sache { 53321308Sache if (errno != EINTR) 53421308Sache return -1; 53521308Sache errno = 0; 53621308Sache } 53758310Sache return 0; 53858310Sache} 53921308Sache 54058310Sachestatic int 54158310Sacheset_tty_settings (tty, tiop) 54258310Sache int tty; 54358310Sache TIOTYPE *tiop; 54458310Sache{ 54558310Sache if (_set_tty_settings (tty, tiop) < 0) 54658310Sache return -1; 54758310Sache 54821308Sache#if 0 54921308Sache 55021308Sache#if defined (TERMIOS_TTY_DRIVER) 55121308Sache# if defined (__ksr1__) 55221308Sache if (ksrflow) 55321308Sache { 55421308Sache ksrflow = 0; 55521308Sache tcflow (tty, TCOON); 55621308Sache } 55721308Sache# else /* !ksr1 */ 55821308Sache tcflow (tty, TCOON); /* Simulate a ^Q. */ 55921308Sache# endif /* !ksr1 */ 56021308Sache#else 56121308Sache ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */ 56221308Sache#endif /* !TERMIOS_TTY_DRIVER */ 56321308Sache 56458310Sache#endif /* 0 */ 56521308Sache 56621308Sache return 0; 56721308Sache} 56821308Sache 56921308Sachestatic void 57075406Sacheprepare_terminal_settings (meta_flag, oldtio, tiop) 57121308Sache int meta_flag; 57275406Sache TIOTYPE oldtio, *tiop; 57321308Sache{ 57475406Sache readline_echoing_p = (oldtio.c_lflag & ECHO); 57521308Sache 57621308Sache tiop->c_lflag &= ~(ICANON | ECHO); 57721308Sache 57875406Sache if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE) 57975406Sache _rl_eof_char = oldtio.c_cc[VEOF]; 58021308Sache 58121308Sache#if defined (USE_XON_XOFF) 58221308Sache#if defined (IXANY) 58321308Sache tiop->c_iflag &= ~(IXON | IXOFF | IXANY); 58421308Sache#else 58521308Sache /* `strict' Posix systems do not define IXANY. */ 58621308Sache tiop->c_iflag &= ~(IXON | IXOFF); 58721308Sache#endif /* IXANY */ 58821308Sache#endif /* USE_XON_XOFF */ 58921308Sache 59021308Sache /* Only turn this off if we are using all 8 bits. */ 59121308Sache if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag) 59221308Sache tiop->c_iflag &= ~(ISTRIP | INPCK); 59321308Sache 59421308Sache /* Make sure we differentiate between CR and NL on input. */ 59521308Sache tiop->c_iflag &= ~(ICRNL | INLCR); 59621308Sache 59721308Sache#if !defined (HANDLE_SIGNALS) 59821308Sache tiop->c_lflag &= ~ISIG; 59921308Sache#else 60021308Sache tiop->c_lflag |= ISIG; 60121308Sache#endif 60221308Sache 60321308Sache tiop->c_cc[VMIN] = 1; 60421308Sache tiop->c_cc[VTIME] = 0; 60521308Sache 60621308Sache#if defined (FLUSHO) 60721308Sache if (OUTPUT_BEING_FLUSHED (tiop)) 60821308Sache { 60921308Sache tiop->c_lflag &= ~FLUSHO; 61075406Sache oldtio.c_lflag &= ~FLUSHO; 61121308Sache } 61221308Sache#endif 61321308Sache 61421308Sache /* Turn off characters that we need on Posix systems with job control, 61521308Sache just to be sure. This includes ^Y and ^V. This should not really 61621308Sache be necessary. */ 61721308Sache#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE) 61821308Sache 61921308Sache#if defined (VLNEXT) 62021308Sache tiop->c_cc[VLNEXT] = _POSIX_VDISABLE; 62121308Sache#endif 62221308Sache 62321308Sache#if defined (VDSUSP) 62421308Sache tiop->c_cc[VDSUSP] = _POSIX_VDISABLE; 62521308Sache#endif 62621308Sache 62721308Sache#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */ 62821308Sache} 62921308Sache#endif /* NEW_TTY_DRIVER */ 63021308Sache 63121308Sache/* Put the terminal in CBREAK mode so that we can detect key presses. */ 63221308Sachevoid 63321308Sacherl_prep_terminal (meta_flag) 63421308Sache int meta_flag; 63521308Sache{ 63621308Sache int tty; 63721308Sache TIOTYPE tio; 63821308Sache 63921308Sache if (terminal_prepped) 64021308Sache return; 64121308Sache 64221308Sache /* Try to keep this function from being INTerrupted. */ 64321308Sache block_sigint (); 64421308Sache 64521308Sache tty = fileno (rl_instream); 64621308Sache 64721308Sache if (get_tty_settings (tty, &tio) < 0) 64821308Sache { 64921308Sache release_sigint (); 65021308Sache return; 65121308Sache } 65221308Sache 65321308Sache otio = tio; 65421308Sache 65558310Sache save_tty_chars (&otio); 65658310Sache 65721308Sache prepare_terminal_settings (meta_flag, otio, &tio); 65821308Sache 65921308Sache if (set_tty_settings (tty, &tio) < 0) 66021308Sache { 66121308Sache release_sigint (); 66221308Sache return; 66321308Sache } 66421308Sache 66521308Sache if (_rl_enable_keypad) 66621308Sache _rl_control_keypad (1); 66721308Sache 66821308Sache fflush (rl_outstream); 66921308Sache terminal_prepped = 1; 67075406Sache RL_SETSTATE(RL_STATE_TERMPREPPED); 67121308Sache 67221308Sache release_sigint (); 67321308Sache} 67421308Sache 67521308Sache/* Restore the terminal's normal settings and modes. */ 67621308Sachevoid 67721308Sacherl_deprep_terminal () 67821308Sache{ 67921308Sache int tty; 68021308Sache 68121308Sache if (!terminal_prepped) 68221308Sache return; 68321308Sache 68421308Sache /* Try to keep this function from being interrupted. */ 68521308Sache block_sigint (); 68621308Sache 68721308Sache tty = fileno (rl_instream); 68821308Sache 68921308Sache if (_rl_enable_keypad) 69021308Sache _rl_control_keypad (0); 69121308Sache 69221308Sache fflush (rl_outstream); 69321308Sache 69421308Sache if (set_tty_settings (tty, &otio) < 0) 69521308Sache { 69621308Sache release_sigint (); 69721308Sache return; 69821308Sache } 69921308Sache 70021308Sache terminal_prepped = 0; 70175406Sache RL_UNSETSTATE(RL_STATE_TERMPREPPED); 70221308Sache 70321308Sache release_sigint (); 70421308Sache} 70521308Sache 70621308Sache/* **************************************************************** */ 70721308Sache/* */ 70821308Sache/* Bogus Flow Control */ 70921308Sache/* */ 71021308Sache/* **************************************************************** */ 71121308Sache 71221308Sacheint 71321308Sacherl_restart_output (count, key) 71421308Sache int count, key; 71521308Sache{ 71621308Sache int fildes = fileno (rl_outstream); 71721308Sache#if defined (TIOCSTART) 71821308Sache#if defined (apollo) 71921308Sache ioctl (&fildes, TIOCSTART, 0); 72021308Sache#else 72121308Sache ioctl (fildes, TIOCSTART, 0); 72221308Sache#endif /* apollo */ 72321308Sache 72421308Sache#else /* !TIOCSTART */ 72521308Sache# if defined (TERMIOS_TTY_DRIVER) 72621308Sache# if defined (__ksr1__) 72721308Sache if (ksrflow) 72821308Sache { 72921308Sache ksrflow = 0; 73021308Sache tcflow (fildes, TCOON); 73121308Sache } 73221308Sache# else /* !ksr1 */ 73321308Sache tcflow (fildes, TCOON); /* Simulate a ^Q. */ 73421308Sache# endif /* !ksr1 */ 73521308Sache# else /* !TERMIOS_TTY_DRIVER */ 73621308Sache# if defined (TCXONC) 73721308Sache ioctl (fildes, TCXONC, TCOON); 73821308Sache# endif /* TCXONC */ 73921308Sache# endif /* !TERMIOS_TTY_DRIVER */ 74021308Sache#endif /* !TIOCSTART */ 74121308Sache 74221308Sache return 0; 74321308Sache} 74421308Sache 74521308Sacheint 74621308Sacherl_stop_output (count, key) 74721308Sache int count, key; 74821308Sache{ 74921308Sache int fildes = fileno (rl_instream); 75021308Sache 75121308Sache#if defined (TIOCSTOP) 75221308Sache# if defined (apollo) 75321308Sache ioctl (&fildes, TIOCSTOP, 0); 75421308Sache# else 75521308Sache ioctl (fildes, TIOCSTOP, 0); 75621308Sache# endif /* apollo */ 75721308Sache#else /* !TIOCSTOP */ 75821308Sache# if defined (TERMIOS_TTY_DRIVER) 75921308Sache# if defined (__ksr1__) 76021308Sache ksrflow = 1; 76121308Sache# endif /* ksr1 */ 76221308Sache tcflow (fildes, TCOOFF); 76321308Sache# else 76421308Sache# if defined (TCXONC) 76521308Sache ioctl (fildes, TCXONC, TCOON); 76621308Sache# endif /* TCXONC */ 76721308Sache# endif /* !TERMIOS_TTY_DRIVER */ 76821308Sache#endif /* !TIOCSTOP */ 76921308Sache 77021308Sache return 0; 77121308Sache} 77221308Sache 77321308Sache/* **************************************************************** */ 77421308Sache/* */ 77521308Sache/* Default Key Bindings */ 77621308Sache/* */ 77721308Sache/* **************************************************************** */ 77875406Sache 77975406Sache/* Set the system's default editing characters to their readline equivalents 78075406Sache in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */ 78121308Sachevoid 78221308Sacherltty_set_default_bindings (kmap) 78321308Sache Keymap kmap; 78421308Sache{ 78521308Sache TIOTYPE ttybuff; 78621308Sache int tty = fileno (rl_instream); 78721308Sache 78821308Sache#if defined (NEW_TTY_DRIVER) 78921308Sache 79021308Sache#define SET_SPECIAL(sc, func) \ 79121308Sache do \ 79221308Sache { \ 79321308Sache int ic; \ 79421308Sache ic = sc; \ 795119610Sache if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \ 796119610Sache kmap[(unsigned char)ic].function = func; \ 79721308Sache } \ 79821308Sache while (0) 79921308Sache 80021308Sache if (get_tty_settings (tty, &ttybuff) == 0) 80121308Sache { 80221308Sache if (ttybuff.flags & SGTTY_SET) 80321308Sache { 80421308Sache SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout); 80521308Sache SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard); 80621308Sache } 80721308Sache 80821308Sache# if defined (TIOCGLTC) 80921308Sache if (ttybuff.flags & LTCHARS_SET) 81021308Sache { 81121308Sache SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout); 81221308Sache SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert); 81321308Sache } 81421308Sache# endif /* TIOCGLTC */ 81521308Sache } 81621308Sache 81721308Sache#else /* !NEW_TTY_DRIVER */ 81821308Sache 81921308Sache#define SET_SPECIAL(sc, func) \ 82021308Sache do \ 82121308Sache { \ 82221308Sache unsigned char uc; \ 82321308Sache uc = ttybuff.c_cc[sc]; \ 82421308Sache if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \ 82521308Sache kmap[uc].function = func; \ 82621308Sache } \ 82721308Sache while (0) 82821308Sache 82921308Sache if (get_tty_settings (tty, &ttybuff) == 0) 83021308Sache { 83121308Sache SET_SPECIAL (VERASE, rl_rubout); 83221308Sache SET_SPECIAL (VKILL, rl_unix_line_discard); 83321308Sache 83421308Sache# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER) 83521308Sache SET_SPECIAL (VLNEXT, rl_quoted_insert); 83621308Sache# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ 83721308Sache 83821308Sache# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) 83921308Sache SET_SPECIAL (VWERASE, rl_unix_word_rubout); 84021308Sache# endif /* VWERASE && TERMIOS_TTY_DRIVER */ 84121308Sache } 84221308Sache#endif /* !NEW_TTY_DRIVER */ 84321308Sache} 84458310Sache 84575406Sache/* New public way to set the system default editing chars to their readline 84675406Sache equivalents. */ 84775406Sachevoid 84875406Sacherl_tty_set_default_bindings (kmap) 84975406Sache Keymap kmap; 85075406Sache{ 85175406Sache rltty_set_default_bindings (kmap); 85275406Sache} 85375406Sache 85458310Sache#if defined (HANDLE_SIGNALS) 85558310Sache 85658310Sache#if defined (NEW_TTY_DRIVER) 85758310Sacheint 85858310Sache_rl_disable_tty_signals () 85958310Sache{ 86058310Sache return 0; 86158310Sache} 86258310Sache 86358310Sacheint 86458310Sache_rl_restore_tty_signals () 86558310Sache{ 86658310Sache return 0; 86758310Sache} 86858310Sache#else 86958310Sache 87058310Sachestatic TIOTYPE sigstty, nosigstty; 87158310Sachestatic int tty_sigs_disabled = 0; 87258310Sache 87358310Sacheint 87458310Sache_rl_disable_tty_signals () 87558310Sache{ 87658310Sache if (tty_sigs_disabled) 87758310Sache return 0; 87858310Sache 87958310Sache if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0) 88058310Sache return -1; 88158310Sache 88258310Sache nosigstty = sigstty; 88358310Sache 88458310Sache nosigstty.c_lflag &= ~ISIG; 885119610Sache nosigstty.c_iflag &= ~IXON; 88658310Sache 88758310Sache if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0) 88858310Sache return (_set_tty_settings (fileno (rl_instream), &sigstty)); 88958310Sache 89058310Sache tty_sigs_disabled = 1; 89158310Sache return 0; 89258310Sache} 89358310Sache 89458310Sacheint 89558310Sache_rl_restore_tty_signals () 89658310Sache{ 897119610Sache int r; 898119610Sache 89958310Sache if (tty_sigs_disabled == 0) 90058310Sache return 0; 90158310Sache 902119610Sache r = _set_tty_settings (fileno (rl_instream), &sigstty); 903119610Sache 904119610Sache if (r == 0) 905119610Sache tty_sigs_disabled = 0; 906119610Sache 907119610Sache return r; 90858310Sache} 90958310Sache#endif /* !NEW_TTY_DRIVER */ 91058310Sache 91158310Sache#endif /* HANDLE_SIGNALS */ 912