Imported from ../bash-2.05b.tar.gz.
[platform/upstream/bash.git] / lib / 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   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
256 static int
257 set_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
295 static void
296 prepare_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
393 static TIOTYPE otio;
394
395 static void save_tty_chars PARAMS((TIOTYPE *));
396 static int _get_tty_settings PARAMS((int, TIOTYPE *));
397 static int get_tty_settings PARAMS((int, TIOTYPE *));
398 static int _set_tty_settings PARAMS((int, TIOTYPE *));
399 static int set_tty_settings PARAMS((int, TIOTYPE *));
400
401 static 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
409 static void
410 save_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 */
455 static void
456 rltty_warning (msg)
457      char *msg;
458 {
459   fprintf (stderr, "readline: warning: %s\n", msg);
460 }
461 #endif
462
463 #if defined (_AIX)
464 void
465 setopost(tp)
466 TIOTYPE *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
476 static 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
509 static int
510 get_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
526 static 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
540 static int
541 set_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
569 static void
570 prepare_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. */
632 void
633 rl_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. */
676 void
677 rl_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 \f
706 /* **************************************************************** */
707 /*                                                                  */
708 /*                      Bogus Flow Control                          */
709 /*                                                                  */
710 /* **************************************************************** */
711
712 int
713 rl_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
745 int
746 rl_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. */
781 void
782 rltty_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. */
847 void
848 rl_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)
857 int
858 _rl_disable_tty_signals ()
859 {
860   return 0;
861 }
862
863 int
864 _rl_restore_tty_signals ()
865 {
866   return 0;
867 }
868 #else
869
870 static TIOTYPE sigstty, nosigstty;
871 static int tty_sigs_disabled = 0;
872
873 int
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
894 int
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 */