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