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    59 Temple Place, Suite 330, Boston, MA 02111 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 
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(tty)144 set_winsize (tty)
145      int tty;
146 {
147 #if defined (TIOCGWINSZ)
148   struct winsize w;
149 
150   if (ioctl (tty, TIOCGWINSZ, &w) == 0)
151       (void) ioctl (tty, TIOCSWINSZ, &w);
152 #endif /* TIOCGWINSZ */
153 }
154 
155 #if defined (NO_TTY_DRIVER)
156 /* Nothing */
157 #elif defined (NEW_TTY_DRIVER)
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 
167 struct 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 
181 static TIOTYPE otio;
182 
183 static void save_tty_chars PARAMS((TIOTYPE *));
184 static int _get_tty_settings PARAMS((int, TIOTYPE *));
185 static int get_tty_settings PARAMS((int, TIOTYPE *));
186 static int _set_tty_settings PARAMS((int, TIOTYPE *));
187 static int set_tty_settings PARAMS((int, TIOTYPE *));
188 
189 static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
190 
191 static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
192 
193 static void
save_tty_chars(tiop)194 save_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;
210       _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
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 
229 static int
get_tty_settings(tty,tiop)230 get_tty_settings (tty, tiop)
231      int tty;
232      TIOTYPE *tiop;
233 {
234   set_winsize (tty);
235 
236   tiop->flags = tiop->lflag = 0;
237 
238   errno = 0;
239   if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
240     return -1;
241   tiop->flags |= SGTTY_SET;
242 
243 #if defined (TIOCLGET)
244   if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
245     tiop->flags |= LFLAG_SET;
246 #endif
247 
248 #if defined (TIOCGETC)
249   if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
250     tiop->flags |= TCHARS_SET;
251 #endif
252 
253 #if defined (TIOCGLTC)
254   if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
255     tiop->flags |= LTCHARS_SET;
256 #endif
257 
258   return 0;
259 }
260 
261 static int
set_tty_settings(tty,tiop)262 set_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 
300 static void
prepare_terminal_settings(meta_flag,oldtio,tiop)301 prepare_terminal_settings (meta_flag, oldtio, tiop)
302      int meta_flag;
303      TIOTYPE oldtio, *tiop;
304 {
305   readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
306 
307   /* Copy the original settings to the structure we're going to use for
308      our settings. */
309   tiop->sgttyb = oldtio.sgttyb;
310   tiop->lflag = oldtio.lflag;
311 #if defined (TIOCGETC)
312   tiop->tchars = oldtio.tchars;
313 #endif
314 #if defined (TIOCGLTC)
315   tiop->ltchars = oldtio.ltchars;
316 #endif
317   tiop->flags = oldtio.flags;
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
330   if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
331       ((oldtio.sgttyb.sg_flags & ANYP) == 0))
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. */
350   if (oldtio.tchars.t_startc != -1)
351     rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
352 #  endif /* USE_XON_XOFF */
353 
354   /* If there is an EOF char, bind _rl_eof_char to it. */
355   if (oldtio.tchars.t_eofc != -1)
356     _rl_eof_char = oldtio.tchars.t_eofc;
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 */
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))
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 */
391 #else
392 #  define TIOTYPE struct termio
393 #  define DRAIN_OUTPUT(fd)
394 #  define GETATTR(tty, tiop)	(ioctl (tty, TCGETA, tiop))
395 #  define SETATTR(tty, tiop)	(ioctl (tty, TCSETAW, tiop))
396 #endif /* !TERMIOS_TTY_DRIVER */
397 
398 static TIOTYPE otio;
399 
400 static void save_tty_chars PARAMS((TIOTYPE *));
401 static int _get_tty_settings PARAMS((int, TIOTYPE *));
402 static int get_tty_settings PARAMS((int, TIOTYPE *));
403 static int _set_tty_settings PARAMS((int, TIOTYPE *));
404 static int set_tty_settings PARAMS((int, TIOTYPE *));
405 
406 static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
407 
408 static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
409 static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
410 
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 
417 static void
save_tty_chars(tiop)418 save_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 */
463 static void
rltty_warning(msg)464 rltty_warning (msg)
465      char *msg;
466 {
467   fprintf (stderr, "readline: warning: %s\n", msg);
468 }
469 #endif
470 
471 #if defined (_AIX)
472 void
setopost(tp)473 setopost(tp)
474 TIOTYPE *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 
484 static int
_get_tty_settings(tty,tiop)485 _get_tty_settings (tty, tiop)
486      int tty;
487      TIOTYPE *tiop;
488 {
489   int ioctl_ret;
490 
491   while (1)
492     {
493       ioctl_ret = GETATTR (tty, tiop);
494       if (ioctl_ret < 0)
495 	{
496 	  if (errno != EINTR)
497 	    return -1;
498 	  else
499 	    continue;
500 	}
501       if (OUTPUT_BEING_FLUSHED (tiop))
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;
512     }
513 
514   return 0;
515 }
516 
517 static int
get_tty_settings(tty,tiop)518 get_tty_settings (tty, tiop)
519      int tty;
520      TIOTYPE *tiop;
521 {
522   set_winsize (tty);
523 
524   errno = 0;
525   if (_get_tty_settings (tty, tiop) < 0)
526     return -1;
527 
528 #if defined (_AIX)
529   setopost(tiop);
530 #endif
531 
532   return 0;
533 }
534 
535 static int
_set_tty_settings(tty,tiop)536 _set_tty_settings (tty, tiop)
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     }
546   return 0;
547 }
548 
549 static int
set_tty_settings(tty,tiop)550 set_tty_settings (tty, tiop)
551      int tty;
552      TIOTYPE *tiop;
553 {
554   if (_set_tty_settings (tty, tiop) < 0)
555     return -1;
556 
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 
573 #endif /* 0 */
574 
575   return 0;
576 }
577 
578 static void
prepare_terminal_settings(meta_flag,oldtio,tiop)579 prepare_terminal_settings (meta_flag, oldtio, tiop)
580      int meta_flag;
581      TIOTYPE oldtio, *tiop;
582 {
583   readline_echoing_p = (oldtio.c_lflag & ECHO);
584 
585   tiop->c_lflag &= ~(ICANON | ECHO);
586 
587   if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
588     _rl_eof_char = oldtio.c_cc[VEOF];
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;
619       oldtio.c_lflag &= ~FLUSHO;
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 }
638 #endif  /* !NEW_TTY_DRIVER */
639 
640 /* Put the terminal in CBREAK mode so that we can detect key presses. */
641 #if defined (NO_TTY_DRIVER)
642 void
rl_prep_terminal(meta_flag)643 rl_prep_terminal (meta_flag)
644      int meta_flag;
645 {
646   readline_echoing_p = 1;
647 }
648 
649 void
rl_deprep_terminal()650 rl_deprep_terminal ()
651 {
652 }
653 
654 #else /* ! NO_TTY_DRIVER */
655 void
rl_prep_terminal(meta_flag)656 rl_prep_terminal (meta_flag)
657      int meta_flag;
658 {
659   int tty;
660   TIOTYPE tio;
661 
662   if (terminal_prepped)
663     return;
664 
665   /* Try to keep this function from being INTerrupted. */
666   block_sigint ();
667 
668   tty = fileno (rl_instream);
669 
670   if (get_tty_settings (tty, &tio) < 0)
671     {
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 */
679       release_sigint ();
680       return;
681     }
682 
683   otio = tio;
684 
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     }
696   save_tty_chars (&otio);
697   RL_SETSTATE(RL_STATE_TTYCSAVED);
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     }
709 
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 
718   if (_rl_enable_keypad)
719     _rl_control_keypad (1);
720 
721   fflush (rl_outstream);
722   terminal_prepped = 1;
723   RL_SETSTATE(RL_STATE_TERMPREPPED);
724 
725   release_sigint ();
726 }
727 
728 /* Restore the terminal's normal settings and modes. */
729 void
rl_deprep_terminal()730 rl_deprep_terminal ()
731 {
732   int tty;
733 
734   if (!terminal_prepped)
735     return;
736 
737   /* Try to keep this function from being interrupted. */
738   block_sigint ();
739 
740   tty = fileno (rl_instream);
741 
742   if (_rl_enable_keypad)
743     _rl_control_keypad (0);
744 
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;
754   RL_UNSETSTATE(RL_STATE_TERMPREPPED);
755 
756   release_sigint ();
757 }
758 #endif /* !NO_TTY_DRIVER */
759 
760 /* **************************************************************** */
761 /*								    */
762 /*			Bogus Flow Control      		    */
763 /*								    */
764 /* **************************************************************** */
765 
766 int
rl_restart_output(count,key)767 rl_restart_output (count, key)
768      int count, key;
769 {
770 #if defined (__MINGW32__)
771   return 0;
772 #else /* !__MING32__ */
773 
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;
801 #endif /* !__MINGW32__ */
802 }
803 
804 int
rl_stop_output(count,key)805 rl_stop_output (count, key)
806      int count, key;
807 {
808 #if defined (__MINGW32__)
809   return 0;
810 #else
811 
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;
834 #endif /* !__MINGW32__ */
835 }
836 
837 /* **************************************************************** */
838 /*								    */
839 /*			Default Key Bindings			    */
840 /*								    */
841 /* **************************************************************** */
842 
843 #if !defined (NO_TTY_DRIVER)
844 #define SET_SPECIAL(sc, func)	set_special_char(kmap, &ttybuff, sc, func)
845 #endif
846 
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)
853 static void
set_special_char(kmap,tiop,sc,func)854 set_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 }
863 
864 #define RESET_SPECIAL(c) \
865   if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
866     kmap[(unsigned char)c].function = rl_insert;
867 
868 static void
_rl_bind_tty_special_chars(kmap,ttybuff)869 _rl_bind_tty_special_chars (kmap, ttybuff)
870      Keymap kmap;
871      TIOTYPE ttybuff;
872 {
873   if (ttybuff.flags & SGTTY_SET)
874     {
875       SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
876       SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
877     }
878 
879 #  if defined (TIOCGLTC)
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);
884     }
885 #  endif /* TIOCGLTC */
886 }
887 
888 #else /* !NEW_TTY_DRIVER */
889 static void
set_special_char(kmap,tiop,sc,func)890 set_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;
897 
898   uc = tiop->c_cc[sc];
899   if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
900     kmap[uc].function = func;
901 }
902 
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 
908 static void
_rl_bind_tty_special_chars(kmap,ttybuff)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);
915 
916 #  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
917   SET_SPECIAL (VLNEXT, rl_quoted_insert);
918 #  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
919 
920 #  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
921   SET_SPECIAL (VWERASE, rl_unix_word_rubout);
922 #  endif /* VWERASE && TERMIOS_TTY_DRIVER */
923 }
924 
925 #endif /* !NEW_TTY_DRIVER */
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. */
929 void
rltty_set_default_bindings(kmap)930 rltty_set_default_bindings (kmap)
931      Keymap kmap;
932 {
933 #if !defined (NO_TTY_DRIVER)
934   TIOTYPE ttybuff;
935   int tty;
936 
937   tty = fileno (rl_instream);
938 
939   if (get_tty_settings (tty, &ttybuff) == 0)
940     _rl_bind_tty_special_chars (kmap, ttybuff);
941 #endif
942 }
943 
944 /* New public way to set the system default editing chars to their readline
945    equivalents. */
946 void
rl_tty_set_default_bindings(kmap)947 rl_tty_set_default_bindings (kmap)
948      Keymap kmap;
949 {
950   rltty_set_default_bindings (kmap);
951 }
952 
953 /* Rebind all of the tty special chars that readline worries about back
954    to self-insert.  Call this before saving the current terminal special
955    chars with save_tty_chars().  This only works on POSIX termios or termio
956    systems. */
957 void
rl_tty_unset_default_bindings(kmap)958 rl_tty_unset_default_bindings (kmap)
959      Keymap kmap;
960 {
961   /* Don't bother before we've saved the tty special chars at least once. */
962   if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
963     return;
964 
965   RESET_SPECIAL (_rl_tty_chars.t_erase);
966   RESET_SPECIAL (_rl_tty_chars.t_kill);
967 
968 #  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
969   RESET_SPECIAL (_rl_tty_chars.t_lnext);
970 #  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
971 
972 #  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
973   RESET_SPECIAL (_rl_tty_chars.t_werase);
974 #  endif /* VWERASE && TERMIOS_TTY_DRIVER */
975 }
976 
977 #if defined (HANDLE_SIGNALS)
978 
979 #if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
980 int
_rl_disable_tty_signals()981 _rl_disable_tty_signals ()
982 {
983   return 0;
984 }
985 
986 int
_rl_restore_tty_signals()987 _rl_restore_tty_signals ()
988 {
989   return 0;
990 }
991 #else
992 
993 static TIOTYPE sigstty, nosigstty;
994 static int tty_sigs_disabled = 0;
995 
996 int
_rl_disable_tty_signals()997 _rl_disable_tty_signals ()
998 {
999   if (tty_sigs_disabled)
1000     return 0;
1001 
1002   if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
1003     return -1;
1004 
1005   nosigstty = sigstty;
1006 
1007   nosigstty.c_lflag &= ~ISIG;
1008   nosigstty.c_iflag &= ~IXON;
1009 
1010   if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
1011     return (_set_tty_settings (fileno (rl_instream), &sigstty));
1012 
1013   tty_sigs_disabled = 1;
1014   return 0;
1015 }
1016 
1017 int
_rl_restore_tty_signals()1018 _rl_restore_tty_signals ()
1019 {
1020   int r;
1021 
1022   if (tty_sigs_disabled == 0)
1023     return 0;
1024 
1025   r = _set_tty_settings (fileno (rl_instream), &sigstty);
1026 
1027   if (r == 0)
1028     tty_sigs_disabled = 0;
1029 
1030   return r;
1031 }
1032 #endif /* !NEW_TTY_DRIVER */
1033 
1034 #endif /* HANDLE_SIGNALS */
1035