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