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