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