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