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