1/* rltty.c -- functions to prepare and restore the terminal for readline's
2   use. */
3
4/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
5
6   This file is part of the GNU Readline Library, a library for
7   reading lines of text with interactive input and history editing.
8
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 2, or
12   (at your option) any later version.
13
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.
18
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   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23#define READLINE_LIBRARY
24
25#if defined (HAVE_CONFIG_H)
26#  include <config.h>
27#endif
28
29#include <sys/types.h>
30#include <signal.h>
31#include <errno.h>
32#include <stdio.h>
33
34#if defined (HAVE_UNISTD_H)
35#  include <unistd.h>
36#endif /* HAVE_UNISTD_H */
37
38#include "rldefs.h"
39
40#if defined (GWINSZ_IN_SYS_IOCTL)
41#  include <sys/ioctl.h>
42#endif /* GWINSZ_IN_SYS_IOCTL */
43
44#include "rltty.h"
45#include "readline.h"
46#include "rlprivate.h"
47
48#if !defined (errno)
49extern int errno;
50#endif /* !errno */
51
52rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
53rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
54
55static void block_sigint PARAMS((void));
56static void release_sigint PARAMS((void));
57
58static void set_winsize PARAMS((int));
59
60/* **************************************************************** */
61/*								    */
62/*			   Signal Management			    */
63/*								    */
64/* **************************************************************** */
65
66#if defined (HAVE_POSIX_SIGNALS)
67static sigset_t sigint_set, sigint_oset;
68#else /* !HAVE_POSIX_SIGNALS */
69#  if defined (HAVE_BSD_SIGNALS)
70static int sigint_oldmask;
71#  endif /* HAVE_BSD_SIGNALS */
72#endif /* !HAVE_POSIX_SIGNALS */
73
74static int sigint_blocked;
75
76/* Cause SIGINT to not be delivered until the corresponding call to
77   release_sigint(). */
78static void
79block_sigint ()
80{
81  if (sigint_blocked)
82    return;
83
84#if defined (HAVE_POSIX_SIGNALS)
85  sigemptyset (&sigint_set);
86  sigemptyset (&sigint_oset);
87  sigaddset (&sigint_set, SIGINT);
88  sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
89#else /* !HAVE_POSIX_SIGNALS */
90#  if defined (HAVE_BSD_SIGNALS)
91  sigint_oldmask = sigblock (sigmask (SIGINT));
92#  else /* !HAVE_BSD_SIGNALS */
93#    if defined (HAVE_USG_SIGHOLD)
94  sighold (SIGINT);
95#    endif /* HAVE_USG_SIGHOLD */
96#  endif /* !HAVE_BSD_SIGNALS */
97#endif /* !HAVE_POSIX_SIGNALS */
98
99  sigint_blocked = 1;
100}
101
102/* Allow SIGINT to be delivered. */
103static void
104release_sigint ()
105{
106  if (sigint_blocked == 0)
107    return;
108
109#if defined (HAVE_POSIX_SIGNALS)
110  sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
111#else
112#  if defined (HAVE_BSD_SIGNALS)
113  sigsetmask (sigint_oldmask);
114#  else /* !HAVE_BSD_SIGNALS */
115#    if defined (HAVE_USG_SIGHOLD)
116  sigrelse (SIGINT);
117#    endif /* HAVE_USG_SIGHOLD */
118#  endif /* !HAVE_BSD_SIGNALS */
119#endif /* !HAVE_POSIX_SIGNALS */
120
121  sigint_blocked = 0;
122}
123
124/* **************************************************************** */
125/*								    */
126/*		      Saving and Restoring the TTY	    	    */
127/*								    */
128/* **************************************************************** */
129
130/* Non-zero means that the terminal is in a prepped state. */
131static int terminal_prepped;
132
133static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
134
135/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
136   and output is suspended. */
137#if defined (__ksr1__)
138static int ksrflow;
139#endif
140
141/* Dummy call to force a backgrounded readline to stop before it tries
142   to get the tty settings. */
143static void
144set_winsize (tty)
145     int tty;
146{
147#if defined (TIOCGWINSZ)
148  struct winsize w;
149
150  if (ioctl (tty, TIOCGWINSZ, &w) == 0)
151      (void) ioctl (tty, TIOCSWINSZ, &w);
152#endif /* TIOCGWINSZ */
153}
154
155#if defined (NO_TTY_DRIVER)
156/* Nothing */
157#elif defined (NEW_TTY_DRIVER)
158
159/* Values for the `flags' field of a struct bsdtty.  This tells which
160   elements of the struct bsdtty have been fetched from the system and
161   are valid. */
162#define SGTTY_SET	0x01
163#define LFLAG_SET	0x02
164#define TCHARS_SET	0x04
165#define LTCHARS_SET	0x08
166
167struct bsdtty {
168  struct sgttyb sgttyb;	/* Basic BSD tty driver information. */
169  int lflag;		/* Local mode flags, like LPASS8. */
170#if defined (TIOCGETC)
171  struct tchars tchars;	/* Terminal special characters, including ^S and ^Q. */
172#endif
173#if defined (TIOCGLTC)
174  struct ltchars ltchars; /* 4.2 BSD editing characters */
175#endif
176  int flags;		/* Bitmap saying which parts of the struct are valid. */
177};
178
179#define TIOTYPE struct bsdtty
180
181static TIOTYPE otio;
182
183static void save_tty_chars PARAMS((TIOTYPE *));
184static int _get_tty_settings PARAMS((int, TIOTYPE *));
185static int get_tty_settings PARAMS((int, TIOTYPE *));
186static int _set_tty_settings PARAMS((int, TIOTYPE *));
187static int set_tty_settings PARAMS((int, TIOTYPE *));
188
189static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
190
191static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
192
193static void
194save_tty_chars (tiop)
195     TIOTYPE *tiop;
196{
197  _rl_last_tty_chars = _rl_tty_chars;
198
199  if (tiop->flags & SGTTY_SET)
200    {
201      _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
202      _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
203    }
204
205  if (tiop->flags & TCHARS_SET)
206    {
207      _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
208      _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
209      _rl_tty_chars.t_start = tiop->tchars.t_startc;
210      _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
211      _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
212      _rl_tty_chars.t_eol = '\n';
213      _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
214    }
215
216  if (tiop->flags & LTCHARS_SET)
217    {
218      _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
219      _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
220      _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
221      _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
222      _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
223      _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
224    }
225
226  _rl_tty_chars.t_status = -1;
227}
228
229static int
230get_tty_settings (tty, tiop)
231     int tty;
232     TIOTYPE *tiop;
233{
234  set_winsize (tty);
235
236  tiop->flags = tiop->lflag = 0;
237
238  errno = 0;
239  if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
240    return -1;
241  tiop->flags |= SGTTY_SET;
242
243#if defined (TIOCLGET)
244  if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
245    tiop->flags |= LFLAG_SET;
246#endif
247
248#if defined (TIOCGETC)
249  if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
250    tiop->flags |= TCHARS_SET;
251#endif
252
253#if defined (TIOCGLTC)
254  if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
255    tiop->flags |= LTCHARS_SET;
256#endif
257
258  return 0;
259}
260
261static int
262set_tty_settings (tty, tiop)
263     int tty;
264     TIOTYPE *tiop;
265{
266  if (tiop->flags & SGTTY_SET)
267    {
268      ioctl (tty, TIOCSETN, &(tiop->sgttyb));
269      tiop->flags &= ~SGTTY_SET;
270    }
271  readline_echoing_p = 1;
272
273#if defined (TIOCLSET)
274  if (tiop->flags & LFLAG_SET)
275    {
276      ioctl (tty, TIOCLSET, &(tiop->lflag));
277      tiop->flags &= ~LFLAG_SET;
278    }
279#endif
280
281#if defined (TIOCSETC)
282  if (tiop->flags & TCHARS_SET)
283    {
284      ioctl (tty, TIOCSETC, &(tiop->tchars));
285      tiop->flags &= ~TCHARS_SET;
286    }
287#endif
288
289#if defined (TIOCSLTC)
290  if (tiop->flags & LTCHARS_SET)
291    {
292      ioctl (tty, TIOCSLTC, &(tiop->ltchars));
293      tiop->flags &= ~LTCHARS_SET;
294    }
295#endif
296
297  return 0;
298}
299
300static void
301prepare_terminal_settings (meta_flag, oldtio, tiop)
302     int meta_flag;
303     TIOTYPE oldtio, *tiop;
304{
305  readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
306
307  /* Copy the original settings to the structure we're going to use for
308     our settings. */
309  tiop->sgttyb = oldtio.sgttyb;
310  tiop->lflag = oldtio.lflag;
311#if defined (TIOCGETC)
312  tiop->tchars = oldtio.tchars;
313#endif
314#if defined (TIOCGLTC)
315  tiop->ltchars = oldtio.ltchars;
316#endif
317  tiop->flags = oldtio.flags;
318
319  /* First, the basic settings to put us into character-at-a-time, no-echo
320     input mode. */
321  tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
322  tiop->sgttyb.sg_flags |= CBREAK;
323
324  /* If this terminal doesn't care how the 8th bit is used, then we can
325     use it for the meta-key.  If only one of even or odd parity is
326     specified, then the terminal is using parity, and we cannot. */
327#if !defined (ANYP)
328#  define ANYP (EVENP | ODDP)
329#endif
330  if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
331      ((oldtio.sgttyb.sg_flags & ANYP) == 0))
332    {
333      tiop->sgttyb.sg_flags |= ANYP;
334
335      /* Hack on local mode flags if we can. */
336#if defined (TIOCLGET)
337#  if defined (LPASS8)
338      tiop->lflag |= LPASS8;
339#  endif /* LPASS8 */
340#endif /* TIOCLGET */
341    }
342
343#if defined (TIOCGETC)
344#  if defined (USE_XON_XOFF)
345  /* Get rid of terminal output start and stop characters. */
346  tiop->tchars.t_stopc = -1; /* C-s */
347  tiop->tchars.t_startc = -1; /* C-q */
348
349  /* If there is an XON character, bind it to restart the output. */
350  if (oldtio.tchars.t_startc != -1)
351    rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
352#  endif /* USE_XON_XOFF */
353
354  /* If there is an EOF char, bind _rl_eof_char to it. */
355  if (oldtio.tchars.t_eofc != -1)
356    _rl_eof_char = oldtio.tchars.t_eofc;
357
358#  if defined (NO_KILL_INTR)
359  /* Get rid of terminal-generated SIGQUIT and SIGINT. */
360  tiop->tchars.t_quitc = -1; /* C-\ */
361  tiop->tchars.t_intrc = -1; /* C-c */
362#  endif /* NO_KILL_INTR */
363#endif /* TIOCGETC */
364
365#if defined (TIOCGLTC)
366  /* Make the interrupt keys go away.  Just enough to make people happy. */
367  tiop->ltchars.t_dsuspc = -1;	/* C-y */
368  tiop->ltchars.t_lnextc = -1;	/* C-v */
369#endif /* TIOCGLTC */
370}
371
372#else  /* !defined (NEW_TTY_DRIVER) */
373
374#if !defined (VMIN)
375#  define VMIN VEOF
376#endif
377
378#if !defined (VTIME)
379#  define VTIME VEOL
380#endif
381
382#if defined (TERMIOS_TTY_DRIVER)
383#  define TIOTYPE struct termios
384#  define DRAIN_OUTPUT(fd)	tcdrain (fd)
385#  define GETATTR(tty, tiop)	(tcgetattr (tty, tiop))
386#  ifdef M_UNIX
387#    define SETATTR(tty, tiop)	(tcsetattr (tty, TCSANOW, tiop))
388#  else
389#    define SETATTR(tty, tiop)	(tcsetattr (tty, TCSADRAIN, tiop))
390#  endif /* !M_UNIX */
391#else
392#  define TIOTYPE struct termio
393#  define DRAIN_OUTPUT(fd)
394#  define GETATTR(tty, tiop)	(ioctl (tty, TCGETA, tiop))
395#  define SETATTR(tty, tiop)	(ioctl (tty, TCSETAW, tiop))
396#endif /* !TERMIOS_TTY_DRIVER */
397
398static TIOTYPE otio;
399
400static void save_tty_chars PARAMS((TIOTYPE *));
401static int _get_tty_settings PARAMS((int, TIOTYPE *));
402static int get_tty_settings PARAMS((int, TIOTYPE *));
403static int _set_tty_settings PARAMS((int, TIOTYPE *));
404static int set_tty_settings PARAMS((int, TIOTYPE *));
405
406static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
407
408static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
409static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
410
411#if defined (FLUSHO)
412#  define OUTPUT_BEING_FLUSHED(tp)  (tp->c_lflag & FLUSHO)
413#else
414#  define OUTPUT_BEING_FLUSHED(tp)  0
415#endif
416
417static void
418save_tty_chars (tiop)
419     TIOTYPE *tiop;
420{
421  _rl_last_tty_chars = _rl_tty_chars;
422
423  _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
424  _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
425#ifdef VEOL2
426  _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
427#endif
428  _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
429#ifdef VWERASE
430  _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
431#endif
432  _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
433#ifdef VREPRINT
434  _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
435#endif
436  _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
437  _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
438#ifdef VSUSP
439  _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
440#endif
441#ifdef VDSUSP
442  _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
443#endif
444#ifdef VSTART
445  _rl_tty_chars.t_start = tiop->c_cc[VSTART];
446#endif
447#ifdef VSTOP
448  _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
449#endif
450#ifdef VLNEXT
451  _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
452#endif
453#ifdef VDISCARD
454  _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
455#endif
456#ifdef VSTATUS
457  _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
458#endif
459}
460
461#if defined (_AIX) || defined (_AIX41)
462/* Currently this is only used on AIX */
463static void
464rltty_warning (msg)
465     char *msg;
466{
467  fprintf (stderr, "readline: warning: %s\n", msg);
468}
469#endif
470
471#if defined (_AIX)
472void
473setopost(tp)
474TIOTYPE *tp;
475{
476  if ((tp->c_oflag & OPOST) == 0)
477    {
478      rltty_warning ("turning on OPOST for terminal\r");
479      tp->c_oflag |= OPOST|ONLCR;
480    }
481}
482#endif
483
484static int
485_get_tty_settings (tty, tiop)
486     int tty;
487     TIOTYPE *tiop;
488{
489  int ioctl_ret;
490
491  while (1)
492    {
493      ioctl_ret = GETATTR (tty, tiop);
494      if (ioctl_ret < 0)
495	{
496	  if (errno != EINTR)
497	    return -1;
498	  else
499	    continue;
500	}
501      if (OUTPUT_BEING_FLUSHED (tiop))
502	{
503#if defined (FLUSHO) && defined (_AIX41)
504	  rltty_warning ("turning off output flushing");
505	  tiop->c_lflag &= ~FLUSHO;
506	  break;
507#else
508	  continue;
509#endif
510	}
511      break;
512    }
513
514  return 0;
515}
516
517static int
518get_tty_settings (tty, tiop)
519     int tty;
520     TIOTYPE *tiop;
521{
522  set_winsize (tty);
523
524  errno = 0;
525  if (_get_tty_settings (tty, tiop) < 0)
526    return -1;
527
528#if defined (_AIX)
529  setopost(tiop);
530#endif
531
532  return 0;
533}
534
535static int
536_set_tty_settings (tty, tiop)
537     int tty;
538     TIOTYPE *tiop;
539{
540  while (SETATTR (tty, tiop) < 0)
541    {
542      if (errno != EINTR)
543	return -1;
544      errno = 0;
545    }
546  return 0;
547}
548
549static int
550set_tty_settings (tty, tiop)
551     int tty;
552     TIOTYPE *tiop;
553{
554  if (_set_tty_settings (tty, tiop) < 0)
555    return -1;
556
557#if 0
558
559#if defined (TERMIOS_TTY_DRIVER)
560#  if defined (__ksr1__)
561  if (ksrflow)
562    {
563      ksrflow = 0;
564      tcflow (tty, TCOON);
565    }
566#  else /* !ksr1 */
567  tcflow (tty, TCOON);		/* Simulate a ^Q. */
568#  endif /* !ksr1 */
569#else
570  ioctl (tty, TCXONC, 1);	/* Simulate a ^Q. */
571#endif /* !TERMIOS_TTY_DRIVER */
572
573#endif /* 0 */
574
575  return 0;
576}
577
578static void
579prepare_terminal_settings (meta_flag, oldtio, tiop)
580     int meta_flag;
581     TIOTYPE oldtio, *tiop;
582{
583  readline_echoing_p = (oldtio.c_lflag & ECHO);
584
585  tiop->c_lflag &= ~(ICANON | ECHO);
586
587  if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
588    _rl_eof_char = oldtio.c_cc[VEOF];
589
590#if defined (USE_XON_XOFF)
591#if defined (IXANY)
592  tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
593#else
594  /* `strict' Posix systems do not define IXANY. */
595  tiop->c_iflag &= ~(IXON | IXOFF);
596#endif /* IXANY */
597#endif /* USE_XON_XOFF */
598
599  /* Only turn this off if we are using all 8 bits. */
600  if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
601    tiop->c_iflag &= ~(ISTRIP | INPCK);
602
603  /* Make sure we differentiate between CR and NL on input. */
604  tiop->c_iflag &= ~(ICRNL | INLCR);
605
606#if !defined (HANDLE_SIGNALS)
607  tiop->c_lflag &= ~ISIG;
608#else
609  tiop->c_lflag |= ISIG;
610#endif
611
612  tiop->c_cc[VMIN] = 1;
613  tiop->c_cc[VTIME] = 0;
614
615#if defined (FLUSHO)
616  if (OUTPUT_BEING_FLUSHED (tiop))
617    {
618      tiop->c_lflag &= ~FLUSHO;
619      oldtio.c_lflag &= ~FLUSHO;
620    }
621#endif
622
623  /* Turn off characters that we need on Posix systems with job control,
624     just to be sure.  This includes ^Y and ^V.  This should not really
625     be necessary.  */
626#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
627
628#if defined (VLNEXT)
629  tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
630#endif
631
632#if defined (VDSUSP)
633  tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
634#endif
635
636#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
637}
638#endif  /* !NEW_TTY_DRIVER */
639
640/* Put the terminal in CBREAK mode so that we can detect key presses. */
641#if defined (NO_TTY_DRIVER)
642void
643rl_prep_terminal (meta_flag)
644     int meta_flag;
645{
646  readline_echoing_p = 1;
647}
648
649void
650rl_deprep_terminal ()
651{
652}
653
654#else /* ! NO_TTY_DRIVER */
655void
656rl_prep_terminal (meta_flag)
657     int meta_flag;
658{
659  int tty;
660  TIOTYPE tio;
661
662  if (terminal_prepped)
663    return;
664
665  /* Try to keep this function from being INTerrupted. */
666  block_sigint ();
667
668  tty = fileno (rl_instream);
669
670  if (get_tty_settings (tty, &tio) < 0)
671    {
672#if defined (ENOTSUP)
673      /* MacOS X, at least, lies about the value of errno if tcgetattr fails. */
674      if (errno == ENOTTY || errno == ENOTSUP)
675#else
676      if (errno == ENOTTY)
677#endif
678	readline_echoing_p = 1;		/* XXX */
679      release_sigint ();
680      return;
681    }
682
683  otio = tio;
684
685  if (_rl_bind_stty_chars)
686    {
687#if defined (VI_MODE)
688      /* If editing in vi mode, make sure we restore the bindings in the
689	 insertion keymap no matter what keymap we ended up in. */
690      if (rl_editing_mode == vi_mode)
691	rl_tty_unset_default_bindings (vi_insertion_keymap);
692      else
693#endif
694	rl_tty_unset_default_bindings (_rl_keymap);
695    }
696  save_tty_chars (&otio);
697  RL_SETSTATE(RL_STATE_TTYCSAVED);
698  if (_rl_bind_stty_chars)
699    {
700#if defined (VI_MODE)
701      /* If editing in vi mode, make sure we set the bindings in the
702	 insertion keymap no matter what keymap we ended up in. */
703      if (rl_editing_mode == vi_mode)
704	_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
705      else
706#endif
707	_rl_bind_tty_special_chars (_rl_keymap, tio);
708    }
709
710  prepare_terminal_settings (meta_flag, otio, &tio);
711
712  if (set_tty_settings (tty, &tio) < 0)
713    {
714      release_sigint ();
715      return;
716    }
717
718  if (_rl_enable_keypad)
719    _rl_control_keypad (1);
720
721  fflush (rl_outstream);
722  terminal_prepped = 1;
723  RL_SETSTATE(RL_STATE_TERMPREPPED);
724
725  release_sigint ();
726}
727
728/* Restore the terminal's normal settings and modes. */
729void
730rl_deprep_terminal ()
731{
732  int tty;
733
734  if (!terminal_prepped)
735    return;
736
737  /* Try to keep this function from being interrupted. */
738  block_sigint ();
739
740  tty = fileno (rl_instream);
741
742  if (_rl_enable_keypad)
743    _rl_control_keypad (0);
744
745  fflush (rl_outstream);
746
747  if (set_tty_settings (tty, &otio) < 0)
748    {
749      release_sigint ();
750      return;
751    }
752
753  terminal_prepped = 0;
754  RL_UNSETSTATE(RL_STATE_TERMPREPPED);
755
756  release_sigint ();
757}
758#endif /* !NO_TTY_DRIVER */
759
760/* **************************************************************** */
761/*								    */
762/*			Bogus Flow Control      		    */
763/*								    */
764/* **************************************************************** */
765
766int
767rl_restart_output (count, key)
768     int count, key;
769{
770#if defined (__MINGW32__)
771  return 0;
772#else /* !__MING32__ */
773
774  int fildes = fileno (rl_outstream);
775#if defined (TIOCSTART)
776#if defined (apollo)
777  ioctl (&fildes, TIOCSTART, 0);
778#else
779  ioctl (fildes, TIOCSTART, 0);
780#endif /* apollo */
781
782#else /* !TIOCSTART */
783#  if defined (TERMIOS_TTY_DRIVER)
784#    if defined (__ksr1__)
785  if (ksrflow)
786    {
787      ksrflow = 0;
788      tcflow (fildes, TCOON);
789    }
790#    else /* !ksr1 */
791  tcflow (fildes, TCOON);		/* Simulate a ^Q. */
792#    endif /* !ksr1 */
793#  else /* !TERMIOS_TTY_DRIVER */
794#    if defined (TCXONC)
795  ioctl (fildes, TCXONC, TCOON);
796#    endif /* TCXONC */
797#  endif /* !TERMIOS_TTY_DRIVER */
798#endif /* !TIOCSTART */
799
800  return 0;
801#endif /* !__MINGW32__ */
802}
803
804int
805rl_stop_output (count, key)
806     int count, key;
807{
808#if defined (__MINGW32__)
809  return 0;
810#else
811
812  int fildes = fileno (rl_instream);
813
814#if defined (TIOCSTOP)
815# if defined (apollo)
816  ioctl (&fildes, TIOCSTOP, 0);
817# else
818  ioctl (fildes, TIOCSTOP, 0);
819# endif /* apollo */
820#else /* !TIOCSTOP */
821# if defined (TERMIOS_TTY_DRIVER)
822#  if defined (__ksr1__)
823  ksrflow = 1;
824#  endif /* ksr1 */
825  tcflow (fildes, TCOOFF);
826# else
827#   if defined (TCXONC)
828  ioctl (fildes, TCXONC, TCOON);
829#   endif /* TCXONC */
830# endif /* !TERMIOS_TTY_DRIVER */
831#endif /* !TIOCSTOP */
832
833  return 0;
834#endif /* !__MINGW32__ */
835}
836
837/* **************************************************************** */
838/*								    */
839/*			Default Key Bindings			    */
840/*								    */
841/* **************************************************************** */
842
843#if !defined (NO_TTY_DRIVER)
844#define SET_SPECIAL(sc, func)	set_special_char(kmap, &ttybuff, sc, func)
845#endif
846
847#if defined (NO_TTY_DRIVER)
848
849#define SET_SPECIAL(sc, func)
850#define RESET_SPECIAL(c)
851
852#elif defined (NEW_TTY_DRIVER)
853static void
854set_special_char (kmap, tiop, sc, func)
855     Keymap kmap;
856     TIOTYPE *tiop;
857     int sc;
858     rl_command_func_t *func;
859{
860  if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
861    kmap[(unsigned char)sc].function = func;
862}
863
864#define RESET_SPECIAL(c) \
865  if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
866    kmap[(unsigned char)c].function = rl_insert;
867
868static void
869_rl_bind_tty_special_chars (kmap, ttybuff)
870     Keymap kmap;
871     TIOTYPE ttybuff;
872{
873  if (ttybuff.flags & SGTTY_SET)
874    {
875      SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
876      SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
877    }
878
879#  if defined (TIOCGLTC)
880  if (ttybuff.flags & LTCHARS_SET)
881    {
882      SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
883      SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
884    }
885#  endif /* TIOCGLTC */
886}
887
888#else /* !NEW_TTY_DRIVER */
889static void
890set_special_char (kmap, tiop, sc, func)
891     Keymap kmap;
892     TIOTYPE *tiop;
893     int sc;
894     rl_command_func_t *func;
895{
896  unsigned char uc;
897
898  uc = tiop->c_cc[sc];
899  if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
900    kmap[uc].function = func;
901}
902
903/* used later */
904#define RESET_SPECIAL(uc) \
905  if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
906    kmap[uc].function = rl_insert;
907
908static void
909_rl_bind_tty_special_chars (kmap, ttybuff)
910     Keymap kmap;
911     TIOTYPE ttybuff;
912{
913  SET_SPECIAL (VERASE, rl_rubout);
914  SET_SPECIAL (VKILL, rl_unix_line_discard);
915
916#  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
917  SET_SPECIAL (VLNEXT, rl_quoted_insert);
918#  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
919
920#  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
921  SET_SPECIAL (VWERASE, rl_unix_word_rubout);
922#  endif /* VWERASE && TERMIOS_TTY_DRIVER */
923}
924
925#endif /* !NEW_TTY_DRIVER */
926
927/* Set the system's default editing characters to their readline equivalents
928   in KMAP.  Should be static, now that we have rl_tty_set_default_bindings. */
929void
930rltty_set_default_bindings (kmap)
931     Keymap kmap;
932{
933#if !defined (NO_TTY_DRIVER)
934  TIOTYPE ttybuff;
935  int tty;
936
937  tty = fileno (rl_instream);
938
939  if (get_tty_settings (tty, &ttybuff) == 0)
940    _rl_bind_tty_special_chars (kmap, ttybuff);
941#endif
942}
943
944/* New public way to set the system default editing chars to their readline
945   equivalents. */
946void
947rl_tty_set_default_bindings (kmap)
948     Keymap kmap;
949{
950  rltty_set_default_bindings (kmap);
951}
952
953/* Rebind all of the tty special chars that readline worries about back
954   to self-insert.  Call this before saving the current terminal special
955   chars with save_tty_chars().  This only works on POSIX termios or termio
956   systems. */
957void
958rl_tty_unset_default_bindings (kmap)
959     Keymap kmap;
960{
961  /* Don't bother before we've saved the tty special chars at least once. */
962  if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
963    return;
964
965  RESET_SPECIAL (_rl_tty_chars.t_erase);
966  RESET_SPECIAL (_rl_tty_chars.t_kill);
967
968#  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
969  RESET_SPECIAL (_rl_tty_chars.t_lnext);
970#  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
971
972#  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
973  RESET_SPECIAL (_rl_tty_chars.t_werase);
974#  endif /* VWERASE && TERMIOS_TTY_DRIVER */
975}
976
977#if defined (HANDLE_SIGNALS)
978
979#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
980int
981_rl_disable_tty_signals ()
982{
983  return 0;
984}
985
986int
987_rl_restore_tty_signals ()
988{
989  return 0;
990}
991#else
992
993static TIOTYPE sigstty, nosigstty;
994static int tty_sigs_disabled = 0;
995
996int
997_rl_disable_tty_signals ()
998{
999  if (tty_sigs_disabled)
1000    return 0;
1001
1002  if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
1003    return -1;
1004
1005  nosigstty = sigstty;
1006
1007  nosigstty.c_lflag &= ~ISIG;
1008  nosigstty.c_iflag &= ~IXON;
1009
1010  if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
1011    return (_set_tty_settings (fileno (rl_instream), &sigstty));
1012
1013  tty_sigs_disabled = 1;
1014  return 0;
1015}
1016
1017int
1018_rl_restore_tty_signals ()
1019{
1020  int r;
1021
1022  if (tty_sigs_disabled == 0)
1023    return 0;
1024
1025  r = _set_tty_settings (fileno (rl_instream), &sigstty);
1026
1027  if (r == 0)
1028    tty_sigs_disabled = 0;
1029
1030  return r;
1031}
1032#endif /* !NEW_TTY_DRIVER */
1033
1034#endif /* HANDLE_SIGNALS */
1035