📄 tty.c
字号:
/*- * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. 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. */#if !defined(lint) && !defined(SCCSID)static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";#endif /* not lint && not SCCSID *//* * tty.c: tty interface stuff */#include "sys.h"#include "tty.h"#include "el.h"typedef struct ttymodes_t { char *m_name; int m_value; int m_type;} ttymodes_t;typedef struct ttymap_t { int nch, och; /* Internal and termio rep of chars */ el_action_t bind[3]; /* emacs, vi, and vi-cmd */} ttymap_t;private 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 }, { "oflag:", 0, 0 }, { "cflag:", 0, 0 }, { "lflag:", 0, ISIG | IEXTEN }, { "chars:", 0, 0 }, }};private 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 }};private ttymap_t tty_map[] = {#ifdef VERASE { C_ERASE, VERASE, { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },#endif /* VERASE */#ifdef VERASE2 { C_ERASE2, VERASE2, { ED_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 */ { -1, -1, { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } } };private ttymodes_t ttymodes[] = {# ifdef IGNBRK { "ignbrk", IGNBRK, M_INP },# endif /* IGNBRK */# ifdef BRKINT { "brkint", BRKINT, M_INP },# endif /* BRKINT */# ifdef IGNPAR { "ignpar", IGNPAR, M_INP },# endif /* IGNPAR */# ifdef PARMRK { "parmrk", PARMRK, M_INP },# endif /* PARMRK */# ifdef INPCK { "inpck", INPCK, M_INP },# endif /* INPCK */# ifdef ISTRIP { "istrip", ISTRIP, M_INP },# endif /* ISTRIP */# ifdef INLCR { "inlcr", INLCR, M_INP },# endif /* INLCR */# ifdef IGNCR { "igncr", IGNCR, M_INP },# endif /* IGNCR */# ifdef ICRNL { "icrnl", ICRNL, M_INP },# endif /* ICRNL */# ifdef IUCLC { "iuclc", IUCLC, M_INP },# endif /* IUCLC */# ifdef IXON { "ixon", IXON, M_INP },# endif /* IXON */# ifdef IXANY { "ixany", IXANY, M_INP },# endif /* IXANY */# ifdef IXOFF { "ixoff", IXOFF, M_INP },# endif /* IXOFF */# ifdef IMAXBEL { "imaxbel",IMAXBEL,M_INP },# endif /* IMAXBEL */# ifdef OPOST { "opost", OPOST, M_OUT },# endif /* OPOST */# ifdef OLCUC { "olcuc", OLCUC, M_OUT },# endif /* OLCUC */# ifdef ONLCR { "onlcr", ONLCR, M_OUT },# endif /* ONLCR */# ifdef OCRNL { "ocrnl", OCRNL, M_OUT },# endif /* OCRNL */# ifdef ONOCR { "onocr", ONOCR, M_OUT },# endif /* ONOCR */# ifdef ONOEOT { "onoeot", ONOEOT, M_OUT },# endif /* ONOEOT */# ifdef ONLRET { "onlret", ONLRET, M_OUT },# endif /* ONLRET */# ifdef OFILL { "ofill", OFILL, M_OUT },# endif /* OFILL */# ifdef OFDEL { "ofdel", OFDEL, M_OUT },# endif /* OFDEL */# ifdef NLDLY { "nldly", NLDLY, M_OUT },# endif /* NLDLY */# ifdef CRDLY { "crdly", CRDLY, M_OUT },# endif /* CRDLY */# ifdef TABDLY { "tabdly", TABDLY, M_OUT },# endif /* TABDLY */# ifdef XTABS { "xtabs", XTABS, M_OUT },# endif /* XTABS */# ifdef BSDLY { "bsdly", BSDLY, M_OUT },# endif /* BSDLY */# ifdef VTDLY { "vtdly", VTDLY, M_OUT },# endif /* VTDLY */# ifdef FFDLY { "ffdly", FFDLY, M_OUT },# endif /* FFDLY */# ifdef PAGEOUT { "pageout",PAGEOUT,M_OUT },# endif /* PAGEOUT */# ifdef WRAP { "wrap", WRAP, M_OUT },# endif /* WRAP */# ifdef CIGNORE { "cignore",CIGNORE,M_CTL },# endif /* CBAUD */# ifdef CBAUD { "cbaud", CBAUD, M_CTL },# endif /* CBAUD */# ifdef CSTOPB { "cstopb", CSTOPB, M_CTL },# endif /* CSTOPB */# ifdef CREAD { "cread", CREAD, M_CTL },# endif /* CREAD */# ifdef PARENB { "parenb", PARENB, M_CTL },# endif /* PARENB */# ifdef PARODD { "parodd", PARODD, M_CTL },# endif /* PARODD */# ifdef HUPCL { "hupcl", HUPCL, M_CTL },# endif /* HUPCL */# ifdef CLOCAL { "clocal", CLOCAL, M_CTL },# endif /* CLOCAL */# ifdef LOBLK { "loblk", LOBLK, M_CTL },# endif /* LOBLK */# ifdef CIBAUD { "cibaud", CIBAUD, M_CTL },# endif /* CIBAUD */# ifdef CRTSCTS# ifdef CCTS_OFLOW { "ccts_oflow",CCTS_OFLOW,M_CTL },# else { "crtscts",CRTSCTS,M_CTL },# endif /* CCTS_OFLOW */# endif /* CRTSCTS */# ifdef CRTS_IFLOW { "crts_iflow",CRTS_IFLOW,M_CTL },# endif /* CRTS_IFLOW */# ifdef MDMBUF { "mdmbuf", MDMBUF, M_CTL },# endif /* MDMBUF */# ifdef RCV1EN { "rcv1en", RCV1EN, M_CTL },# endif /* RCV1EN */# ifdef XMT1EN { "xmt1en", XMT1EN, M_CTL },# endif /* XMT1EN */# ifdef ISIG { "isig", ISIG, M_LIN },# endif /* ISIG */# ifdef ICANON { "icanon", ICANON, M_LIN },# endif /* ICANON */# ifdef XCASE { "xcase", XCASE, M_LIN },# endif /* XCASE */# ifdef ECHO { "echo", ECHO, M_LIN },# endif /* ECHO */# ifdef ECHOE { "echoe", ECHOE, M_LIN },# endif /* ECHOE */# ifdef ECHOK { "echok", ECHOK, M_LIN },# endif /* ECHOK */# ifdef ECHONL { "echonl", ECHONL, M_LIN },# endif /* ECHONL */# ifdef NOFLSH { "noflsh", NOFLSH, M_LIN },# endif /* NOFLSH */# ifdef TOSTOP { "tostop", TOSTOP, M_LIN },# endif /* TOSTOP */# ifdef ECHOCTL { "echoctl",ECHOCTL,M_LIN },# endif /* ECHOCTL */# ifdef ECHOPRT { "echoprt",ECHOPRT,M_LIN },# endif /* ECHOPRT */# ifdef ECHOKE { "echoke", ECHOKE, M_LIN },# endif /* ECHOKE */# ifdef DEFECHO { "defecho",DEFECHO,M_LIN },# endif /* DEFECHO */# ifdef FLUSHO { "flusho", FLUSHO, M_LIN },# endif /* FLUSHO */# ifdef PENDIN { "pendin", PENDIN, M_LIN },# endif /* PENDIN */# ifdef IEXTEN { "iexten", IEXTEN, M_LIN },# endif /* IEXTEN */# ifdef NOKERNINFO { "nokerninfo",NOKERNINFO,M_LIN },# endif /* NOKERNINFO */# ifdef ALTWERASE { "altwerase",ALTWERASE,M_LIN },# endif /* ALTWERASE */# ifdef EXTPROC { "extproc",EXTPROC, M_LIN },# endif /* EXTPROC */# if defined(VINTR) { "intr", C_SH(C_INTR), M_CHAR },# endif /* VINTR */# if defined(VQUIT) { "quit", C_SH(C_QUIT), M_CHAR },# endif /* VQUIT */# if defined(VERASE) { "erase", C_SH(C_ERASE), M_CHAR },# endif /* VERASE */# if defined(VKILL) { "kill", C_SH(C_KILL), M_CHAR },# endif /* VKILL */# if defined(VEOF) { "eof", C_SH(C_EOF), M_CHAR },# endif /* VEOF */# if defined(VEOL) { "eol", C_SH(C_EOL), M_CHAR },# endif /* VEOL */# if defined(VEOL2) { "eol2", C_SH(C_EOL2), M_CHAR },# endif /* VEOL2 */# if defined(VSWTCH) { "swtch", C_SH(C_SWTCH), M_CHAR },# endif /* VSWTCH */# if defined(VDSWTCH) { "dswtch", C_SH(C_DSWTCH), M_CHAR },# endif /* VDSWTCH */# if defined(VERASE2) { "erase2", C_SH(C_ERASE2), M_CHAR },# endif /* VERASE2 */# if defined(VSTART) { "start", C_SH(C_START), M_CHAR },# endif /* VSTART */# if defined(VSTOP) { "stop", C_SH(C_STOP), M_CHAR },# endif /* VSTOP */# if defined(VWERASE) { "werase", C_SH(C_WERASE), M_CHAR },# endif /* VWERASE */# if defined(VSUSP) { "susp", C_SH(C_SUSP), M_CHAR },# endif /* VSUSP */# if defined(VDSUSP) { "dsusp", C_SH(C_DSUSP), M_CHAR },# endif /* VDSUSP */# if defined(VREPRINT) { "reprint", C_SH(C_REPRINT),M_CHAR },# endif /* VREPRINT */# if defined(VDISCARD) { "discard", C_SH(C_DISCARD),M_CHAR },# endif /* VDISCARD */# if defined(VLNEXT) { "lnext", C_SH(C_LNEXT), M_CHAR },# endif /* VLNEXT */# if defined(VSTATUS) { "status", C_SH(C_STATUS), M_CHAR },# endif /* VSTATUS */# if defined(VPAGE) { "page", C_SH(C_PAGE), M_CHAR },# endif /* VPAGE */# if defined(VPGOFF) { "pgoff", C_SH(C_PGOFF), M_CHAR },# endif /* VPGOFF */# if defined(VKILL2) { "kill2", C_SH(C_KILL2), M_CHAR },# endif /* VKILL2 */# if defined(VBRK) { "brk", C_SH(C_BRK), M_CHAR },# endif /* VBRK */# if defined(VMIN) { "min", C_SH(C_MIN), M_CHAR },# endif /* VMIN */# if defined(VTIME) { "time", C_SH(C_TIME), M_CHAR },# endif /* VTIME */ { NULL, 0, -1 },};#define tty_getty(el, td) tcgetattr((el)->el_infd, (td))#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) #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)private void tty__getchar __P((struct termios *, unsigned char *));private void tty__setchar __P((struct termios *, unsigned char *));private speed_t tty__getspeed __P((struct termios *));private int tty_setup __P((EditLine *));#define t_qu t_ts/* tty_setup(): * Get the tty parameters and initialize the editing state */private int tty_setup(el) EditLine *el;{ int rst = 1; if (tty_getty(el, &el->el_tty.t_ed) == -1) {#ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_setup: tty_getty: %s\n", 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_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); el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask; el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask; el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask; el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask; el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask; el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask; el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask; el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask; /* * 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_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, &el->el_tty.t_ex) == -1) {#ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n", strerror(errno));#endif /* DEBUG_TTY */ return(-1); } } else tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask; el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask; el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask; el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask; el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask; el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask; el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask; el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask; tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); return 0;}protected inttty_init(el) EditLine *el;{ el->el_tty.t_mode = EX_IO; el->el_tty.t_vdisable = _POSIX_VDISABLE; (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);} /* end tty_init *//* tty_end(): * Restore the tty to its original settings */protected void/*ARGSUSED*/tty_end(el) EditLine *el;{ /* XXX: Maybe reset to an initial state? */}/* tty__getspeed(): * Get the tty speed */private speed_ttty__getspeed(td) struct termios *td;{ speed_t spd; if ((spd = cfgetispeed(td)) == 0) spd = cfgetospeed(td); return spd;} /* end tty__getspeed */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -