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