1
/* rltty.c -- functions to prepare and restore the terminal for readline's
4
/* Copyright (C) 1992 Free Software Foundation, Inc.
6
This file is part of the GNU Readline Library, a library for
7
reading lines of text with interactive input and history editing.
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.
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.
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
25
#if defined (HAVE_CONFIG_H)
29
#include <sys/types.h>
34
#if defined (HAVE_UNISTD_H)
36
#endif /* HAVE_UNISTD_H */
40
#if defined (GWINSZ_IN_SYS_IOCTL)
41
# include <sys/ioctl.h>
42
#endif /* GWINSZ_IN_SYS_IOCTL */
51
extern int readline_echoing_p;
52
extern int _rl_eof_char;
54
extern int _rl_enable_keypad, _rl_enable_meta;
56
extern void _rl_control_keypad ();
58
#if defined (__GO32__)
60
# undef HANDLE_SIGNALS
63
/* Indirect functions to allow apps control over terminal management. */
64
extern void rl_prep_terminal (), rl_deprep_terminal ();
66
VFunction *rl_prep_term_function = rl_prep_terminal;
67
VFunction *rl_deprep_term_function = rl_deprep_terminal;
69
/* **************************************************************** */
71
/* Signal Management */
73
/* **************************************************************** */
75
#if defined (HAVE_POSIX_SIGNALS)
76
static sigset_t sigint_set, sigint_oset;
77
#else /* !HAVE_POSIX_SIGNALS */
78
# if defined (HAVE_BSD_SIGNALS)
79
static int sigint_oldmask;
80
# endif /* HAVE_BSD_SIGNALS */
81
#endif /* !HAVE_POSIX_SIGNALS */
83
static int sigint_blocked;
85
/* Cause SIGINT to not be delivered until the corresponding call to
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)
104
# endif /* HAVE_USG_SIGHOLD */
105
# endif /* !HAVE_BSD_SIGNALS */
106
#endif /* !HAVE_POSIX_SIGNALS */
110
/* Allow SIGINT to be delivered. */
117
#if defined (HAVE_POSIX_SIGNALS)
118
sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
120
# if defined (HAVE_BSD_SIGNALS)
121
sigsetmask (sigint_oldmask);
122
# else /* !HAVE_BSD_SIGNALS */
123
# if defined (HAVE_USG_SIGHOLD)
125
# endif /* HAVE_USG_SIGHOLD */
126
# endif /* !HAVE_BSD_SIGNALS */
127
#endif /* !HAVE_POSIX_SIGNALS */
132
/* **************************************************************** */
134
/* Saving and Restoring the TTY */
136
/* **************************************************************** */
138
/* Non-zero means that the terminal is in a prepped state. */
139
static int terminal_prepped;
141
/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
142
and output is suspended. */
143
#if defined (__ksr1__)
147
#if defined (TIOCGWINSZ)
148
/* Dummy call to force a backgrounded readline to stop before it tries
149
to get the tty settings. */
156
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
157
(void) ioctl (tty, TIOCSWINSZ, &w);
159
#endif /* TIOCGWINSZ */
161
#if defined (NEW_TTY_DRIVER)
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
166
#define SGTTY_SET 0x01
167
#define LFLAG_SET 0x02
168
#define TCHARS_SET 0x04
169
#define LTCHARS_SET 0x08
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. */
177
#if defined (TIOCGLTC)
178
struct ltchars ltchars; /* 4.2 BSD editing characters */
180
int flags; /* Bitmap saying which parts of the struct are valid. */
183
#define TIOTYPE struct bsdtty
188
get_tty_settings (tty, tiop)
194
tiop->flags = tiop->lflag = 0;
196
ioctl (tty, TIOCGETP, &(tiop->sgttyb));
197
tiop->flags |= SGTTY_SET;
199
#if defined (TIOCLGET)
200
ioctl (tty, TIOCLGET, &(tiop->lflag));
201
tiop->flags |= LFLAG_SET;
204
#if defined (TIOCGETC)
205
ioctl (tty, TIOCGETC, &(tiop->tchars));
206
tiop->flags |= TCHARS_SET;
209
#if defined (TIOCGLTC)
210
ioctl (tty, TIOCGLTC, &(tiop->ltchars));
211
tiop->flags |= LTCHARS_SET;
218
set_tty_settings (tty, tiop)
222
if (tiop->flags & SGTTY_SET)
224
ioctl (tty, TIOCSETN, &(tiop->sgttyb));
225
tiop->flags &= ~SGTTY_SET;
227
readline_echoing_p = 1;
229
#if defined (TIOCLSET)
230
if (tiop->flags & LFLAG_SET)
232
ioctl (tty, TIOCLSET, &(tiop->lflag));
233
tiop->flags &= ~LFLAG_SET;
237
#if defined (TIOCSETC)
238
if (tiop->flags & TCHARS_SET)
240
ioctl (tty, TIOCSETC, &(tiop->tchars));
241
tiop->flags &= ~TCHARS_SET;
245
#if defined (TIOCSLTC)
246
if (tiop->flags & LTCHARS_SET)
248
ioctl (tty, TIOCSLTC, &(tiop->ltchars));
249
tiop->flags &= ~LTCHARS_SET;
257
prepare_terminal_settings (meta_flag, otio, tiop)
261
#if !defined (__GO32__)
262
readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
264
/* Copy the original settings to the structure we're going to use for
266
tiop->sgttyb = otio.sgttyb;
267
tiop->lflag = otio.lflag;
268
#if defined (TIOCGETC)
269
tiop->tchars = otio.tchars;
271
#if defined (TIOCGLTC)
272
tiop->ltchars = otio.ltchars;
274
tiop->flags = otio.flags;
276
/* First, the basic settings to put us into character-at-a-time, no-echo
278
tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
279
tiop->sgttyb.sg_flags |= CBREAK;
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. */
285
# define ANYP (EVENP | ODDP)
287
if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
288
((otio.sgttyb.sg_flags & ANYP) == 0))
290
tiop->sgttyb.sg_flags |= ANYP;
292
/* Hack on local mode flags if we can. */
293
#if defined (TIOCLGET)
294
# if defined (LPASS8)
295
tiop->lflag |= LPASS8;
297
#endif /* TIOCLGET */
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 */
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 */
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;
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 */
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__ */
330
#else /* !defined (NEW_TTY_DRIVER) */
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))
345
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
347
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
348
# endif /* !M_UNIX */
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 */
359
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
361
# define OUTPUT_BEING_FLUSHED(tp) 0
368
fprintf (stderr, "readline: warning: %s\n", msg);
376
if ((tp->c_oflag & OPOST) == 0)
378
rltty_warning ("turning on OPOST for terminal\r");
379
tp->c_oflag |= OPOST|ONLCR;
385
get_tty_settings (tty, tiop)
395
ioctl_ret = GETATTR (tty, tiop);
403
if (OUTPUT_BEING_FLUSHED (tiop))
405
#if defined (FLUSHO) && defined (_AIX41)
406
rltty_warning ("turning off output flushing");
407
tiop->c_lflag &= ~FLUSHO;
424
set_tty_settings (tty, tiop)
428
while (SETATTR (tty, tiop) < 0)
437
#if defined (TERMIOS_TTY_DRIVER)
438
# if defined (__ksr1__)
445
tcflow (tty, TCOON); /* Simulate a ^Q. */
448
ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
449
#endif /* !TERMIOS_TTY_DRIVER */
457
prepare_terminal_settings (meta_flag, otio, tiop)
461
readline_echoing_p = (otio.c_lflag & ECHO);
463
tiop->c_lflag &= ~(ICANON | ECHO);
465
if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
466
_rl_eof_char = otio.c_cc[VEOF];
468
#if defined (USE_XON_XOFF)
470
tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
472
/* `strict' Posix systems do not define IXANY. */
473
tiop->c_iflag &= ~(IXON | IXOFF);
475
#endif /* USE_XON_XOFF */
477
/* Only turn this off if we are using all 8 bits. */
478
if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
479
tiop->c_iflag &= ~(ISTRIP | INPCK);
481
/* Make sure we differentiate between CR and NL on input. */
482
tiop->c_iflag &= ~(ICRNL | INLCR);
484
#if !defined (HANDLE_SIGNALS)
485
tiop->c_lflag &= ~ISIG;
487
tiop->c_lflag |= ISIG;
490
tiop->c_cc[VMIN] = 1;
491
tiop->c_cc[VTIME] = 0;
494
if (OUTPUT_BEING_FLUSHED (tiop))
496
tiop->c_lflag &= ~FLUSHO;
497
otio.c_lflag &= ~FLUSHO;
501
/* Turn off characters that we need on Posix systems with job control,
502
just to be sure. This includes ^Y and ^V. This should not really
504
#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
507
tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
511
tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
514
#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
516
#endif /* NEW_TTY_DRIVER */
518
/* Put the terminal in CBREAK mode so that we can detect key presses. */
520
rl_prep_terminal (meta_flag)
523
#if !defined (__GO32__)
527
if (terminal_prepped)
530
/* Try to keep this function from being INTerrupted. */
533
tty = fileno (rl_instream);
535
if (get_tty_settings (tty, &tio) < 0)
543
prepare_terminal_settings (meta_flag, otio, &tio);
545
if (set_tty_settings (tty, &tio) < 0)
551
if (_rl_enable_keypad)
552
_rl_control_keypad (1);
554
fflush (rl_outstream);
555
terminal_prepped = 1;
558
#endif /* !__GO32__ */
561
/* Restore the terminal's normal settings and modes. */
563
rl_deprep_terminal ()
565
#if !defined (__GO32__)
568
if (!terminal_prepped)
571
/* Try to keep this function from being interrupted. */
574
tty = fileno (rl_instream);
576
if (_rl_enable_keypad)
577
_rl_control_keypad (0);
579
fflush (rl_outstream);
581
if (set_tty_settings (tty, &otio) < 0)
587
terminal_prepped = 0;
590
#endif /* !__GO32__ */
593
/* **************************************************************** */
595
/* Bogus Flow Control */
597
/* **************************************************************** */
600
rl_restart_output (count, key)
603
int fildes = fileno (rl_outstream);
604
#if defined (TIOCSTART)
606
ioctl (&fildes, TIOCSTART, 0);
608
ioctl (fildes, TIOCSTART, 0);
611
#else /* !TIOCSTART */
612
# if defined (TERMIOS_TTY_DRIVER)
613
# if defined (__ksr1__)
617
tcflow (fildes, TCOON);
620
tcflow (fildes, TCOON); /* Simulate a ^Q. */
622
# else /* !TERMIOS_TTY_DRIVER */
623
# if defined (TCXONC)
624
ioctl (fildes, TCXONC, TCOON);
626
# endif /* !TERMIOS_TTY_DRIVER */
627
#endif /* !TIOCSTART */
633
rl_stop_output (count, key)
636
int fildes = fileno (rl_instream);
638
#if defined (TIOCSTOP)
639
# if defined (apollo)
640
ioctl (&fildes, TIOCSTOP, 0);
642
ioctl (fildes, TIOCSTOP, 0);
644
#else /* !TIOCSTOP */
645
# if defined (TERMIOS_TTY_DRIVER)
646
# if defined (__ksr1__)
649
tcflow (fildes, TCOOFF);
651
# if defined (TCXONC)
652
ioctl (fildes, TCXONC, TCOON);
654
# endif /* !TERMIOS_TTY_DRIVER */
655
#endif /* !TIOCSTOP */
660
/* **************************************************************** */
662
/* Default Key Bindings */
664
/* **************************************************************** */
666
rltty_set_default_bindings (kmap)
670
int tty = fileno (rl_instream);
672
#if defined (NEW_TTY_DRIVER)
674
#define SET_SPECIAL(sc, func) \
679
if (ic != -1 && kmap[ic].type == ISFUNC) \
680
kmap[ic].function = func; \
684
if (get_tty_settings (tty, &ttybuff) == 0)
686
if (ttybuff.flags & SGTTY_SET)
688
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
689
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
692
# if defined (TIOCGLTC)
693
if (ttybuff.flags & LTCHARS_SET)
695
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
696
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
698
# endif /* TIOCGLTC */
701
#else /* !NEW_TTY_DRIVER */
703
#define SET_SPECIAL(sc, func) \
707
uc = ttybuff.c_cc[sc]; \
708
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
709
kmap[uc].function = func; \
713
if (get_tty_settings (tty, &ttybuff) == 0)
715
SET_SPECIAL (VERASE, rl_rubout);
716
SET_SPECIAL (VKILL, rl_unix_line_discard);
718
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
719
SET_SPECIAL (VLNEXT, rl_quoted_insert);
720
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
722
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
723
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
724
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
726
#endif /* !NEW_TTY_DRIVER */