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