* hppa-dis.c (print_insn_hppa): Handle 'g' operand.
[deliverable/binutils-gdb.git] / readline / rltty.c
CommitLineData
d60d9f65
SS
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
c862e87b 40#if defined (GWINSZ_IN_SYS_IOCTL)
d60d9f65 41# include <sys/ioctl.h>
c862e87b 42#endif /* GWINSZ_IN_SYS_IOCTL */
d60d9f65
SS
43
44#include "rltty.h"
45#include "readline.h"
46
47#if !defined (errno)
48extern int errno;
49#endif /* !errno */
50
51extern int readline_echoing_p;
52extern int _rl_eof_char;
53
54extern int _rl_enable_keypad, _rl_enable_meta;
55
56extern 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. */
64extern void rl_prep_terminal (), rl_deprep_terminal ();
65
66VFunction *rl_prep_term_function = rl_prep_terminal;
67VFunction *rl_deprep_term_function = rl_deprep_terminal;
68
69/* **************************************************************** */
70/* */
71/* Signal Management */
72/* */
73/* **************************************************************** */
74
75#if defined (HAVE_POSIX_SIGNALS)
76static sigset_t sigint_set, sigint_oset;
77#else /* !HAVE_POSIX_SIGNALS */
78# if defined (HAVE_BSD_SIGNALS)
79static int sigint_oldmask;
80# endif /* HAVE_BSD_SIGNALS */
81#endif /* !HAVE_POSIX_SIGNALS */
82
83static int sigint_blocked;
84
85/* Cause SIGINT to not be delivered until the corresponding call to
86 release_sigint(). */
87static void
88block_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. */
111static void
112release_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. */
139static 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__)
144static int ksrflow;
145#endif
146
c862e87b 147#if defined (TIOCGWINSZ)
d60d9f65
SS
148/* Dummy call to force a backgrounded readline to stop before it tries
149 to get the tty settings. */
150static void
151set_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}
c862e87b 159#endif /* TIOCGWINSZ */
d60d9f65
SS
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
171struct 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
185static TIOTYPE otio;
186
187static int
188get_tty_settings (tty, tiop)
189 int tty;
190 TIOTYPE *tiop;
191{
d1857004 192#if defined (TIOCGWINSZ)
d60d9f65 193 set_winsize (tty);
d1857004 194#endif
d60d9f65
SS
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
219static int
220set_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
258static void
259prepare_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
358static 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
366static void
367rltty_warning (msg)
368 char *msg;
369{
370 fprintf (stderr, "readline: warning: %s\n", msg);
371}
372
373#if defined (_AIX)
374void
375setopost(tp)
376TIOTYPE *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
386static int
387get_tty_settings (tty, tiop)
388 int tty;
389 TIOTYPE *tiop;
390{
391 int ioctl_ret;
c862e87b 392
d1857004 393#if defined (TIOCGWINSZ)
d60d9f65 394 set_winsize (tty);
d1857004 395#endif
d60d9f65
SS
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
427static int
428set_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
460static void
461prepare_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. */
523void
524rl_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. */
566void
567rl_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
603int
604rl_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
636int
637rl_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/* **************************************************************** */
669void
670rltty_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}
This page took 0.051562 seconds and 4 git commands to generate.