]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/rltty.c
Imported from ../bash-3.1.tar.gz.
[thirdparty/bash.git] / lib / readline / rltty.c
CommitLineData
726f6388
JA
1/* rltty.c -- functions to prepare and restore the terminal for readline's
2 use. */
3
95732b49 4/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
726f6388
JA
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
bb70624e 11 as published by the Free Software Foundation; either version 2, or
726f6388
JA
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,
bb70624e 22 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
726f6388
JA
23#define READLINE_LIBRARY
24
25#if defined (HAVE_CONFIG_H)
ccc6cda3 26# include <config.h>
726f6388
JA
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"
ccc6cda3 39
b72432fd 40#if defined (GWINSZ_IN_SYS_IOCTL)
ccc6cda3 41# include <sys/ioctl.h>
b72432fd 42#endif /* GWINSZ_IN_SYS_IOCTL */
ccc6cda3
JA
43
44#include "rltty.h"
726f6388 45#include "readline.h"
bb70624e 46#include "rlprivate.h"
726f6388
JA
47
48#if !defined (errno)
49extern int errno;
50#endif /* !errno */
51
28ef6c31
JA
52rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
53rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
ccc6cda3 54
f73dda09
JA
55static void block_sigint PARAMS((void));
56static void release_sigint PARAMS((void));
57
58static void set_winsize PARAMS((int));
59
726f6388
JA
60/* **************************************************************** */
61/* */
62/* Signal Management */
63/* */
64/* **************************************************************** */
65
66#if defined (HAVE_POSIX_SIGNALS)
67static sigset_t sigint_set, sigint_oset;
68#else /* !HAVE_POSIX_SIGNALS */
69# if defined (HAVE_BSD_SIGNALS)
70static int sigint_oldmask;
71# endif /* HAVE_BSD_SIGNALS */
72#endif /* !HAVE_POSIX_SIGNALS */
73
ccc6cda3 74static int sigint_blocked;
726f6388
JA
75
76/* Cause SIGINT to not be delivered until the corresponding call to
77 release_sigint(). */
78static void
79block_sigint ()
80{
81 if (sigint_blocked)
82 return;
83
84#if defined (HAVE_POSIX_SIGNALS)
85 sigemptyset (&sigint_set);
86 sigemptyset (&sigint_oset);
87 sigaddset (&sigint_set, SIGINT);
88 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
89#else /* !HAVE_POSIX_SIGNALS */
90# if defined (HAVE_BSD_SIGNALS)
91 sigint_oldmask = sigblock (sigmask (SIGINT));
92# else /* !HAVE_BSD_SIGNALS */
93# if defined (HAVE_USG_SIGHOLD)
94 sighold (SIGINT);
95# endif /* HAVE_USG_SIGHOLD */
96# endif /* !HAVE_BSD_SIGNALS */
97#endif /* !HAVE_POSIX_SIGNALS */
bb70624e 98
726f6388
JA
99 sigint_blocked = 1;
100}
101
102/* Allow SIGINT to be delivered. */
103static void
104release_sigint ()
105{
bb70624e 106 if (sigint_blocked == 0)
726f6388
JA
107 return;
108
109#if defined (HAVE_POSIX_SIGNALS)
110 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
111#else
112# if defined (HAVE_BSD_SIGNALS)
113 sigsetmask (sigint_oldmask);
114# else /* !HAVE_BSD_SIGNALS */
115# if defined (HAVE_USG_SIGHOLD)
116 sigrelse (SIGINT);
117# endif /* HAVE_USG_SIGHOLD */
118# endif /* !HAVE_BSD_SIGNALS */
119#endif /* !HAVE_POSIX_SIGNALS */
120
121 sigint_blocked = 0;
122}
123
726f6388
JA
124/* **************************************************************** */
125/* */
126/* Saving and Restoring the TTY */
127/* */
128/* **************************************************************** */
129
130/* Non-zero means that the terminal is in a prepped state. */
ccc6cda3 131static int terminal_prepped;
726f6388 132
bb70624e
JA
133static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
134
726f6388
JA
135/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
136 and output is suspended. */
137#if defined (__ksr1__)
ccc6cda3 138static int ksrflow;
726f6388 139#endif
ccc6cda3 140
ccc6cda3
JA
141/* Dummy call to force a backgrounded readline to stop before it tries
142 to get the tty settings. */
143static void
144set_winsize (tty)
145 int tty;
146{
bb70624e 147#if defined (TIOCGWINSZ)
ccc6cda3
JA
148 struct winsize w;
149
150 if (ioctl (tty, TIOCGWINSZ, &w) == 0)
151 (void) ioctl (tty, TIOCSWINSZ, &w);
b72432fd 152#endif /* TIOCGWINSZ */
bb70624e 153}
ccc6cda3 154
95732b49
JA
155#if defined (NO_TTY_DRIVER)
156/* Nothing */
157#elif defined (NEW_TTY_DRIVER)
726f6388
JA
158
159/* Values for the `flags' field of a struct bsdtty. This tells which
160 elements of the struct bsdtty have been fetched from the system and
161 are valid. */
162#define SGTTY_SET 0x01
163#define LFLAG_SET 0x02
164#define TCHARS_SET 0x04
165#define LTCHARS_SET 0x08
166
167struct bsdtty {
168 struct sgttyb sgttyb; /* Basic BSD tty driver information. */
169 int lflag; /* Local mode flags, like LPASS8. */
170#if defined (TIOCGETC)
171 struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
172#endif
173#if defined (TIOCGLTC)
174 struct ltchars ltchars; /* 4.2 BSD editing characters */
175#endif
176 int flags; /* Bitmap saying which parts of the struct are valid. */
177};
178
179#define TIOTYPE struct bsdtty
180
181static TIOTYPE otio;
182
f73dda09
JA
183static void save_tty_chars PARAMS((TIOTYPE *));
184static int _get_tty_settings PARAMS((int, TIOTYPE *));
185static int get_tty_settings PARAMS((int, TIOTYPE *));
186static int _set_tty_settings PARAMS((int, TIOTYPE *));
187static int set_tty_settings PARAMS((int, TIOTYPE *));
188
189static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
190
b80f6443
JA
191static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
192
bb70624e
JA
193static void
194save_tty_chars (tiop)
195 TIOTYPE *tiop;
196{
197 _rl_last_tty_chars = _rl_tty_chars;
198
199 if (tiop->flags & SGTTY_SET)
200 {
201 _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
202 _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
203 }
204
205 if (tiop->flags & TCHARS_SET)
206 {
207 _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
208 _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
209 _rl_tty_chars.t_start = tiop->tchars.t_startc;
28ef6c31 210 _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
bb70624e
JA
211 _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
212 _rl_tty_chars.t_eol = '\n';
213 _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
214 }
215
216 if (tiop->flags & LTCHARS_SET)
217 {
218 _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
219 _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
220 _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
221 _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
222 _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
223 _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
224 }
225
226 _rl_tty_chars.t_status = -1;
227}
228
726f6388
JA
229static int
230get_tty_settings (tty, tiop)
231 int tty;
232 TIOTYPE *tiop;
233{
ccc6cda3 234 set_winsize (tty);
726f6388
JA
235
236 tiop->flags = tiop->lflag = 0;
237
95732b49 238 errno = 0;
28ef6c31
JA
239 if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
240 return -1;
726f6388
JA
241 tiop->flags |= SGTTY_SET;
242
243#if defined (TIOCLGET)
28ef6c31
JA
244 if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
245 tiop->flags |= LFLAG_SET;
726f6388
JA
246#endif
247
248#if defined (TIOCGETC)
28ef6c31
JA
249 if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
250 tiop->flags |= TCHARS_SET;
726f6388
JA
251#endif
252
253#if defined (TIOCGLTC)
28ef6c31
JA
254 if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
255 tiop->flags |= LTCHARS_SET;
726f6388
JA
256#endif
257
258 return 0;
259}
260
ccc6cda3 261static int
726f6388
JA
262set_tty_settings (tty, tiop)
263 int tty;
264 TIOTYPE *tiop;
265{
266 if (tiop->flags & SGTTY_SET)
267 {
268 ioctl (tty, TIOCSETN, &(tiop->sgttyb));
269 tiop->flags &= ~SGTTY_SET;
270 }
271 readline_echoing_p = 1;
272
273#if defined (TIOCLSET)
274 if (tiop->flags & LFLAG_SET)
275 {
276 ioctl (tty, TIOCLSET, &(tiop->lflag));
277 tiop->flags &= ~LFLAG_SET;
278 }
279#endif
280
281#if defined (TIOCSETC)
282 if (tiop->flags & TCHARS_SET)
283 {
284 ioctl (tty, TIOCSETC, &(tiop->tchars));
285 tiop->flags &= ~TCHARS_SET;
286 }
287#endif
288
289#if defined (TIOCSLTC)
290 if (tiop->flags & LTCHARS_SET)
291 {
292 ioctl (tty, TIOCSLTC, &(tiop->ltchars));
293 tiop->flags &= ~LTCHARS_SET;
294 }
295#endif
296
297 return 0;
298}
299
300static void
28ef6c31 301prepare_terminal_settings (meta_flag, oldtio, tiop)
726f6388 302 int meta_flag;
28ef6c31 303 TIOTYPE oldtio, *tiop;
726f6388 304{
28ef6c31 305 readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
726f6388
JA
306
307 /* Copy the original settings to the structure we're going to use for
308 our settings. */
28ef6c31
JA
309 tiop->sgttyb = oldtio.sgttyb;
310 tiop->lflag = oldtio.lflag;
726f6388 311#if defined (TIOCGETC)
28ef6c31 312 tiop->tchars = oldtio.tchars;
726f6388
JA
313#endif
314#if defined (TIOCGLTC)
28ef6c31 315 tiop->ltchars = oldtio.ltchars;
726f6388 316#endif
28ef6c31 317 tiop->flags = oldtio.flags;
726f6388
JA
318
319 /* First, the basic settings to put us into character-at-a-time, no-echo
320 input mode. */
321 tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
322 tiop->sgttyb.sg_flags |= CBREAK;
323
324 /* If this terminal doesn't care how the 8th bit is used, then we can
325 use it for the meta-key. If only one of even or odd parity is
326 specified, then the terminal is using parity, and we cannot. */
327#if !defined (ANYP)
328# define ANYP (EVENP | ODDP)
329#endif
28ef6c31
JA
330 if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
331 ((oldtio.sgttyb.sg_flags & ANYP) == 0))
726f6388
JA
332 {
333 tiop->sgttyb.sg_flags |= ANYP;
334
335 /* Hack on local mode flags if we can. */
336#if defined (TIOCLGET)
337# if defined (LPASS8)
338 tiop->lflag |= LPASS8;
339# endif /* LPASS8 */
340#endif /* TIOCLGET */
341 }
342
343#if defined (TIOCGETC)
344# if defined (USE_XON_XOFF)
345 /* Get rid of terminal output start and stop characters. */
346 tiop->tchars.t_stopc = -1; /* C-s */
347 tiop->tchars.t_startc = -1; /* C-q */
348
349 /* If there is an XON character, bind it to restart the output. */
28ef6c31
JA
350 if (oldtio.tchars.t_startc != -1)
351 rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
726f6388
JA
352# endif /* USE_XON_XOFF */
353
354 /* If there is an EOF char, bind _rl_eof_char to it. */
28ef6c31
JA
355 if (oldtio.tchars.t_eofc != -1)
356 _rl_eof_char = oldtio.tchars.t_eofc;
726f6388
JA
357
358# if defined (NO_KILL_INTR)
359 /* Get rid of terminal-generated SIGQUIT and SIGINT. */
360 tiop->tchars.t_quitc = -1; /* C-\ */
361 tiop->tchars.t_intrc = -1; /* C-c */
362# endif /* NO_KILL_INTR */
363#endif /* TIOCGETC */
364
365#if defined (TIOCGLTC)
366 /* Make the interrupt keys go away. Just enough to make people happy. */
367 tiop->ltchars.t_dsuspc = -1; /* C-y */
368 tiop->ltchars.t_lnextc = -1; /* C-v */
369#endif /* TIOCGLTC */
726f6388
JA
370}
371
372#else /* !defined (NEW_TTY_DRIVER) */
373
374#if !defined (VMIN)
375# define VMIN VEOF
376#endif
377
378#if !defined (VTIME)
379# define VTIME VEOL
380#endif
381
382#if defined (TERMIOS_TTY_DRIVER)
383# define TIOTYPE struct termios
384# define DRAIN_OUTPUT(fd) tcdrain (fd)
385# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
ccc6cda3
JA
386# ifdef M_UNIX
387# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
388# else
389# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
390# endif /* !M_UNIX */
726f6388
JA
391#else
392# define TIOTYPE struct termio
393# define DRAIN_OUTPUT(fd)
394# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
28ef6c31 395# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
726f6388
JA
396#endif /* !TERMIOS_TTY_DRIVER */
397
398static TIOTYPE otio;
399
f73dda09
JA
400static void save_tty_chars PARAMS((TIOTYPE *));
401static int _get_tty_settings PARAMS((int, TIOTYPE *));
402static int get_tty_settings PARAMS((int, TIOTYPE *));
403static int _set_tty_settings PARAMS((int, TIOTYPE *));
404static int set_tty_settings PARAMS((int, TIOTYPE *));
405
406static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
407
b80f6443
JA
408static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
409static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
410
726f6388
JA
411#if defined (FLUSHO)
412# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
413#else
414# define OUTPUT_BEING_FLUSHED(tp) 0
415#endif
416
bb70624e
JA
417static void
418save_tty_chars (tiop)
419 TIOTYPE *tiop;
420{
421 _rl_last_tty_chars = _rl_tty_chars;
422
423 _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
424 _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
425#ifdef VEOL2
426 _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
427#endif
428 _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
429#ifdef VWERASE
430 _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
431#endif
432 _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
433#ifdef VREPRINT
434 _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
435#endif
436 _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
437 _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
438#ifdef VSUSP
439 _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
440#endif
441#ifdef VDSUSP
442 _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
443#endif
444#ifdef VSTART
445 _rl_tty_chars.t_start = tiop->c_cc[VSTART];
446#endif
447#ifdef VSTOP
448 _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
449#endif
450#ifdef VLNEXT
451 _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
452#endif
453#ifdef VDISCARD
454 _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
455#endif
456#ifdef VSTATUS
457 _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
458#endif
459}
460
461#if defined (_AIX) || defined (_AIX41)
462/* Currently this is only used on AIX */
ccc6cda3
JA
463static void
464rltty_warning (msg)
465 char *msg;
466{
467 fprintf (stderr, "readline: warning: %s\n", msg);
468}
bb70624e 469#endif
ccc6cda3
JA
470
471#if defined (_AIX)
472void
473setopost(tp)
474TIOTYPE *tp;
475{
476 if ((tp->c_oflag & OPOST) == 0)
477 {
478 rltty_warning ("turning on OPOST for terminal\r");
479 tp->c_oflag |= OPOST|ONLCR;
480 }
481}
482#endif
483
726f6388 484static int
bb70624e 485_get_tty_settings (tty, tiop)
726f6388
JA
486 int tty;
487 TIOTYPE *tiop;
488{
489 int ioctl_ret;
b72432fd 490
ccc6cda3 491 while (1)
726f6388 492 {
ccc6cda3
JA
493 ioctl_ret = GETATTR (tty, tiop);
494 if (ioctl_ret < 0)
495 {
496 if (errno != EINTR)
497 return -1;
498 else
499 continue;
500 }
726f6388 501 if (OUTPUT_BEING_FLUSHED (tiop))
ccc6cda3
JA
502 {
503#if defined (FLUSHO) && defined (_AIX41)
504 rltty_warning ("turning off output flushing");
505 tiop->c_lflag &= ~FLUSHO;
506 break;
507#else
508 continue;
509#endif
510 }
511 break;
726f6388 512 }
ccc6cda3 513
bb70624e
JA
514 return 0;
515}
516
517static int
518get_tty_settings (tty, tiop)
519 int tty;
520 TIOTYPE *tiop;
521{
522 set_winsize (tty);
523
95732b49 524 errno = 0;
bb70624e
JA
525 if (_get_tty_settings (tty, tiop) < 0)
526 return -1;
527
ccc6cda3
JA
528#if defined (_AIX)
529 setopost(tiop);
530#endif
531
726f6388
JA
532 return 0;
533}
534
535static int
bb70624e 536_set_tty_settings (tty, tiop)
726f6388
JA
537 int tty;
538 TIOTYPE *tiop;
539{
540 while (SETATTR (tty, tiop) < 0)
541 {
542 if (errno != EINTR)
543 return -1;
544 errno = 0;
545 }
bb70624e
JA
546 return 0;
547}
726f6388 548
bb70624e
JA
549static int
550set_tty_settings (tty, tiop)
551 int tty;
552 TIOTYPE *tiop;
553{
554 if (_set_tty_settings (tty, tiop) < 0)
555 return -1;
556
726f6388
JA
557#if 0
558
559#if defined (TERMIOS_TTY_DRIVER)
560# if defined (__ksr1__)
561 if (ksrflow)
562 {
563 ksrflow = 0;
564 tcflow (tty, TCOON);
565 }
566# else /* !ksr1 */
567 tcflow (tty, TCOON); /* Simulate a ^Q. */
568# endif /* !ksr1 */
569#else
570 ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
571#endif /* !TERMIOS_TTY_DRIVER */
572
bb70624e 573#endif /* 0 */
726f6388
JA
574
575 return 0;
576}
577
578static void
28ef6c31 579prepare_terminal_settings (meta_flag, oldtio, tiop)
726f6388 580 int meta_flag;
28ef6c31 581 TIOTYPE oldtio, *tiop;
726f6388 582{
28ef6c31 583 readline_echoing_p = (oldtio.c_lflag & ECHO);
726f6388
JA
584
585 tiop->c_lflag &= ~(ICANON | ECHO);
586
28ef6c31
JA
587 if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
588 _rl_eof_char = oldtio.c_cc[VEOF];
726f6388
JA
589
590#if defined (USE_XON_XOFF)
591#if defined (IXANY)
592 tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
593#else
594 /* `strict' Posix systems do not define IXANY. */
595 tiop->c_iflag &= ~(IXON | IXOFF);
596#endif /* IXANY */
597#endif /* USE_XON_XOFF */
598
599 /* Only turn this off if we are using all 8 bits. */
600 if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
601 tiop->c_iflag &= ~(ISTRIP | INPCK);
602
603 /* Make sure we differentiate between CR and NL on input. */
604 tiop->c_iflag &= ~(ICRNL | INLCR);
605
606#if !defined (HANDLE_SIGNALS)
607 tiop->c_lflag &= ~ISIG;
608#else
609 tiop->c_lflag |= ISIG;
610#endif
611
612 tiop->c_cc[VMIN] = 1;
613 tiop->c_cc[VTIME] = 0;
614
615#if defined (FLUSHO)
616 if (OUTPUT_BEING_FLUSHED (tiop))
617 {
618 tiop->c_lflag &= ~FLUSHO;
28ef6c31 619 oldtio.c_lflag &= ~FLUSHO;
726f6388
JA
620 }
621#endif
622
623 /* Turn off characters that we need on Posix systems with job control,
624 just to be sure. This includes ^Y and ^V. This should not really
625 be necessary. */
626#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
627
628#if defined (VLNEXT)
629 tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
630#endif
631
632#if defined (VDSUSP)
633 tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
634#endif
635
636#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
637}
95732b49 638#endif /* !NEW_TTY_DRIVER */
726f6388
JA
639
640/* Put the terminal in CBREAK mode so that we can detect key presses. */
95732b49
JA
641#if defined (NO_TTY_DRIVER)
642void
643rl_prep_terminal (meta_flag)
644 int meta_flag;
645{
646 readline_echoing_p = 1;
647}
648
649void
650rl_deprep_terminal ()
651{
652}
653
654#else /* ! NO_TTY_DRIVER */
726f6388
JA
655void
656rl_prep_terminal (meta_flag)
657 int meta_flag;
658{
ccc6cda3 659 int tty;
726f6388
JA
660 TIOTYPE tio;
661
662 if (terminal_prepped)
663 return;
664
665 /* Try to keep this function from being INTerrupted. */
666 block_sigint ();
667
ccc6cda3
JA
668 tty = fileno (rl_instream);
669
726f6388
JA
670 if (get_tty_settings (tty, &tio) < 0)
671 {
95732b49
JA
672#if defined (ENOTSUP)
673 /* MacOS X, at least, lies about the value of errno if tcgetattr fails. */
674 if (errno == ENOTTY || errno == ENOTSUP)
675#else
676 if (errno == ENOTTY)
677#endif
678 readline_echoing_p = 1; /* XXX */
726f6388
JA
679 release_sigint ();
680 return;
681 }
682
683 otio = tio;
684
95732b49
JA
685 if (_rl_bind_stty_chars)
686 {
687#if defined (VI_MODE)
688 /* If editing in vi mode, make sure we restore the bindings in the
689 insertion keymap no matter what keymap we ended up in. */
690 if (rl_editing_mode == vi_mode)
691 rl_tty_unset_default_bindings (vi_insertion_keymap);
692 else
693#endif
694 rl_tty_unset_default_bindings (_rl_keymap);
695 }
bb70624e 696 save_tty_chars (&otio);
b80f6443 697 RL_SETSTATE(RL_STATE_TTYCSAVED);
95732b49
JA
698 if (_rl_bind_stty_chars)
699 {
700#if defined (VI_MODE)
701 /* If editing in vi mode, make sure we set the bindings in the
702 insertion keymap no matter what keymap we ended up in. */
703 if (rl_editing_mode == vi_mode)
704 _rl_bind_tty_special_chars (vi_insertion_keymap, tio);
705 else
706#endif
707 _rl_bind_tty_special_chars (_rl_keymap, tio);
708 }
bb70624e 709
726f6388
JA
710 prepare_terminal_settings (meta_flag, otio, &tio);
711
712 if (set_tty_settings (tty, &tio) < 0)
713 {
714 release_sigint ();
715 return;
716 }
717
ccc6cda3
JA
718 if (_rl_enable_keypad)
719 _rl_control_keypad (1);
720
726f6388
JA
721 fflush (rl_outstream);
722 terminal_prepped = 1;
28ef6c31 723 RL_SETSTATE(RL_STATE_TERMPREPPED);
726f6388
JA
724
725 release_sigint ();
726f6388
JA
726}
727
728/* Restore the terminal's normal settings and modes. */
729void
730rl_deprep_terminal ()
731{
ccc6cda3 732 int tty;
726f6388
JA
733
734 if (!terminal_prepped)
735 return;
736
ccc6cda3 737 /* Try to keep this function from being interrupted. */
726f6388
JA
738 block_sigint ();
739
ccc6cda3
JA
740 tty = fileno (rl_instream);
741
742 if (_rl_enable_keypad)
743 _rl_control_keypad (0);
744
726f6388
JA
745 fflush (rl_outstream);
746
747 if (set_tty_settings (tty, &otio) < 0)
748 {
749 release_sigint ();
750 return;
751 }
752
753 terminal_prepped = 0;
28ef6c31 754 RL_UNSETSTATE(RL_STATE_TERMPREPPED);
726f6388
JA
755
756 release_sigint ();
726f6388 757}
95732b49 758#endif /* !NO_TTY_DRIVER */
726f6388
JA
759\f
760/* **************************************************************** */
761/* */
762/* Bogus Flow Control */
763/* */
764/* **************************************************************** */
765
ccc6cda3 766int
726f6388
JA
767rl_restart_output (count, key)
768 int count, key;
769{
95732b49
JA
770#if defined (__MINGW32__)
771 return 0;
772#else /* !__MING32__ */
773
726f6388
JA
774 int fildes = fileno (rl_outstream);
775#if defined (TIOCSTART)
776#if defined (apollo)
777 ioctl (&fildes, TIOCSTART, 0);
778#else
779 ioctl (fildes, TIOCSTART, 0);
780#endif /* apollo */
781
782#else /* !TIOCSTART */
783# if defined (TERMIOS_TTY_DRIVER)
784# if defined (__ksr1__)
785 if (ksrflow)
786 {
787 ksrflow = 0;
788 tcflow (fildes, TCOON);
789 }
790# else /* !ksr1 */
791 tcflow (fildes, TCOON); /* Simulate a ^Q. */
792# endif /* !ksr1 */
793# else /* !TERMIOS_TTY_DRIVER */
794# if defined (TCXONC)
795 ioctl (fildes, TCXONC, TCOON);
796# endif /* TCXONC */
797# endif /* !TERMIOS_TTY_DRIVER */
798#endif /* !TIOCSTART */
799
800 return 0;
95732b49 801#endif /* !__MINGW32__ */
726f6388
JA
802}
803
ccc6cda3 804int
726f6388
JA
805rl_stop_output (count, key)
806 int count, key;
807{
95732b49
JA
808#if defined (__MINGW32__)
809 return 0;
810#else
811
726f6388
JA
812 int fildes = fileno (rl_instream);
813
814#if defined (TIOCSTOP)
815# if defined (apollo)
816 ioctl (&fildes, TIOCSTOP, 0);
817# else
818 ioctl (fildes, TIOCSTOP, 0);
819# endif /* apollo */
820#else /* !TIOCSTOP */
821# if defined (TERMIOS_TTY_DRIVER)
822# if defined (__ksr1__)
823 ksrflow = 1;
824# endif /* ksr1 */
825 tcflow (fildes, TCOOFF);
826# else
827# if defined (TCXONC)
828 ioctl (fildes, TCXONC, TCOON);
829# endif /* TCXONC */
830# endif /* !TERMIOS_TTY_DRIVER */
831#endif /* !TIOCSTOP */
832
833 return 0;
95732b49 834#endif /* !__MINGW32__ */
726f6388 835}
ccc6cda3 836
726f6388
JA
837/* **************************************************************** */
838/* */
839/* Default Key Bindings */
840/* */
841/* **************************************************************** */
28ef6c31 842
95732b49 843#if !defined (NO_TTY_DRIVER)
b80f6443 844#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
95732b49 845#endif
726f6388 846
95732b49
JA
847#if defined (NO_TTY_DRIVER)
848
849#define SET_SPECIAL(sc, func)
850#define RESET_SPECIAL(c)
851
852#elif defined (NEW_TTY_DRIVER)
b80f6443
JA
853static void
854set_special_char (kmap, tiop, sc, func)
855 Keymap kmap;
856 TIOTYPE *tiop;
857 int sc;
858 rl_command_func_t *func;
859{
860 if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
861 kmap[(unsigned char)sc].function = func;
862}
726f6388 863
b80f6443
JA
864#define RESET_SPECIAL(c) \
865 if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
866 kmap[(unsigned char)c].function = rl_insert;
726f6388 867
b80f6443
JA
868static void
869_rl_bind_tty_special_chars (kmap, ttybuff)
870 Keymap kmap;
871 TIOTYPE ttybuff;
872{
873 if (ttybuff.flags & SGTTY_SET)
726f6388 874 {
b80f6443
JA
875 SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
876 SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
877 }
726f6388
JA
878
879# if defined (TIOCGLTC)
b80f6443
JA
880 if (ttybuff.flags & LTCHARS_SET)
881 {
882 SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
883 SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
726f6388 884 }
b80f6443
JA
885# endif /* TIOCGLTC */
886}
726f6388
JA
887
888#else /* !NEW_TTY_DRIVER */
b80f6443
JA
889static void
890set_special_char (kmap, tiop, sc, func)
891 Keymap kmap;
892 TIOTYPE *tiop;
893 int sc;
894 rl_command_func_t *func;
895{
896 unsigned char uc;
726f6388 897
b80f6443
JA
898 uc = tiop->c_cc[sc];
899 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
900 kmap[uc].function = func;
901}
726f6388 902
b80f6443
JA
903/* used later */
904#define RESET_SPECIAL(uc) \
905 if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
906 kmap[uc].function = rl_insert;
907
908static void
909_rl_bind_tty_special_chars (kmap, ttybuff)
910 Keymap kmap;
911 TIOTYPE ttybuff;
912{
913 SET_SPECIAL (VERASE, rl_rubout);
914 SET_SPECIAL (VKILL, rl_unix_line_discard);
726f6388
JA
915
916# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
b80f6443 917 SET_SPECIAL (VLNEXT, rl_quoted_insert);
726f6388
JA
918# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
919
920# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
b80f6443 921 SET_SPECIAL (VWERASE, rl_unix_word_rubout);
726f6388 922# endif /* VWERASE && TERMIOS_TTY_DRIVER */
b80f6443
JA
923}
924
726f6388 925#endif /* !NEW_TTY_DRIVER */
b80f6443
JA
926
927/* Set the system's default editing characters to their readline equivalents
928 in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
929void
930rltty_set_default_bindings (kmap)
931 Keymap kmap;
932{
95732b49 933#if !defined (NO_TTY_DRIVER)
b80f6443
JA
934 TIOTYPE ttybuff;
935 int tty;
936 static int called = 0;
937
938 tty = fileno (rl_instream);
939
940 if (get_tty_settings (tty, &ttybuff) == 0)
941 _rl_bind_tty_special_chars (kmap, ttybuff);
95732b49 942#endif
726f6388 943}
bb70624e 944
28ef6c31
JA
945/* New public way to set the system default editing chars to their readline
946 equivalents. */
947void
948rl_tty_set_default_bindings (kmap)
949 Keymap kmap;
950{
951 rltty_set_default_bindings (kmap);
952}
953
b80f6443
JA
954/* Rebind all of the tty special chars that readline worries about back
955 to self-insert. Call this before saving the current terminal special
956 chars with save_tty_chars(). This only works on POSIX termios or termio
957 systems. */
958void
959rl_tty_unset_default_bindings (kmap)
960 Keymap kmap;
961{
962 /* Don't bother before we've saved the tty special chars at least once. */
963 if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
964 return;
965
966 RESET_SPECIAL (_rl_tty_chars.t_erase);
967 RESET_SPECIAL (_rl_tty_chars.t_kill);
968
969# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
970 RESET_SPECIAL (_rl_tty_chars.t_lnext);
971# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
972
973# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
974 RESET_SPECIAL (_rl_tty_chars.t_werase);
975# endif /* VWERASE && TERMIOS_TTY_DRIVER */
976}
977
bb70624e
JA
978#if defined (HANDLE_SIGNALS)
979
95732b49 980#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
bb70624e
JA
981int
982_rl_disable_tty_signals ()
983{
984 return 0;
985}
986
987int
988_rl_restore_tty_signals ()
989{
990 return 0;
991}
992#else
993
994static TIOTYPE sigstty, nosigstty;
995static int tty_sigs_disabled = 0;
996
997int
998_rl_disable_tty_signals ()
999{
1000 if (tty_sigs_disabled)
1001 return 0;
1002
1003 if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
1004 return -1;
1005
1006 nosigstty = sigstty;
1007
1008 nosigstty.c_lflag &= ~ISIG;
f73dda09 1009 nosigstty.c_iflag &= ~IXON;
bb70624e
JA
1010
1011 if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
1012 return (_set_tty_settings (fileno (rl_instream), &sigstty));
1013
1014 tty_sigs_disabled = 1;
1015 return 0;
1016}
1017
1018int
1019_rl_restore_tty_signals ()
1020{
f73dda09
JA
1021 int r;
1022
bb70624e
JA
1023 if (tty_sigs_disabled == 0)
1024 return 0;
1025
f73dda09
JA
1026 r = _set_tty_settings (fileno (rl_instream), &sigstty);
1027
1028 if (r == 0)
1029 tty_sigs_disabled = 0;
1030
1031 return r;
bb70624e
JA
1032}
1033#endif /* !NEW_TTY_DRIVER */
1034
1035#endif /* HANDLE_SIGNALS */