2003-12-11 Michael Chastain <mec.gnu@mindspring.com>
[external/binutils.git] / readline / 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
190 save_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
225 static int
226 get_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
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 #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
411 static void
412 save_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 */
457 static void
458 rltty_warning (msg)
459      char *msg;
460 {
461   fprintf (stderr, "readline: warning: %s\n", msg);
462 }
463 #endif
464
465 #if defined (_AIX)
466 void
467 setopost(tp)
468 TIOTYPE *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
478 static 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
511 static int
512 get_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
530 static 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
544 static int
545 set_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
573 static void
574 prepare_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. */
636 void
637 rl_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. */
680 void
681 rl_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 \f
710 /* **************************************************************** */
711 /*                                                                  */
712 /*                      Bogus Flow Control                          */
713 /*                                                                  */
714 /* **************************************************************** */
715
716 int
717 rl_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
749 int
750 rl_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. */
785 void
786 rltty_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. */
851 void
852 rl_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)
861 int
862 _rl_disable_tty_signals ()
863 {
864   return 0;
865 }
866
867 int
868 _rl_restore_tty_signals ()
869 {
870   return 0;
871 }
872 #else
873
874 static TIOTYPE sigstty, nosigstty;
875 static int tty_sigs_disabled = 0;
876
877 int
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
898 int
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 */