import gdb-1999-08-16 snapshot
[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 1, 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    675 Mass Ave, Cambridge, MA 02139, 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
47 #if !defined (errno)
48 extern int errno;
49 #endif /* !errno */
50
51 extern int readline_echoing_p;
52 extern int _rl_eof_char;
53
54 extern int _rl_enable_keypad, _rl_enable_meta;
55
56 extern void _rl_control_keypad ();
57
58 #if defined (__GO32__)
59 #  include <pc.h>
60 #  undef HANDLE_SIGNALS
61 #endif /* __GO32__ */
62
63 /* Indirect functions to allow apps control over terminal management. */
64 extern void rl_prep_terminal (), rl_deprep_terminal ();
65
66 VFunction *rl_prep_term_function = rl_prep_terminal;
67 VFunction *rl_deprep_term_function = rl_deprep_terminal;
68
69 /* **************************************************************** */
70 /*                                                                  */
71 /*                         Signal Management                        */
72 /*                                                                  */
73 /* **************************************************************** */
74
75 #if defined (HAVE_POSIX_SIGNALS)
76 static sigset_t sigint_set, sigint_oset;
77 #else /* !HAVE_POSIX_SIGNALS */
78 #  if defined (HAVE_BSD_SIGNALS)
79 static int sigint_oldmask;
80 #  endif /* HAVE_BSD_SIGNALS */
81 #endif /* !HAVE_POSIX_SIGNALS */
82
83 static int sigint_blocked;
84
85 /* Cause SIGINT to not be delivered until the corresponding call to
86    release_sigint(). */
87 static void
88 block_sigint ()
89 {
90   if (sigint_blocked)
91     return;
92
93 #if defined (HAVE_POSIX_SIGNALS)
94   sigemptyset (&sigint_set);
95   sigemptyset (&sigint_oset);
96   sigaddset (&sigint_set, SIGINT);
97   sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
98 #else /* !HAVE_POSIX_SIGNALS */
99 #  if defined (HAVE_BSD_SIGNALS)
100   sigint_oldmask = sigblock (sigmask (SIGINT));
101 #  else /* !HAVE_BSD_SIGNALS */
102 #    if defined (HAVE_USG_SIGHOLD)
103   sighold (SIGINT);
104 #    endif /* HAVE_USG_SIGHOLD */
105 #  endif /* !HAVE_BSD_SIGNALS */
106 #endif /* !HAVE_POSIX_SIGNALS */
107   sigint_blocked = 1;
108 }
109
110 /* Allow SIGINT to be delivered. */
111 static void
112 release_sigint ()
113 {
114   if (!sigint_blocked)
115     return;
116
117 #if defined (HAVE_POSIX_SIGNALS)
118   sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
119 #else
120 #  if defined (HAVE_BSD_SIGNALS)
121   sigsetmask (sigint_oldmask);
122 #  else /* !HAVE_BSD_SIGNALS */
123 #    if defined (HAVE_USG_SIGHOLD)
124   sigrelse (SIGINT);
125 #    endif /* HAVE_USG_SIGHOLD */
126 #  endif /* !HAVE_BSD_SIGNALS */
127 #endif /* !HAVE_POSIX_SIGNALS */
128
129   sigint_blocked = 0;
130 }
131
132 /* **************************************************************** */
133 /*                                                                  */
134 /*                    Saving and Restoring the TTY                  */
135 /*                                                                  */
136 /* **************************************************************** */
137
138 /* Non-zero means that the terminal is in a prepped state. */
139 static int terminal_prepped;
140
141 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
142    and output is suspended. */
143 #if defined (__ksr1__)
144 static int ksrflow;
145 #endif
146
147 #if defined (TIOCGWINSZ)
148 /* Dummy call to force a backgrounded readline to stop before it tries
149    to get the tty settings. */
150 static void
151 set_winsize (tty)
152      int tty;
153 {
154   struct winsize w;
155
156   if (ioctl (tty, TIOCGWINSZ, &w) == 0)
157       (void) ioctl (tty, TIOCSWINSZ, &w);
158 }
159 #endif /* TIOCGWINSZ */
160
161 #if defined (NEW_TTY_DRIVER)
162
163 /* Values for the `flags' field of a struct bsdtty.  This tells which
164    elements of the struct bsdtty have been fetched from the system and
165    are valid. */
166 #define SGTTY_SET       0x01
167 #define LFLAG_SET       0x02
168 #define TCHARS_SET      0x04
169 #define LTCHARS_SET     0x08
170
171 struct bsdtty {
172   struct sgttyb sgttyb; /* Basic BSD tty driver information. */
173   int lflag;            /* Local mode flags, like LPASS8. */
174 #if defined (TIOCGETC)
175   struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
176 #endif
177 #if defined (TIOCGLTC)
178   struct ltchars ltchars; /* 4.2 BSD editing characters */
179 #endif
180   int flags;            /* Bitmap saying which parts of the struct are valid. */
181 };
182
183 #define TIOTYPE struct bsdtty
184
185 static TIOTYPE otio;
186
187 static int
188 get_tty_settings (tty, tiop)
189      int tty;
190      TIOTYPE *tiop;
191 {
192 #if defined (TIOCGWINSZ)
193   set_winsize (tty);
194 #endif
195
196   tiop->flags = tiop->lflag = 0;
197
198   ioctl (tty, TIOCGETP, &(tiop->sgttyb));
199   tiop->flags |= SGTTY_SET;
200
201 #if defined (TIOCLGET)
202   ioctl (tty, TIOCLGET, &(tiop->lflag));
203   tiop->flags |= LFLAG_SET;
204 #endif
205
206 #if defined (TIOCGETC)
207   ioctl (tty, TIOCGETC, &(tiop->tchars));
208   tiop->flags |= TCHARS_SET;
209 #endif
210
211 #if defined (TIOCGLTC)
212   ioctl (tty, TIOCGLTC, &(tiop->ltchars));
213   tiop->flags |= LTCHARS_SET;
214 #endif
215
216   return 0;
217 }
218
219 static int
220 set_tty_settings (tty, tiop)
221      int tty;
222      TIOTYPE *tiop;
223 {
224   if (tiop->flags & SGTTY_SET)
225     {
226       ioctl (tty, TIOCSETN, &(tiop->sgttyb));
227       tiop->flags &= ~SGTTY_SET;
228     }
229   readline_echoing_p = 1;
230
231 #if defined (TIOCLSET)
232   if (tiop->flags & LFLAG_SET)
233     {
234       ioctl (tty, TIOCLSET, &(tiop->lflag));
235       tiop->flags &= ~LFLAG_SET;
236     }
237 #endif
238
239 #if defined (TIOCSETC)
240   if (tiop->flags & TCHARS_SET)
241     {
242       ioctl (tty, TIOCSETC, &(tiop->tchars));
243       tiop->flags &= ~TCHARS_SET;
244     }
245 #endif
246
247 #if defined (TIOCSLTC)
248   if (tiop->flags & LTCHARS_SET)
249     {
250       ioctl (tty, TIOCSLTC, &(tiop->ltchars));
251       tiop->flags &= ~LTCHARS_SET;
252     }
253 #endif
254
255   return 0;
256 }
257
258 static void
259 prepare_terminal_settings (meta_flag, otio, tiop)
260      int meta_flag;
261      TIOTYPE otio, *tiop;
262 {
263 #if !defined (__GO32__)
264   readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
265
266   /* Copy the original settings to the structure we're going to use for
267      our settings. */
268   tiop->sgttyb = otio.sgttyb;
269   tiop->lflag = otio.lflag;
270 #if defined (TIOCGETC)
271   tiop->tchars = otio.tchars;
272 #endif
273 #if defined (TIOCGLTC)
274   tiop->ltchars = otio.ltchars;
275 #endif
276   tiop->flags = otio.flags;
277
278   /* First, the basic settings to put us into character-at-a-time, no-echo
279      input mode. */
280   tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
281   tiop->sgttyb.sg_flags |= CBREAK;
282
283   /* If this terminal doesn't care how the 8th bit is used, then we can
284      use it for the meta-key.  If only one of even or odd parity is
285      specified, then the terminal is using parity, and we cannot. */
286 #if !defined (ANYP)
287 #  define ANYP (EVENP | ODDP)
288 #endif
289   if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
290       ((otio.sgttyb.sg_flags & ANYP) == 0))
291     {
292       tiop->sgttyb.sg_flags |= ANYP;
293
294       /* Hack on local mode flags if we can. */
295 #if defined (TIOCLGET)
296 #  if defined (LPASS8)
297       tiop->lflag |= LPASS8;
298 #  endif /* LPASS8 */
299 #endif /* TIOCLGET */
300     }
301
302 #if defined (TIOCGETC)
303 #  if defined (USE_XON_XOFF)
304   /* Get rid of terminal output start and stop characters. */
305   tiop->tchars.t_stopc = -1; /* C-s */
306   tiop->tchars.t_startc = -1; /* C-q */
307
308   /* If there is an XON character, bind it to restart the output. */
309   if (otio.tchars.t_startc != -1)
310     rl_bind_key (otio.tchars.t_startc, rl_restart_output);
311 #  endif /* USE_XON_XOFF */
312
313   /* If there is an EOF char, bind _rl_eof_char to it. */
314   if (otio.tchars.t_eofc != -1)
315     _rl_eof_char = otio.tchars.t_eofc;
316
317 #  if defined (NO_KILL_INTR)
318   /* Get rid of terminal-generated SIGQUIT and SIGINT. */
319   tiop->tchars.t_quitc = -1; /* C-\ */
320   tiop->tchars.t_intrc = -1; /* C-c */
321 #  endif /* NO_KILL_INTR */
322 #endif /* TIOCGETC */
323
324 #if defined (TIOCGLTC)
325   /* Make the interrupt keys go away.  Just enough to make people happy. */
326   tiop->ltchars.t_dsuspc = -1;  /* C-y */
327   tiop->ltchars.t_lnextc = -1;  /* C-v */
328 #endif /* TIOCGLTC */
329 #endif /* !__GO32__ */
330 }
331
332 #else  /* !defined (NEW_TTY_DRIVER) */
333
334 #if !defined (VMIN)
335 #  define VMIN VEOF
336 #endif
337
338 #if !defined (VTIME)
339 #  define VTIME VEOL
340 #endif
341
342 #if defined (TERMIOS_TTY_DRIVER)
343 #  define TIOTYPE struct termios
344 #  define DRAIN_OUTPUT(fd)      tcdrain (fd)
345 #  define GETATTR(tty, tiop)    (tcgetattr (tty, tiop))
346 #  ifdef M_UNIX
347 #    define SETATTR(tty, tiop)  (tcsetattr (tty, TCSANOW, tiop))
348 #  else
349 #    define SETATTR(tty, tiop)  (tcsetattr (tty, TCSADRAIN, tiop))
350 #  endif /* !M_UNIX */
351 #else
352 #  define TIOTYPE struct termio
353 #  define DRAIN_OUTPUT(fd)
354 #  define GETATTR(tty, tiop)    (ioctl (tty, TCGETA, tiop))
355 #  define SETATTR(tty, tiop)    (ioctl (tty, TCSETA, tiop))
356 #endif /* !TERMIOS_TTY_DRIVER */
357
358 static TIOTYPE otio;
359
360 #if defined (FLUSHO)
361 #  define OUTPUT_BEING_FLUSHED(tp)  (tp->c_lflag & FLUSHO)
362 #else
363 #  define OUTPUT_BEING_FLUSHED(tp)  0
364 #endif
365
366 static void
367 rltty_warning (msg)
368      char *msg;
369 {
370   fprintf (stderr, "readline: warning: %s\n", msg);
371 }
372
373 #if defined (_AIX)
374 void
375 setopost(tp)
376 TIOTYPE *tp;
377 {
378   if ((tp->c_oflag & OPOST) == 0)
379     {
380       rltty_warning ("turning on OPOST for terminal\r");
381       tp->c_oflag |= OPOST|ONLCR;
382     }
383 }
384 #endif
385
386 static int
387 get_tty_settings (tty, tiop)
388      int tty;
389      TIOTYPE *tiop;
390 {
391   int ioctl_ret;
392
393 #if defined (TIOCGWINSZ)
394   set_winsize (tty);
395 #endif
396
397   while (1)
398     {
399       ioctl_ret = GETATTR (tty, tiop);
400       if (ioctl_ret < 0)
401         {
402           if (errno != EINTR)
403             return -1;
404           else
405             continue;
406         }
407       if (OUTPUT_BEING_FLUSHED (tiop))
408         {
409 #if defined (FLUSHO) && defined (_AIX41)
410           rltty_warning ("turning off output flushing");
411           tiop->c_lflag &= ~FLUSHO;
412           break;
413 #else
414           continue;
415 #endif
416         }
417       break;
418     }
419
420 #if defined (_AIX)
421   setopost(tiop);
422 #endif
423
424   return 0;
425 }
426
427 static int
428 set_tty_settings (tty, tiop)
429      int tty;
430      TIOTYPE *tiop;
431 {
432   while (SETATTR (tty, tiop) < 0)
433     {
434       if (errno != EINTR)
435         return -1;
436       errno = 0;
437     }
438
439 #if 0
440
441 #if defined (TERMIOS_TTY_DRIVER)
442 #  if defined (__ksr1__)
443   if (ksrflow)
444     {
445       ksrflow = 0;
446       tcflow (tty, TCOON);
447     }
448 #  else /* !ksr1 */
449   tcflow (tty, TCOON);          /* Simulate a ^Q. */
450 #  endif /* !ksr1 */
451 #else
452   ioctl (tty, TCXONC, 1);       /* Simulate a ^Q. */
453 #endif /* !TERMIOS_TTY_DRIVER */
454
455 #endif
456
457   return 0;
458 }
459
460 static void
461 prepare_terminal_settings (meta_flag, otio, tiop)
462      int meta_flag;
463      TIOTYPE otio, *tiop;
464 {
465   readline_echoing_p = (otio.c_lflag & ECHO);
466
467   tiop->c_lflag &= ~(ICANON | ECHO);
468
469   if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
470     _rl_eof_char = otio.c_cc[VEOF];
471
472 #if defined (USE_XON_XOFF)
473 #if defined (IXANY)
474   tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
475 #else
476   /* `strict' Posix systems do not define IXANY. */
477   tiop->c_iflag &= ~(IXON | IXOFF);
478 #endif /* IXANY */
479 #endif /* USE_XON_XOFF */
480
481   /* Only turn this off if we are using all 8 bits. */
482   if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
483     tiop->c_iflag &= ~(ISTRIP | INPCK);
484
485   /* Make sure we differentiate between CR and NL on input. */
486   tiop->c_iflag &= ~(ICRNL | INLCR);
487
488 #if !defined (HANDLE_SIGNALS)
489   tiop->c_lflag &= ~ISIG;
490 #else
491   tiop->c_lflag |= ISIG;
492 #endif
493
494   tiop->c_cc[VMIN] = 1;
495   tiop->c_cc[VTIME] = 0;
496
497 #if defined (FLUSHO)
498   if (OUTPUT_BEING_FLUSHED (tiop))
499     {
500       tiop->c_lflag &= ~FLUSHO;
501       otio.c_lflag &= ~FLUSHO;
502     }
503 #endif
504
505   /* Turn off characters that we need on Posix systems with job control,
506      just to be sure.  This includes ^Y and ^V.  This should not really
507      be necessary.  */
508 #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
509
510 #if defined (VLNEXT)
511   tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
512 #endif
513
514 #if defined (VDSUSP)
515   tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
516 #endif
517
518 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
519 }
520 #endif  /* NEW_TTY_DRIVER */
521
522 /* Put the terminal in CBREAK mode so that we can detect key presses. */
523 void
524 rl_prep_terminal (meta_flag)
525      int meta_flag;
526 {
527 #if !defined (__GO32__)
528   int tty;
529   TIOTYPE tio;
530
531   if (terminal_prepped)
532     return;
533
534   /* Try to keep this function from being INTerrupted. */
535   block_sigint ();
536
537   tty = fileno (rl_instream);
538
539   if (get_tty_settings (tty, &tio) < 0)
540     {
541       release_sigint ();
542       return;
543     }
544
545   otio = tio;
546
547   prepare_terminal_settings (meta_flag, otio, &tio);
548
549   if (set_tty_settings (tty, &tio) < 0)
550     {
551       release_sigint ();
552       return;
553     }
554
555   if (_rl_enable_keypad)
556     _rl_control_keypad (1);
557
558   fflush (rl_outstream);
559   terminal_prepped = 1;
560
561   release_sigint ();
562 #endif /* !__GO32__ */
563 }
564
565 /* Restore the terminal's normal settings and modes. */
566 void
567 rl_deprep_terminal ()
568 {
569 #if !defined (__GO32__)
570   int tty;
571
572   if (!terminal_prepped)
573     return;
574
575   /* Try to keep this function from being interrupted. */
576   block_sigint ();
577
578   tty = fileno (rl_instream);
579
580   if (_rl_enable_keypad)
581     _rl_control_keypad (0);
582
583   fflush (rl_outstream);
584
585   if (set_tty_settings (tty, &otio) < 0)
586     {
587       release_sigint ();
588       return;
589     }
590
591   terminal_prepped = 0;
592
593   release_sigint ();
594 #endif /* !__GO32__ */
595 }
596 \f
597 /* **************************************************************** */
598 /*                                                                  */
599 /*                      Bogus Flow Control                          */
600 /*                                                                  */
601 /* **************************************************************** */
602
603 int
604 rl_restart_output (count, key)
605      int count, key;
606 {
607   int fildes = fileno (rl_outstream);
608 #if defined (TIOCSTART)
609 #if defined (apollo)
610   ioctl (&fildes, TIOCSTART, 0);
611 #else
612   ioctl (fildes, TIOCSTART, 0);
613 #endif /* apollo */
614
615 #else /* !TIOCSTART */
616 #  if defined (TERMIOS_TTY_DRIVER)
617 #    if defined (__ksr1__)
618   if (ksrflow)
619     {
620       ksrflow = 0;
621       tcflow (fildes, TCOON);
622     }
623 #    else /* !ksr1 */
624   tcflow (fildes, TCOON);               /* Simulate a ^Q. */
625 #    endif /* !ksr1 */
626 #  else /* !TERMIOS_TTY_DRIVER */
627 #    if defined (TCXONC)
628   ioctl (fildes, TCXONC, TCOON);
629 #    endif /* TCXONC */
630 #  endif /* !TERMIOS_TTY_DRIVER */
631 #endif /* !TIOCSTART */
632
633   return 0;
634 }
635
636 int
637 rl_stop_output (count, key)
638      int count, key;
639 {
640   int fildes = fileno (rl_instream);
641
642 #if defined (TIOCSTOP)
643 # if defined (apollo)
644   ioctl (&fildes, TIOCSTOP, 0);
645 # else
646   ioctl (fildes, TIOCSTOP, 0);
647 # endif /* apollo */
648 #else /* !TIOCSTOP */
649 # if defined (TERMIOS_TTY_DRIVER)
650 #  if defined (__ksr1__)
651   ksrflow = 1;
652 #  endif /* ksr1 */
653   tcflow (fildes, TCOOFF);
654 # else
655 #   if defined (TCXONC)
656   ioctl (fildes, TCXONC, TCOON);
657 #   endif /* TCXONC */
658 # endif /* !TERMIOS_TTY_DRIVER */
659 #endif /* !TIOCSTOP */
660
661   return 0;
662 }
663
664 /* **************************************************************** */
665 /*                                                                  */
666 /*                      Default Key Bindings                        */
667 /*                                                                  */
668 /* **************************************************************** */
669 void
670 rltty_set_default_bindings (kmap)
671      Keymap kmap;
672 {
673   TIOTYPE ttybuff;
674   int tty = fileno (rl_instream);
675
676 #if defined (NEW_TTY_DRIVER)
677
678 #define SET_SPECIAL(sc, func) \
679   do \
680     { \
681       int ic; \
682       ic = sc; \
683       if (ic != -1 && kmap[ic].type == ISFUNC) \
684         kmap[ic].function = func; \
685     } \
686   while (0)
687
688   if (get_tty_settings (tty, &ttybuff) == 0)
689     {
690       if (ttybuff.flags & SGTTY_SET)
691         {
692           SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
693           SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
694         }
695
696 #  if defined (TIOCGLTC)
697       if (ttybuff.flags & LTCHARS_SET)
698         {
699           SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
700           SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
701         }
702 #  endif /* TIOCGLTC */
703     }
704
705 #else /* !NEW_TTY_DRIVER */
706
707 #define SET_SPECIAL(sc, func) \
708   do \
709     { \
710       unsigned char uc; \
711       uc = ttybuff.c_cc[sc]; \
712       if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
713         kmap[uc].function = func; \
714     } \
715   while (0)
716
717   if (get_tty_settings (tty, &ttybuff) == 0)
718     {
719       SET_SPECIAL (VERASE, rl_rubout);
720       SET_SPECIAL (VKILL, rl_unix_line_discard);
721
722 #  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
723       SET_SPECIAL (VLNEXT, rl_quoted_insert);
724 #  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
725
726 #  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
727       SET_SPECIAL (VWERASE, rl_unix_word_rubout);
728 #  endif /* VWERASE && TERMIOS_TTY_DRIVER */
729     }
730 #endif /* !NEW_TTY_DRIVER */
731 }