Merge from vendor branch GCC:
[dragonfly.git] / contrib / readline-5.0 / rltty.c
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)
49 extern int errno;
50 #endif /* !errno */
51
52 rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
53 rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
54
55 static void block_sigint PARAMS((void));
56 static void release_sigint PARAMS((void));
57
58 static void set_winsize PARAMS((int));
59
60 /* **************************************************************** */
61 /*                                                                  */
62 /*                         Signal Management                        */
63 /*                                                                  */
64 /* **************************************************************** */
65
66 #if defined (HAVE_POSIX_SIGNALS)
67 static sigset_t sigint_set, sigint_oset;
68 #else /* !HAVE_POSIX_SIGNALS */
69 #  if defined (HAVE_BSD_SIGNALS)
70 static int sigint_oldmask;
71 #  endif /* HAVE_BSD_SIGNALS */
72 #endif /* !HAVE_POSIX_SIGNALS */
73
74 static int sigint_blocked;
75
76 /* Cause SIGINT to not be delivered until the corresponding call to
77    release_sigint(). */
78 static void
79 block_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. */
103 static void
104 release_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. */
131 static int terminal_prepped;
132
133 static _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__)
138 static int ksrflow;
139 #endif
140
141 /* Dummy call to force a backgrounded readline to stop before it tries
142    to get the tty settings. */
143 static void
144 set_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
165 struct 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
179 static TIOTYPE otio;
180
181 static void save_tty_chars PARAMS((TIOTYPE *));
182 static int _get_tty_settings PARAMS((int, TIOTYPE *));
183 static int get_tty_settings PARAMS((int, TIOTYPE *));
184 static int _set_tty_settings PARAMS((int, TIOTYPE *));
185 static int set_tty_settings PARAMS((int, TIOTYPE *));
186
187 static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
188
189 static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
190
191 static void
192 save_tty_chars (tiop)
193      TIOTYPE *tiop;
194 {
195   _rl_last_tty_chars = _rl_tty_chars;
196
197   if (tiop->flags & SGTTY_SET)
198     {
199       _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
200       _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
201     }
202
203   if (tiop->flags & TCHARS_SET)
204     {
205       _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
206       _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
207       _rl_tty_chars.t_start = tiop->tchars.t_startc;
208       _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
209       _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
210       _rl_tty_chars.t_eol = '\n';
211       _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
212     }
213
214   if (tiop->flags & LTCHARS_SET)
215     {
216       _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
217       _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
218       _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
219       _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
220       _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
221       _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
222     }
223
224   _rl_tty_chars.t_status = -1;
225 }
226
227 static int
228 get_tty_settings (tty, tiop)
229      int tty;
230      TIOTYPE *tiop;
231 {
232   set_winsize (tty);
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
258 static int
259 set_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
297 static void
298 prepare_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
395 static TIOTYPE otio;
396
397 static void save_tty_chars PARAMS((TIOTYPE *));
398 static int _get_tty_settings PARAMS((int, TIOTYPE *));
399 static int get_tty_settings PARAMS((int, TIOTYPE *));
400 static int _set_tty_settings PARAMS((int, TIOTYPE *));
401 static int set_tty_settings PARAMS((int, TIOTYPE *));
402
403 static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
404
405 static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
406 static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
407
408 #if defined (FLUSHO)
409 #  define OUTPUT_BEING_FLUSHED(tp)  (tp->c_lflag & FLUSHO)
410 #else
411 #  define OUTPUT_BEING_FLUSHED(tp)  0
412 #endif
413
414 static void
415 save_tty_chars (tiop)
416      TIOTYPE *tiop;
417 {
418   _rl_last_tty_chars = _rl_tty_chars;
419
420   _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
421   _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
422 #ifdef VEOL2
423   _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
424 #endif
425   _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
426 #ifdef VWERASE
427   _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
428 #endif
429   _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
430 #ifdef VREPRINT
431   _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
432 #endif
433   _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
434   _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
435 #ifdef VSUSP
436   _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
437 #endif
438 #ifdef VDSUSP
439   _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
440 #endif
441 #ifdef VSTART
442   _rl_tty_chars.t_start = tiop->c_cc[VSTART];
443 #endif
444 #ifdef VSTOP
445   _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
446 #endif
447 #ifdef VLNEXT
448   _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
449 #endif
450 #ifdef VDISCARD
451   _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
452 #endif
453 #ifdef VSTATUS
454   _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
455 #endif
456 }
457
458 #if defined (_AIX) || defined (_AIX41)
459 /* Currently this is only used on AIX */
460 static void
461 rltty_warning (msg)
462      char *msg;
463 {
464   fprintf (stderr, "readline: warning: %s\n", msg);
465 }
466 #endif
467
468 #if defined (_AIX)
469 void
470 setopost(tp)
471 TIOTYPE *tp;
472 {
473   if ((tp->c_oflag & OPOST) == 0)
474     {
475       rltty_warning ("turning on OPOST for terminal\r");
476       tp->c_oflag |= OPOST|ONLCR;
477     }
478 }
479 #endif
480
481 static int
482 _get_tty_settings (tty, tiop)
483      int tty;
484      TIOTYPE *tiop;
485 {
486   int ioctl_ret;
487
488   while (1)
489     {
490       ioctl_ret = GETATTR (tty, tiop);
491       if (ioctl_ret < 0)
492         {
493           if (errno != EINTR)
494             return -1;
495           else
496             continue;
497         }
498       if (OUTPUT_BEING_FLUSHED (tiop))
499         {
500 #if defined (FLUSHO) && defined (_AIX41)
501           rltty_warning ("turning off output flushing");
502           tiop->c_lflag &= ~FLUSHO;
503           break;
504 #else
505           continue;
506 #endif
507         }
508       break;
509     }
510
511   return 0;
512 }
513
514 static int
515 get_tty_settings (tty, tiop)
516      int tty;
517      TIOTYPE *tiop;
518 {
519   set_winsize (tty);
520
521   if (_get_tty_settings (tty, tiop) < 0)
522     return -1;
523
524 #if defined (_AIX)
525   setopost(tiop);
526 #endif
527
528   return 0;
529 }
530
531 static int
532 _set_tty_settings (tty, tiop)
533      int tty;
534      TIOTYPE *tiop;
535 {
536   while (SETATTR (tty, tiop) < 0)
537     {
538       if (errno != EINTR)
539         return -1;
540       errno = 0;
541     }
542   return 0;
543 }
544
545 static int
546 set_tty_settings (tty, tiop)
547      int tty;
548      TIOTYPE *tiop;
549 {
550   if (_set_tty_settings (tty, tiop) < 0)
551     return -1;
552     
553 #if 0
554
555 #if defined (TERMIOS_TTY_DRIVER)
556 #  if defined (__ksr1__)
557   if (ksrflow)
558     {
559       ksrflow = 0;
560       tcflow (tty, TCOON);
561     }
562 #  else /* !ksr1 */
563   tcflow (tty, TCOON);          /* Simulate a ^Q. */
564 #  endif /* !ksr1 */
565 #else
566   ioctl (tty, TCXONC, 1);       /* Simulate a ^Q. */
567 #endif /* !TERMIOS_TTY_DRIVER */
568
569 #endif /* 0 */
570
571   return 0;
572 }
573
574 static void
575 prepare_terminal_settings (meta_flag, oldtio, tiop)
576      int meta_flag;
577      TIOTYPE oldtio, *tiop;
578 {
579   readline_echoing_p = (oldtio.c_lflag & ECHO);
580
581   tiop->c_lflag &= ~(ICANON | ECHO);
582
583   if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
584     _rl_eof_char = oldtio.c_cc[VEOF];
585
586 #if defined (USE_XON_XOFF)
587 #if defined (IXANY)
588   tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
589 #else
590   /* `strict' Posix systems do not define IXANY. */
591   tiop->c_iflag &= ~(IXON | IXOFF);
592 #endif /* IXANY */
593 #endif /* USE_XON_XOFF */
594
595   /* Only turn this off if we are using all 8 bits. */
596   if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
597     tiop->c_iflag &= ~(ISTRIP | INPCK);
598
599   /* Make sure we differentiate between CR and NL on input. */
600   tiop->c_iflag &= ~(ICRNL | INLCR);
601
602 #if !defined (HANDLE_SIGNALS)
603   tiop->c_lflag &= ~ISIG;
604 #else
605   tiop->c_lflag |= ISIG;
606 #endif
607
608   tiop->c_cc[VMIN] = 1;
609   tiop->c_cc[VTIME] = 0;
610
611 #if defined (FLUSHO)
612   if (OUTPUT_BEING_FLUSHED (tiop))
613     {
614       tiop->c_lflag &= ~FLUSHO;
615       oldtio.c_lflag &= ~FLUSHO;
616     }
617 #endif
618
619   /* Turn off characters that we need on Posix systems with job control,
620      just to be sure.  This includes ^Y and ^V.  This should not really
621      be necessary.  */
622 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
623
624 #if defined (VLNEXT)
625   tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
626 #endif
627
628 #if defined (VDSUSP)
629   tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
630 #endif
631
632 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
633 }
634 #endif  /* NEW_TTY_DRIVER */
635
636 /* Put the terminal in CBREAK mode so that we can detect key presses. */
637 void
638 rl_prep_terminal (meta_flag)
639      int meta_flag;
640 {
641   int tty;
642   TIOTYPE tio;
643
644   if (terminal_prepped)
645     return;
646
647   /* Try to keep this function from being INTerrupted. */
648   block_sigint ();
649
650   tty = fileno (rl_instream);
651
652   if (get_tty_settings (tty, &tio) < 0)
653     {
654       release_sigint ();
655       return;
656     }
657
658   otio = tio;
659
660   rl_tty_unset_default_bindings (_rl_keymap);
661   save_tty_chars (&otio);
662   RL_SETSTATE(RL_STATE_TTYCSAVED);
663   _rl_bind_tty_special_chars (_rl_keymap, tio);
664
665   prepare_terminal_settings (meta_flag, otio, &tio);
666
667   if (set_tty_settings (tty, &tio) < 0)
668     {
669       release_sigint ();
670       return;
671     }
672
673   if (_rl_enable_keypad)
674     _rl_control_keypad (1);
675
676   fflush (rl_outstream);
677   terminal_prepped = 1;
678   RL_SETSTATE(RL_STATE_TERMPREPPED);
679
680   release_sigint ();
681 }
682
683 /* Restore the terminal's normal settings and modes. */
684 void
685 rl_deprep_terminal ()
686 {
687   int tty;
688
689   if (!terminal_prepped)
690     return;
691
692   /* Try to keep this function from being interrupted. */
693   block_sigint ();
694
695   tty = fileno (rl_instream);
696
697   if (_rl_enable_keypad)
698     _rl_control_keypad (0);
699
700   fflush (rl_outstream);
701
702   if (set_tty_settings (tty, &otio) < 0)
703     {
704       release_sigint ();
705       return;
706     }
707
708   terminal_prepped = 0;
709   RL_UNSETSTATE(RL_STATE_TERMPREPPED);
710
711   release_sigint ();
712 }
713 \f
714 /* **************************************************************** */
715 /*                                                                  */
716 /*                      Bogus Flow Control                          */
717 /*                                                                  */
718 /* **************************************************************** */
719
720 int
721 rl_restart_output (count, key)
722      int count, key;
723 {
724   int fildes = fileno (rl_outstream);
725 #if defined (TIOCSTART)
726 #if defined (apollo)
727   ioctl (&fildes, TIOCSTART, 0);
728 #else
729   ioctl (fildes, TIOCSTART, 0);
730 #endif /* apollo */
731
732 #else /* !TIOCSTART */
733 #  if defined (TERMIOS_TTY_DRIVER)
734 #    if defined (__ksr1__)
735   if (ksrflow)
736     {
737       ksrflow = 0;
738       tcflow (fildes, TCOON);
739     }
740 #    else /* !ksr1 */
741   tcflow (fildes, TCOON);               /* Simulate a ^Q. */
742 #    endif /* !ksr1 */
743 #  else /* !TERMIOS_TTY_DRIVER */
744 #    if defined (TCXONC)
745   ioctl (fildes, TCXONC, TCOON);
746 #    endif /* TCXONC */
747 #  endif /* !TERMIOS_TTY_DRIVER */
748 #endif /* !TIOCSTART */
749
750   return 0;
751 }
752
753 int
754 rl_stop_output (count, key)
755      int count, key;
756 {
757   int fildes = fileno (rl_instream);
758
759 #if defined (TIOCSTOP)
760 # if defined (apollo)
761   ioctl (&fildes, TIOCSTOP, 0);
762 # else
763   ioctl (fildes, TIOCSTOP, 0);
764 # endif /* apollo */
765 #else /* !TIOCSTOP */
766 # if defined (TERMIOS_TTY_DRIVER)
767 #  if defined (__ksr1__)
768   ksrflow = 1;
769 #  endif /* ksr1 */
770   tcflow (fildes, TCOOFF);
771 # else
772 #   if defined (TCXONC)
773   ioctl (fildes, TCXONC, TCOON);
774 #   endif /* TCXONC */
775 # endif /* !TERMIOS_TTY_DRIVER */
776 #endif /* !TIOCSTOP */
777
778   return 0;
779 }
780
781 /* **************************************************************** */
782 /*                                                                  */
783 /*                      Default Key Bindings                        */
784 /*                                                                  */
785 /* **************************************************************** */
786
787 #define SET_SPECIAL(sc, func)   set_special_char(kmap, &ttybuff, sc, func)
788
789 #if defined (NEW_TTY_DRIVER)
790 static void
791 set_special_char (kmap, tiop, sc, func)
792      Keymap kmap;
793      TIOTYPE *tiop;
794      int sc;
795      rl_command_func_t *func;
796 {
797   if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
798     kmap[(unsigned char)sc].function = func;
799 }
800
801 #define RESET_SPECIAL(c) \
802   if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
803     kmap[(unsigned char)c].function = rl_insert;
804
805 static void
806 _rl_bind_tty_special_chars (kmap, ttybuff)
807      Keymap kmap;
808      TIOTYPE ttybuff;
809 {
810   if (ttybuff.flags & SGTTY_SET)
811     {
812       SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
813       SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
814     }
815
816 #  if defined (TIOCGLTC)
817   if (ttybuff.flags & LTCHARS_SET)
818     {
819       SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
820       SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
821     }
822 #  endif /* TIOCGLTC */
823 }
824
825 #else /* !NEW_TTY_DRIVER */
826 static void
827 set_special_char (kmap, tiop, sc, func)
828      Keymap kmap;
829      TIOTYPE *tiop;
830      int sc;
831      rl_command_func_t *func;
832 {
833   unsigned char uc;
834
835   uc = tiop->c_cc[sc];
836   if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
837     kmap[uc].function = func;
838 }
839
840 /* used later */
841 #define RESET_SPECIAL(uc) \
842   if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
843     kmap[uc].function = rl_insert;
844
845 static void
846 _rl_bind_tty_special_chars (kmap, ttybuff)
847      Keymap kmap;
848      TIOTYPE ttybuff;
849 {
850   SET_SPECIAL (VERASE, rl_rubout);
851   SET_SPECIAL (VKILL, rl_unix_line_discard);
852
853 #  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
854   SET_SPECIAL (VLNEXT, rl_quoted_insert);
855 #  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
856
857 #  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
858   SET_SPECIAL (VWERASE, rl_unix_word_rubout);
859 #  endif /* VWERASE && TERMIOS_TTY_DRIVER */
860 }
861
862 #endif /* !NEW_TTY_DRIVER */
863
864 /* Set the system's default editing characters to their readline equivalents
865    in KMAP.  Should be static, now that we have rl_tty_set_default_bindings. */
866 void
867 rltty_set_default_bindings (kmap)
868      Keymap kmap;
869 {
870   TIOTYPE ttybuff;
871   int tty;
872   static int called = 0;
873
874   tty = fileno (rl_instream);
875
876   if (get_tty_settings (tty, &ttybuff) == 0)
877     _rl_bind_tty_special_chars (kmap, ttybuff);
878 }
879
880 /* New public way to set the system default editing chars to their readline
881    equivalents. */
882 void
883 rl_tty_set_default_bindings (kmap)
884      Keymap kmap;
885 {
886   rltty_set_default_bindings (kmap);
887 }
888
889 /* Rebind all of the tty special chars that readline worries about back
890    to self-insert.  Call this before saving the current terminal special
891    chars with save_tty_chars().  This only works on POSIX termios or termio
892    systems. */
893 void
894 rl_tty_unset_default_bindings (kmap)
895      Keymap kmap;
896 {
897   /* Don't bother before we've saved the tty special chars at least once. */
898   if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
899     return;
900
901   RESET_SPECIAL (_rl_tty_chars.t_erase);
902   RESET_SPECIAL (_rl_tty_chars.t_kill);
903
904 #  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
905   RESET_SPECIAL (_rl_tty_chars.t_lnext);
906 #  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
907
908 #  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
909   RESET_SPECIAL (_rl_tty_chars.t_werase);
910 #  endif /* VWERASE && TERMIOS_TTY_DRIVER */
911 }
912
913 #if defined (HANDLE_SIGNALS)
914
915 #if defined (NEW_TTY_DRIVER)
916 int
917 _rl_disable_tty_signals ()
918 {
919   return 0;
920 }
921
922 int
923 _rl_restore_tty_signals ()
924 {
925   return 0;
926 }
927 #else
928
929 static TIOTYPE sigstty, nosigstty;
930 static int tty_sigs_disabled = 0;
931
932 int
933 _rl_disable_tty_signals ()
934 {
935   if (tty_sigs_disabled)
936     return 0;
937
938   if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
939     return -1;
940
941   nosigstty = sigstty;
942
943   nosigstty.c_lflag &= ~ISIG;
944   nosigstty.c_iflag &= ~IXON;
945
946   if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
947     return (_set_tty_settings (fileno (rl_instream), &sigstty));
948
949   tty_sigs_disabled = 1;
950   return 0;
951 }
952
953 int
954 _rl_restore_tty_signals ()
955 {
956   int r;
957
958   if (tty_sigs_disabled == 0)
959     return 0;
960
961   r = _set_tty_settings (fileno (rl_instream), &sigstty);
962
963   if (r == 0)
964     tty_sigs_disabled = 0;
965
966   return r;
967 }
968 #endif /* !NEW_TTY_DRIVER */
969
970 #endif /* HANDLE_SIGNALS */