diff options
Diffstat (limited to 'bin/catsh/libedit/tty.c')
-rw-r--r-- | bin/catsh/libedit/tty.c | 1342 |
1 files changed, 0 insertions, 1342 deletions
diff --git a/bin/catsh/libedit/tty.c b/bin/catsh/libedit/tty.c deleted file mode 100644 index f524da47..00000000 --- a/bin/catsh/libedit/tty.c +++ /dev/null @@ -1,1342 +0,0 @@ -/* $NetBSD: tty.c,v 1.65 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: tty.c,v 1.65 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * tty.c: tty interface stuff - */ -#include <assert.h> -#include <errno.h> -#include <stdlib.h> /* for abort */ -#include <string.h> -#include <strings.h> /* for ffs */ -#include <unistd.h> /* for isatty */ - -#include "el.h" -#include "fcns.h" -#include "parse.h" - -typedef struct ttymodes_t { - const char *m_name; - unsigned int m_value; - int m_type; -} ttymodes_t; - -typedef struct ttymap_t { - wint_t nch, och; /* Internal and termio rep of chars */ - el_action_t bind[3]; /* emacs, vi, and vi-cmd */ -} ttymap_t; - - -static const ttyperm_t ttyperm = { - { - {"iflag:", ICRNL, (INLCR | IGNCR)}, - {"oflag:", (OPOST | ONLCR), ONLRET}, - {"cflag:", 0, 0}, - {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN), - (NOFLSH | ECHONL | EXTPROC | FLUSHO)}, - {"chars:", 0, 0}, - }, - { - {"iflag:", (INLCR | ICRNL), IGNCR}, - {"oflag:", (OPOST | ONLCR), ONLRET}, - {"cflag:", 0, 0}, - {"lflag:", ISIG, - (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)}, - {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) | - C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) | - C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0} - }, - { - {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL}, - {"oflag:", 0, 0}, - {"cflag:", 0, 0}, - {"lflag:", 0, ISIG | IEXTEN}, - {"chars:", 0, 0}, - } -}; - -static const ttychar_t ttychar = { - { - CINTR, CQUIT, CERASE, CKILL, - CEOF, CEOL, CEOL2, CSWTCH, - CDSWTCH, CERASE2, CSTART, CSTOP, - CWERASE, CSUSP, CDSUSP, CREPRINT, - CDISCARD, CLNEXT, CSTATUS, CPAGE, - CPGOFF, CKILL2, CBRK, CMIN, - CTIME - }, - { - CINTR, CQUIT, CERASE, CKILL, - _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, - _POSIX_VDISABLE, CERASE2, CSTART, CSTOP, - _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE, - CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, - _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1, - 0 - }, - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0 - } -}; - -static const ttymap_t tty_map[] = { -#ifdef VERASE - {C_ERASE, VERASE, - {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, -#endif /* VERASE */ -#ifdef VERASE2 - {C_ERASE2, VERASE2, - {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, -#endif /* VERASE2 */ -#ifdef VKILL - {C_KILL, VKILL, - {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, -#endif /* VKILL */ -#ifdef VKILL2 - {C_KILL2, VKILL2, - {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, -#endif /* VKILL2 */ -#ifdef VEOF - {C_EOF, VEOF, - {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}}, -#endif /* VEOF */ -#ifdef VWERASE - {C_WERASE, VWERASE, - {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}}, -#endif /* VWERASE */ -#ifdef VREPRINT - {C_REPRINT, VREPRINT, - {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}}, -#endif /* VREPRINT */ -#ifdef VLNEXT - {C_LNEXT, VLNEXT, - {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}}, -#endif /* VLNEXT */ - {(wint_t)-1, (wint_t)-1, - {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}} -}; - -static const ttymodes_t ttymodes[] = { -#ifdef IGNBRK - {"ignbrk", IGNBRK, MD_INP}, -#endif /* IGNBRK */ -#ifdef BRKINT - {"brkint", BRKINT, MD_INP}, -#endif /* BRKINT */ -#ifdef IGNPAR - {"ignpar", IGNPAR, MD_INP}, -#endif /* IGNPAR */ -#ifdef PARMRK - {"parmrk", PARMRK, MD_INP}, -#endif /* PARMRK */ -#ifdef INPCK - {"inpck", INPCK, MD_INP}, -#endif /* INPCK */ -#ifdef ISTRIP - {"istrip", ISTRIP, MD_INP}, -#endif /* ISTRIP */ -#ifdef INLCR - {"inlcr", INLCR, MD_INP}, -#endif /* INLCR */ -#ifdef IGNCR - {"igncr", IGNCR, MD_INP}, -#endif /* IGNCR */ -#ifdef ICRNL - {"icrnl", ICRNL, MD_INP}, -#endif /* ICRNL */ -#ifdef IUCLC - {"iuclc", IUCLC, MD_INP}, -#endif /* IUCLC */ -#ifdef IXON - {"ixon", IXON, MD_INP}, -#endif /* IXON */ -#ifdef IXANY - {"ixany", IXANY, MD_INP}, -#endif /* IXANY */ -#ifdef IXOFF - {"ixoff", IXOFF, MD_INP}, -#endif /* IXOFF */ -#ifdef IMAXBEL - {"imaxbel", IMAXBEL, MD_INP}, -#endif /* IMAXBEL */ - -#ifdef OPOST - {"opost", OPOST, MD_OUT}, -#endif /* OPOST */ -#ifdef OLCUC - {"olcuc", OLCUC, MD_OUT}, -#endif /* OLCUC */ -#ifdef ONLCR - {"onlcr", ONLCR, MD_OUT}, -#endif /* ONLCR */ -#ifdef OCRNL - {"ocrnl", OCRNL, MD_OUT}, -#endif /* OCRNL */ -#ifdef ONOCR - {"onocr", ONOCR, MD_OUT}, -#endif /* ONOCR */ -#ifdef ONOEOT - {"onoeot", ONOEOT, MD_OUT}, -#endif /* ONOEOT */ -#ifdef ONLRET - {"onlret", ONLRET, MD_OUT}, -#endif /* ONLRET */ -#ifdef OFILL - {"ofill", OFILL, MD_OUT}, -#endif /* OFILL */ -#ifdef OFDEL - {"ofdel", OFDEL, MD_OUT}, -#endif /* OFDEL */ -#ifdef NLDLY - {"nldly", NLDLY, MD_OUT}, -#endif /* NLDLY */ -#ifdef CRDLY - {"crdly", CRDLY, MD_OUT}, -#endif /* CRDLY */ -#ifdef TABDLY - {"tabdly", TABDLY, MD_OUT}, -#endif /* TABDLY */ -#ifdef XTABS - {"xtabs", XTABS, MD_OUT}, -#endif /* XTABS */ -#ifdef BSDLY - {"bsdly", BSDLY, MD_OUT}, -#endif /* BSDLY */ -#ifdef VTDLY - {"vtdly", VTDLY, MD_OUT}, -#endif /* VTDLY */ -#ifdef FFDLY - {"ffdly", FFDLY, MD_OUT}, -#endif /* FFDLY */ -#ifdef PAGEOUT - {"pageout", PAGEOUT, MD_OUT}, -#endif /* PAGEOUT */ -#ifdef WRAP - {"wrap", WRAP, MD_OUT}, -#endif /* WRAP */ - -#ifdef CIGNORE - {"cignore", CIGNORE, MD_CTL}, -#endif /* CBAUD */ -#ifdef CBAUD - {"cbaud", CBAUD, MD_CTL}, -#endif /* CBAUD */ -#ifdef CSTOPB - {"cstopb", CSTOPB, MD_CTL}, -#endif /* CSTOPB */ -#ifdef CREAD - {"cread", CREAD, MD_CTL}, -#endif /* CREAD */ -#ifdef PARENB - {"parenb", PARENB, MD_CTL}, -#endif /* PARENB */ -#ifdef PARODD - {"parodd", PARODD, MD_CTL}, -#endif /* PARODD */ -#ifdef HUPCL - {"hupcl", HUPCL, MD_CTL}, -#endif /* HUPCL */ -#ifdef CLOCAL - {"clocal", CLOCAL, MD_CTL}, -#endif /* CLOCAL */ -#ifdef LOBLK - {"loblk", LOBLK, MD_CTL}, -#endif /* LOBLK */ -#ifdef CIBAUD - {"cibaud", CIBAUD, MD_CTL}, -#endif /* CIBAUD */ -#ifdef CRTSCTS -#ifdef CCTS_OFLOW - {"ccts_oflow", CCTS_OFLOW, MD_CTL}, -#else - {"crtscts", CRTSCTS, MD_CTL}, -#endif /* CCTS_OFLOW */ -#endif /* CRTSCTS */ -#ifdef CRTS_IFLOW - {"crts_iflow", CRTS_IFLOW, MD_CTL}, -#endif /* CRTS_IFLOW */ -#ifdef CDTRCTS - {"cdtrcts", CDTRCTS, MD_CTL}, -#endif /* CDTRCTS */ -#ifdef MDMBUF - {"mdmbuf", MDMBUF, MD_CTL}, -#endif /* MDMBUF */ -#ifdef RCV1EN - {"rcv1en", RCV1EN, MD_CTL}, -#endif /* RCV1EN */ -#ifdef XMT1EN - {"xmt1en", XMT1EN, MD_CTL}, -#endif /* XMT1EN */ - -#ifdef ISIG - {"isig", ISIG, MD_LIN}, -#endif /* ISIG */ -#ifdef ICANON - {"icanon", ICANON, MD_LIN}, -#endif /* ICANON */ -#ifdef XCASE - {"xcase", XCASE, MD_LIN}, -#endif /* XCASE */ -#ifdef ECHO - {"echo", ECHO, MD_LIN}, -#endif /* ECHO */ -#ifdef ECHOE - {"echoe", ECHOE, MD_LIN}, -#endif /* ECHOE */ -#ifdef ECHOK - {"echok", ECHOK, MD_LIN}, -#endif /* ECHOK */ -#ifdef ECHONL - {"echonl", ECHONL, MD_LIN}, -#endif /* ECHONL */ -#ifdef NOFLSH - {"noflsh", NOFLSH, MD_LIN}, -#endif /* NOFLSH */ -#ifdef TOSTOP - {"tostop", TOSTOP, MD_LIN}, -#endif /* TOSTOP */ -#ifdef ECHOCTL - {"echoctl", ECHOCTL, MD_LIN}, -#endif /* ECHOCTL */ -#ifdef ECHOPRT - {"echoprt", ECHOPRT, MD_LIN}, -#endif /* ECHOPRT */ -#ifdef ECHOKE - {"echoke", ECHOKE, MD_LIN}, -#endif /* ECHOKE */ -#ifdef DEFECHO - {"defecho", DEFECHO, MD_LIN}, -#endif /* DEFECHO */ -#ifdef FLUSHO - {"flusho", FLUSHO, MD_LIN}, -#endif /* FLUSHO */ -#ifdef PENDIN - {"pendin", PENDIN, MD_LIN}, -#endif /* PENDIN */ -#ifdef IEXTEN - {"iexten", IEXTEN, MD_LIN}, -#endif /* IEXTEN */ -#ifdef NOKERNINFO - {"nokerninfo", NOKERNINFO, MD_LIN}, -#endif /* NOKERNINFO */ -#ifdef ALTWERASE - {"altwerase", ALTWERASE, MD_LIN}, -#endif /* ALTWERASE */ -#ifdef EXTPROC - {"extproc", EXTPROC, MD_LIN}, -#endif /* EXTPROC */ - -#if defined(VINTR) - {"intr", C_SH(C_INTR), MD_CHAR}, -#endif /* VINTR */ -#if defined(VQUIT) - {"quit", C_SH(C_QUIT), MD_CHAR}, -#endif /* VQUIT */ -#if defined(VERASE) - {"erase", C_SH(C_ERASE), MD_CHAR}, -#endif /* VERASE */ -#if defined(VKILL) - {"kill", C_SH(C_KILL), MD_CHAR}, -#endif /* VKILL */ -#if defined(VEOF) - {"eof", C_SH(C_EOF), MD_CHAR}, -#endif /* VEOF */ -#if defined(VEOL) - {"eol", C_SH(C_EOL), MD_CHAR}, -#endif /* VEOL */ -#if defined(VEOL2) - {"eol2", C_SH(C_EOL2), MD_CHAR}, -#endif /* VEOL2 */ -#if defined(VSWTCH) - {"swtch", C_SH(C_SWTCH), MD_CHAR}, -#endif /* VSWTCH */ -#if defined(VDSWTCH) - {"dswtch", C_SH(C_DSWTCH), MD_CHAR}, -#endif /* VDSWTCH */ -#if defined(VERASE2) - {"erase2", C_SH(C_ERASE2), MD_CHAR}, -#endif /* VERASE2 */ -#if defined(VSTART) - {"start", C_SH(C_START), MD_CHAR}, -#endif /* VSTART */ -#if defined(VSTOP) - {"stop", C_SH(C_STOP), MD_CHAR}, -#endif /* VSTOP */ -#if defined(VWERASE) - {"werase", C_SH(C_WERASE), MD_CHAR}, -#endif /* VWERASE */ -#if defined(VSUSP) - {"susp", C_SH(C_SUSP), MD_CHAR}, -#endif /* VSUSP */ -#if defined(VDSUSP) - {"dsusp", C_SH(C_DSUSP), MD_CHAR}, -#endif /* VDSUSP */ -#if defined(VREPRINT) - {"reprint", C_SH(C_REPRINT), MD_CHAR}, -#endif /* VREPRINT */ -#if defined(VDISCARD) - {"discard", C_SH(C_DISCARD), MD_CHAR}, -#endif /* VDISCARD */ -#if defined(VLNEXT) - {"lnext", C_SH(C_LNEXT), MD_CHAR}, -#endif /* VLNEXT */ -#if defined(VSTATUS) - {"status", C_SH(C_STATUS), MD_CHAR}, -#endif /* VSTATUS */ -#if defined(VPAGE) - {"page", C_SH(C_PAGE), MD_CHAR}, -#endif /* VPAGE */ -#if defined(VPGOFF) - {"pgoff", C_SH(C_PGOFF), MD_CHAR}, -#endif /* VPGOFF */ -#if defined(VKILL2) - {"kill2", C_SH(C_KILL2), MD_CHAR}, -#endif /* VKILL2 */ -#if defined(VBRK) - {"brk", C_SH(C_BRK), MD_CHAR}, -#endif /* VBRK */ -#if defined(VMIN) - {"min", C_SH(C_MIN), MD_CHAR}, -#endif /* VMIN */ -#if defined(VTIME) - {"time", C_SH(C_TIME), MD_CHAR}, -#endif /* VTIME */ - {NULL, 0, -1}, -}; - - - -#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) -#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) -#define tty__cooked_mode(td) ((td)->c_lflag & ICANON) - -static int tty_getty(EditLine *, struct termios *); -static int tty_setty(EditLine *, int, const struct termios *); -static int tty__getcharindex(int); -static void tty__getchar(struct termios *, unsigned char *); -static void tty__setchar(struct termios *, unsigned char *); -static speed_t tty__getspeed(struct termios *); -static int tty_setup(EditLine *); -static void tty_setup_flags(EditLine *, struct termios *, int); - -#define t_qu t_ts - -/* tty_getty(): - * Wrapper for tcgetattr to handle EINTR - */ -static int -tty_getty(EditLine *el, struct termios *t) -{ - int rv; - while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR) - continue; - return rv; -} - -/* tty_setty(): - * Wrapper for tcsetattr to handle EINTR - */ -static int -tty_setty(EditLine *el, int action, const struct termios *t) -{ - int rv; - while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR) - continue; - return rv; -} - -/* tty_setup(): - * Get the tty parameters and initialize the editing state - */ -static int -tty_setup(EditLine *el) -{ - int rst = 1; - - if (el->el_flags & EDIT_DISABLED) - return 0; - - if (el->el_tty.t_initialized) - return -1; - - if (!isatty(el->el_outfd)) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: isatty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - if (tty_getty(el, &el->el_tty.t_or) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or; - - el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); - el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); - el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); - - tty_setup_flags(el, &el->el_tty.t_ex, EX_IO); - - /* - * Reset the tty chars to reasonable defaults - * If they are disabled, then enable them. - */ - if (rst) { - if (tty__cooked_mode(&el->el_tty.t_ts)) { - tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); - /* - * Don't affect CMIN and CTIME for the editor mode - */ - for (rst = 0; rst < C_NCC - 2; rst++) - if (el->el_tty.t_c[TS_IO][rst] != - el->el_tty.t_vdisable - && el->el_tty.t_c[ED_IO][rst] != - el->el_tty.t_vdisable) - el->el_tty.t_c[ED_IO][rst] = - el->el_tty.t_c[TS_IO][rst]; - for (rst = 0; rst < C_NCC; rst++) - if (el->el_tty.t_c[TS_IO][rst] != - el->el_tty.t_vdisable) - el->el_tty.t_c[EX_IO][rst] = - el->el_tty.t_c[TS_IO][rst]; - } - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", - __func__, strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - } - - tty_setup_flags(el, &el->el_tty.t_ed, ED_IO); - - tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); - tty_bind_char(el, 1); - el->el_tty.t_initialized = 1; - return 0; -} - -libedit_private int -tty_init(EditLine *el) -{ - - el->el_tty.t_mode = EX_IO; - el->el_tty.t_vdisable = _POSIX_VDISABLE; - el->el_tty.t_initialized = 0; - (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); - (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); - return tty_setup(el); -} - - -/* tty_end(): - * Restore the tty to its original settings - */ -libedit_private void -/*ARGSUSED*/ -tty_end(EditLine *el) -{ - if (el->el_flags & EDIT_DISABLED) - return; - - if (!el->el_tty.t_initialized) - return; - - if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, - "%s: tty_setty: %s\n", __func__, strerror(errno)); -#endif /* DEBUG_TTY */ - } -} - - -/* tty__getspeed(): - * Get the tty speed - */ -static speed_t -tty__getspeed(struct termios *td) -{ - speed_t spd; - - if ((spd = cfgetispeed(td)) == 0) - spd = cfgetospeed(td); - return spd; -} - -/* tty__getspeed(): - * Return the index of the asked char in the c_cc array - */ -static int -tty__getcharindex(int i) -{ - switch (i) { -#ifdef VINTR - case C_INTR: - return VINTR; -#endif /* VINTR */ -#ifdef VQUIT - case C_QUIT: - return VQUIT; -#endif /* VQUIT */ -#ifdef VERASE - case C_ERASE: - return VERASE; -#endif /* VERASE */ -#ifdef VKILL - case C_KILL: - return VKILL; -#endif /* VKILL */ -#ifdef VEOF - case C_EOF: - return VEOF; -#endif /* VEOF */ -#ifdef VEOL - case C_EOL: - return VEOL; -#endif /* VEOL */ -#ifdef VEOL2 - case C_EOL2: - return VEOL2; -#endif /* VEOL2 */ -#ifdef VSWTCH - case C_SWTCH: - return VSWTCH; -#endif /* VSWTCH */ -#ifdef VDSWTCH - case C_DSWTCH: - return VDSWTCH; -#endif /* VDSWTCH */ -#ifdef VERASE2 - case C_ERASE2: - return VERASE2; -#endif /* VERASE2 */ -#ifdef VSTART - case C_START: - return VSTART; -#endif /* VSTART */ -#ifdef VSTOP - case C_STOP: - return VSTOP; -#endif /* VSTOP */ -#ifdef VWERASE - case C_WERASE: - return VWERASE; -#endif /* VWERASE */ -#ifdef VSUSP - case C_SUSP: - return VSUSP; -#endif /* VSUSP */ -#ifdef VDSUSP - case C_DSUSP: - return VDSUSP; -#endif /* VDSUSP */ -#ifdef VREPRINT - case C_REPRINT: - return VREPRINT; -#endif /* VREPRINT */ -#ifdef VDISCARD - case C_DISCARD: - return VDISCARD; -#endif /* VDISCARD */ -#ifdef VLNEXT - case C_LNEXT: - return VLNEXT; -#endif /* VLNEXT */ -#ifdef VSTATUS - case C_STATUS: - return VSTATUS; -#endif /* VSTATUS */ -#ifdef VPAGE - case C_PAGE: - return VPAGE; -#endif /* VPAGE */ -#ifdef VPGOFF - case C_PGOFF: - return VPGOFF; -#endif /* VPGOFF */ -#ifdef VKILL2 - case C_KILL2: - return VKILL2; -#endif /* KILL2 */ -#ifdef VMIN - case C_MIN: - return VMIN; -#endif /* VMIN */ -#ifdef VTIME - case C_TIME: - return VTIME; -#endif /* VTIME */ - default: - return -1; - } -} - -/* tty__getchar(): - * Get the tty characters - */ -static void -tty__getchar(struct termios *td, unsigned char *s) -{ - -#ifdef VINTR - s[C_INTR] = td->c_cc[VINTR]; -#endif /* VINTR */ -#ifdef VQUIT - s[C_QUIT] = td->c_cc[VQUIT]; -#endif /* VQUIT */ -#ifdef VERASE - s[C_ERASE] = td->c_cc[VERASE]; -#endif /* VERASE */ -#ifdef VKILL - s[C_KILL] = td->c_cc[VKILL]; -#endif /* VKILL */ -#ifdef VEOF - s[C_EOF] = td->c_cc[VEOF]; -#endif /* VEOF */ -#ifdef VEOL - s[C_EOL] = td->c_cc[VEOL]; -#endif /* VEOL */ -#ifdef VEOL2 - s[C_EOL2] = td->c_cc[VEOL2]; -#endif /* VEOL2 */ -#ifdef VSWTCH - s[C_SWTCH] = td->c_cc[VSWTCH]; -#endif /* VSWTCH */ -#ifdef VDSWTCH - s[C_DSWTCH] = td->c_cc[VDSWTCH]; -#endif /* VDSWTCH */ -#ifdef VERASE2 - s[C_ERASE2] = td->c_cc[VERASE2]; -#endif /* VERASE2 */ -#ifdef VSTART - s[C_START] = td->c_cc[VSTART]; -#endif /* VSTART */ -#ifdef VSTOP - s[C_STOP] = td->c_cc[VSTOP]; -#endif /* VSTOP */ -#ifdef VWERASE - s[C_WERASE] = td->c_cc[VWERASE]; -#endif /* VWERASE */ -#ifdef VSUSP - s[C_SUSP] = td->c_cc[VSUSP]; -#endif /* VSUSP */ -#ifdef VDSUSP - s[C_DSUSP] = td->c_cc[VDSUSP]; -#endif /* VDSUSP */ -#ifdef VREPRINT - s[C_REPRINT] = td->c_cc[VREPRINT]; -#endif /* VREPRINT */ -#ifdef VDISCARD - s[C_DISCARD] = td->c_cc[VDISCARD]; -#endif /* VDISCARD */ -#ifdef VLNEXT - s[C_LNEXT] = td->c_cc[VLNEXT]; -#endif /* VLNEXT */ -#ifdef VSTATUS - s[C_STATUS] = td->c_cc[VSTATUS]; -#endif /* VSTATUS */ -#ifdef VPAGE - s[C_PAGE] = td->c_cc[VPAGE]; -#endif /* VPAGE */ -#ifdef VPGOFF - s[C_PGOFF] = td->c_cc[VPGOFF]; -#endif /* VPGOFF */ -#ifdef VKILL2 - s[C_KILL2] = td->c_cc[VKILL2]; -#endif /* KILL2 */ -#ifdef VMIN - s[C_MIN] = td->c_cc[VMIN]; -#endif /* VMIN */ -#ifdef VTIME - s[C_TIME] = td->c_cc[VTIME]; -#endif /* VTIME */ -} /* tty__getchar */ - - -/* tty__setchar(): - * Set the tty characters - */ -static void -tty__setchar(struct termios *td, unsigned char *s) -{ - -#ifdef VINTR - td->c_cc[VINTR] = s[C_INTR]; -#endif /* VINTR */ -#ifdef VQUIT - td->c_cc[VQUIT] = s[C_QUIT]; -#endif /* VQUIT */ -#ifdef VERASE - td->c_cc[VERASE] = s[C_ERASE]; -#endif /* VERASE */ -#ifdef VKILL - td->c_cc[VKILL] = s[C_KILL]; -#endif /* VKILL */ -#ifdef VEOF - td->c_cc[VEOF] = s[C_EOF]; -#endif /* VEOF */ -#ifdef VEOL - td->c_cc[VEOL] = s[C_EOL]; -#endif /* VEOL */ -#ifdef VEOL2 - td->c_cc[VEOL2] = s[C_EOL2]; -#endif /* VEOL2 */ -#ifdef VSWTCH - td->c_cc[VSWTCH] = s[C_SWTCH]; -#endif /* VSWTCH */ -#ifdef VDSWTCH - td->c_cc[VDSWTCH] = s[C_DSWTCH]; -#endif /* VDSWTCH */ -#ifdef VERASE2 - td->c_cc[VERASE2] = s[C_ERASE2]; -#endif /* VERASE2 */ -#ifdef VSTART - td->c_cc[VSTART] = s[C_START]; -#endif /* VSTART */ -#ifdef VSTOP - td->c_cc[VSTOP] = s[C_STOP]; -#endif /* VSTOP */ -#ifdef VWERASE - td->c_cc[VWERASE] = s[C_WERASE]; -#endif /* VWERASE */ -#ifdef VSUSP - td->c_cc[VSUSP] = s[C_SUSP]; -#endif /* VSUSP */ -#ifdef VDSUSP - td->c_cc[VDSUSP] = s[C_DSUSP]; -#endif /* VDSUSP */ -#ifdef VREPRINT - td->c_cc[VREPRINT] = s[C_REPRINT]; -#endif /* VREPRINT */ -#ifdef VDISCARD - td->c_cc[VDISCARD] = s[C_DISCARD]; -#endif /* VDISCARD */ -#ifdef VLNEXT - td->c_cc[VLNEXT] = s[C_LNEXT]; -#endif /* VLNEXT */ -#ifdef VSTATUS - td->c_cc[VSTATUS] = s[C_STATUS]; -#endif /* VSTATUS */ -#ifdef VPAGE - td->c_cc[VPAGE] = s[C_PAGE]; -#endif /* VPAGE */ -#ifdef VPGOFF - td->c_cc[VPGOFF] = s[C_PGOFF]; -#endif /* VPGOFF */ -#ifdef VKILL2 - td->c_cc[VKILL2] = s[C_KILL2]; -#endif /* VKILL2 */ -#ifdef VMIN - td->c_cc[VMIN] = s[C_MIN]; -#endif /* VMIN */ -#ifdef VTIME - td->c_cc[VTIME] = s[C_TIME]; -#endif /* VTIME */ -} /* tty__setchar */ - - -/* tty_bind_char(): - * Rebind the editline functions - */ -libedit_private void -tty_bind_char(EditLine *el, int force) -{ - - unsigned char *t_n = el->el_tty.t_c[ED_IO]; - unsigned char *t_o = el->el_tty.t_ed.c_cc; - wchar_t new[2], old[2]; - const ttymap_t *tp; - el_action_t *map, *alt; - const el_action_t *dmap, *dalt; - new[1] = old[1] = '\0'; - - map = el->el_map.key; - alt = el->el_map.alt; - if (el->el_map.type == MAP_VI) { - dmap = el->el_map.vii; - dalt = el->el_map.vic; - } else { - dmap = el->el_map.emacs; - dalt = NULL; - } - - for (tp = tty_map; tp->nch != (wint_t)-1; tp++) { - new[0] = (wchar_t)t_n[tp->nch]; - old[0] = (wchar_t)t_o[tp->och]; - if (new[0] == old[0] && !force) - continue; - /* Put the old default binding back, and set the new binding */ - keymacro_clear(el, map, old); - map[(unsigned char)old[0]] = dmap[(unsigned char)old[0]]; - keymacro_clear(el, map, new); - /* MAP_VI == 1, MAP_EMACS == 0... */ - map[(unsigned char)new[0]] = tp->bind[el->el_map.type]; - if (dalt) { - keymacro_clear(el, alt, old); - alt[(unsigned char)old[0]] = - dalt[(unsigned char)old[0]]; - keymacro_clear(el, alt, new); - alt[(unsigned char)new[0]] = - tp->bind[el->el_map.type + 1]; - } - } -} - - -static tcflag_t * -tty__get_flag(struct termios *t, int kind) { - switch (kind) { - case MD_INP: - return &t->c_iflag; - case MD_OUT: - return &t->c_oflag; - case MD_CTL: - return &t->c_cflag; - case MD_LIN: - return &t->c_lflag; - default: - abort(); - /*NOTREACHED*/ - } -} - - -static tcflag_t -tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind) -{ - f &= ~el->el_tty.t_t[mode][kind].t_clrmask; - f |= el->el_tty.t_t[mode][kind].t_setmask; - return f; -} - - -static void -tty_update_flags(EditLine *el, int kind) -{ - tcflag_t *tt, *ed, *ex; - tt = tty__get_flag(&el->el_tty.t_ts, kind); - ed = tty__get_flag(&el->el_tty.t_ed, kind); - ex = tty__get_flag(&el->el_tty.t_ex, kind); - - if (*tt != *ex && (kind != MD_CTL || *tt != *ed)) { - *ed = tty_update_flag(el, *tt, ED_IO, kind); - *ex = tty_update_flag(el, *tt, EX_IO, kind); - } -} - - -static void -tty_update_char(EditLine *el, int mode, int c) { - if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c))) - && (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c])) - el->el_tty.t_c[mode][c] = el->el_tty.t_c[TS_IO][c]; - if (el->el_tty.t_t[mode][MD_CHAR].t_clrmask & C_SH(c)) - el->el_tty.t_c[mode][c] = el->el_tty.t_vdisable; -} - - -/* tty_rawmode(): - * Set terminal into 1 character at a time mode. - */ -libedit_private int -tty_rawmode(EditLine *el) -{ - - if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO) - return 0; - - if (el->el_flags & EDIT_DISABLED) - return 0; - - if (tty_getty(el, &el->el_tty.t_ts) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - /* - * We always keep up with the eight bit setting and the speed of the - * tty. But we only believe changes that are made to cooked mode! - */ - el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); - el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); - - if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed || - tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { - (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed); - (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed); - (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); - (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); - } - if (tty__cooked_mode(&el->el_tty.t_ts)) { - int i; - - for (i = MD_INP; i <= MD_LIN; i++) - tty_update_flags(el, i); - - if (tty__gettabs(&el->el_tty.t_ex) == 0) - el->el_tty.t_tabs = 0; - else - el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; - - tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); - /* - * Check if the user made any changes. - * If he did, then propagate the changes to the - * edit and execute data structures. - */ - for (i = 0; i < C_NCC; i++) - if (el->el_tty.t_c[TS_IO][i] != - el->el_tty.t_c[EX_IO][i]) - break; - - if (i != C_NCC) { - /* - * Propagate changes only to the unlibedit_private - * chars that have been modified just now. - */ - for (i = 0; i < C_NCC; i++) - tty_update_char(el, ED_IO, i); - - tty_bind_char(el, 0); - tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); - - for (i = 0; i < C_NCC; i++) - tty_update_char(el, EX_IO, i); - - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - } - } - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = ED_IO; - return 0; -} - - -/* tty_cookedmode(): - * Set the tty back to normal mode - */ -libedit_private int -tty_cookedmode(EditLine *el) -{ /* set tty in normal setup */ - - if (el->el_tty.t_mode == EX_IO) - return 0; - - if (el->el_flags & EDIT_DISABLED) - return 0; - - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = EX_IO; - return 0; -} - - -/* tty_quotemode(): - * Turn on quote mode - */ -libedit_private int -tty_quotemode(EditLine *el) -{ - if (el->el_tty.t_mode == QU_IO) - return 0; - - el->el_tty.t_qu = el->el_tty.t_ed; - - tty_setup_flags(el, &el->el_tty.t_qu, QU_IO); - - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = QU_IO; - return 0; -} - - -/* tty_noquotemode(): - * Turn off quote mode - */ -libedit_private int -tty_noquotemode(EditLine *el) -{ - - if (el->el_tty.t_mode != QU_IO) - return 0; - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = ED_IO; - return 0; -} - - -/* tty_stty(): - * Stty builtin - */ -libedit_private int -/*ARGSUSED*/ -tty_stty(EditLine *el, int argc __attribute__((__unused__)), - const wchar_t **argv) -{ - const ttymodes_t *m; - char x; - int aflag = 0; - const wchar_t *s, *d; - char name[EL_BUFSIZ]; - struct termios *tios = &el->el_tty.t_ex; - int z = EX_IO; - - if (argv == NULL) - return -1; - strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name)); - name[sizeof(name) - 1] = '\0'; - - while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') - switch (argv[0][1]) { - case 'a': - aflag++; - argv++; - break; - case 'd': - argv++; - tios = &el->el_tty.t_ed; - z = ED_IO; - break; - case 'x': - argv++; - tios = &el->el_tty.t_ex; - z = EX_IO; - break; - case 'q': - argv++; - tios = &el->el_tty.t_ts; - z = QU_IO; - break; - default: - (void) fprintf(el->el_errfile, - "%s: Unknown switch `%lc'.\n", - name, (wint_t)argv[0][1]); - return -1; - } - - if (!argv || !*argv) { - int i = -1; - size_t len = 0, st = 0, cu; - for (m = ttymodes; m->m_name; m++) { - if (m->m_type != i) { - (void) fprintf(el->el_outfile, "%s%s", - i != -1 ? "\n" : "", - el->el_tty.t_t[z][m->m_type].t_name); - i = m->m_type; - st = len = - strlen(el->el_tty.t_t[z][m->m_type].t_name); - } - if (i != -1) { - x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) - ? '+' : '\0'; - - if (el->el_tty.t_t[z][i].t_clrmask & m->m_value) - x = '-'; - } else { - x = '\0'; - } - - if (x != '\0' || aflag) { - - cu = strlen(m->m_name) + (x != '\0') + 1; - - if (len + cu >= - (size_t)el->el_terminal.t_size.h) { - (void) fprintf(el->el_outfile, "\n%*s", - (int)st, ""); - len = st + cu; - } else - len += cu; - - if (x != '\0') - (void) fprintf(el->el_outfile, "%c%s ", - x, m->m_name); - else - (void) fprintf(el->el_outfile, "%s ", - m->m_name); - } - } - (void) fprintf(el->el_outfile, "\n"); - return 0; - } - while (argv && (s = *argv++)) { - const wchar_t *p; - switch (*s) { - case '+': - case '-': - x = (char)*s++; - break; - default: - x = '\0'; - break; - } - d = s; - p = wcschr(s, L'='); - for (m = ttymodes; m->m_name; m++) - if ((p ? strncmp(m->m_name, ct_encode_string(d, - &el->el_scratch), (size_t)(p - d)) : - strcmp(m->m_name, ct_encode_string(d, - &el->el_scratch))) == 0 && - (p == NULL || m->m_type == MD_CHAR)) - break; - - if (!m->m_name) { - (void) fprintf(el->el_errfile, - "%s: Invalid argument `%ls'.\n", name, d); - return -1; - } - if (p) { - int c = ffs((int)m->m_value); - int v = *++p ? parse__escape(&p) : - el->el_tty.t_vdisable; - assert(c != 0); - c--; - c = tty__getcharindex(c); - assert(c != -1); - tios->c_cc[c] = (cc_t)v; - continue; - } - switch (x) { - case '+': - el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value; - el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; - break; - case '-': - el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; - el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value; - break; - default: - el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; - el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; - break; - } - } - - tty_setup_flags(el, tios, z); - if (el->el_tty.t_mode == z) { - if (tty_setty(el, TCSADRAIN, tios) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", - __func__, strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - } - - return 0; -} - - -#ifdef notyet -/* tty_printchar(): - * DEbugging routine to print the tty characters - */ -static void -tty_printchar(EditLine *el, unsigned char *s) -{ - ttyperm_t *m; - int i; - - for (i = 0; i < C_NCC; i++) { - for (m = el->el_tty.t_t; m->m_name; m++) - if (m->m_type == MD_CHAR && C_SH(i) == m->m_value) - break; - if (m->m_name) - (void) fprintf(el->el_errfile, "%s ^%c ", - m->m_name, s[i] + 'A' - 1); - if (i % 5 == 0) - (void) fprintf(el->el_errfile, "\n"); - } - (void) fprintf(el->el_errfile, "\n"); -} -#endif /* notyet */ - - -static void -tty_setup_flags(EditLine *el, struct termios *tios, int mode) -{ - int kind; - for (kind = MD_INP; kind <= MD_LIN; kind++) { - tcflag_t *f = tty__get_flag(tios, kind); - *f = tty_update_flag(el, *f, mode, kind); - } -} |