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