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