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