11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1992, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Christos Zoulas of Cornell University. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 16148834Sstefanf * 3. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 3184260Sobrien * 32268782Spfg * $NetBSD: tty.c,v 1.31 2009/07/22 15:58:09 christos Exp $ 331573Srgrimes */ 341573Srgrimes 351573Srgrimes#if !defined(lint) && !defined(SCCSID) 361573Srgrimesstatic char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; 371573Srgrimes#endif /* not lint && not SCCSID */ 3884260Sobrien#include <sys/cdefs.h> 3984260Sobrien__FBSDID("$FreeBSD$"); 401573Srgrimes 418870Srgrimes/* 421573Srgrimes * tty.c: tty interface stuff 431573Srgrimes */ 44148834Sstefanf#include <assert.h> 451573Srgrimes#include "sys.h" 461573Srgrimes#include "tty.h" 471573Srgrimes#include "el.h" 481573Srgrimes 491573Srgrimestypedef struct ttymodes_t { 5084260Sobrien const char *m_name; 51148834Sstefanf unsigned int m_value; 5284260Sobrien int m_type; 5384260Sobrien} ttymodes_t; 541573Srgrimes 551573Srgrimestypedef struct ttymap_t { 5684260Sobrien int nch, och; /* Internal and termio rep of chars */ 5784260Sobrien el_action_t bind[3]; /* emacs, vi, and vi-cmd */ 58148834Sstefanf} ttymap_t; 591573Srgrimes 601573Srgrimes 6184260Sobrienprivate const ttyperm_t ttyperm = { 6284260Sobrien { 6384260Sobrien {"iflag:", ICRNL, (INLCR | IGNCR)}, 6484260Sobrien {"oflag:", (OPOST | ONLCR), ONLRET}, 6584260Sobrien {"cflag:", 0, 0}, 6684260Sobrien {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN), 6784260Sobrien (NOFLSH | ECHONL | EXTPROC | FLUSHO)}, 6884260Sobrien {"chars:", 0, 0}, 6984260Sobrien }, 7084260Sobrien { 7184260Sobrien {"iflag:", (INLCR | ICRNL), IGNCR}, 7284260Sobrien {"oflag:", (OPOST | ONLCR), ONLRET}, 7384260Sobrien {"cflag:", 0, 0}, 7484260Sobrien {"lflag:", ISIG, 7584260Sobrien (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)}, 7684260Sobrien {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) | 7784260Sobrien C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) | 7884260Sobrien C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0} 7984260Sobrien }, 8084260Sobrien { 8184260Sobrien {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL}, 8284260Sobrien {"oflag:", 0, 0}, 8384260Sobrien {"cflag:", 0, 0}, 8484260Sobrien {"lflag:", 0, ISIG | IEXTEN}, 8584260Sobrien {"chars:", 0, 0}, 8684260Sobrien } 871573Srgrimes}; 881573Srgrimes 8984260Sobrienprivate const ttychar_t ttychar = { 9084260Sobrien { 9184260Sobrien CINTR, CQUIT, CERASE, CKILL, 9284260Sobrien CEOF, CEOL, CEOL2, CSWTCH, 9384260Sobrien CDSWTCH, CERASE2, CSTART, CSTOP, 9484260Sobrien CWERASE, CSUSP, CDSUSP, CREPRINT, 9584260Sobrien CDISCARD, CLNEXT, CSTATUS, CPAGE, 9684260Sobrien CPGOFF, CKILL2, CBRK, CMIN, 9784260Sobrien CTIME 9884260Sobrien }, 9984260Sobrien { 10084260Sobrien CINTR, CQUIT, CERASE, CKILL, 10184260Sobrien _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 10284260Sobrien _POSIX_VDISABLE, CERASE2, CSTART, CSTOP, 10384260Sobrien _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE, 10484260Sobrien CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 10584260Sobrien _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1, 10684260Sobrien 0 10784260Sobrien }, 10884260Sobrien { 10984260Sobrien 0, 0, 0, 0, 11084260Sobrien 0, 0, 0, 0, 11184260Sobrien 0, 0, 0, 0, 11284260Sobrien 0, 0, 0, 0, 11384260Sobrien 0, 0, 0, 0, 11484260Sobrien 0, 0, 0, 0, 11584260Sobrien 0 11684260Sobrien } 1171573Srgrimes}; 1181573Srgrimes 11984260Sobrienprivate const ttymap_t tty_map[] = { 1201573Srgrimes#ifdef VERASE 12184260Sobrien {C_ERASE, VERASE, 122148834Sstefanf {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, 1231573Srgrimes#endif /* VERASE */ 1241573Srgrimes#ifdef VERASE2 12584260Sobrien {C_ERASE2, VERASE2, 126148834Sstefanf {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, 1271573Srgrimes#endif /* VERASE2 */ 1281573Srgrimes#ifdef VKILL 12984260Sobrien {C_KILL, VKILL, 13084260Sobrien {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, 1311573Srgrimes#endif /* VKILL */ 1321573Srgrimes#ifdef VKILL2 13384260Sobrien {C_KILL2, VKILL2, 13484260Sobrien {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, 1351573Srgrimes#endif /* VKILL2 */ 1361573Srgrimes#ifdef VEOF 13784260Sobrien {C_EOF, VEOF, 13884260Sobrien {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}}, 1391573Srgrimes#endif /* VEOF */ 1401573Srgrimes#ifdef VWERASE 14184260Sobrien {C_WERASE, VWERASE, 14284260Sobrien {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}}, 1431573Srgrimes#endif /* VWERASE */ 1441573Srgrimes#ifdef VREPRINT 14584260Sobrien {C_REPRINT, VREPRINT, 14684260Sobrien {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}}, 1471573Srgrimes#endif /* VREPRINT */ 1481573Srgrimes#ifdef VLNEXT 14984260Sobrien {C_LNEXT, VLNEXT, 15084260Sobrien {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}}, 1511573Srgrimes#endif /* VLNEXT */ 15284260Sobrien {-1, -1, 15384260Sobrien {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}} 15484260Sobrien}; 1551573Srgrimes 15684260Sobrienprivate const ttymodes_t ttymodes[] = { 15784260Sobrien#ifdef IGNBRK 15884260Sobrien {"ignbrk", IGNBRK, MD_INP}, 15984260Sobrien#endif /* IGNBRK */ 16084260Sobrien#ifdef BRKINT 16184260Sobrien {"brkint", BRKINT, MD_INP}, 16284260Sobrien#endif /* BRKINT */ 16384260Sobrien#ifdef IGNPAR 16484260Sobrien {"ignpar", IGNPAR, MD_INP}, 16584260Sobrien#endif /* IGNPAR */ 16684260Sobrien#ifdef PARMRK 16784260Sobrien {"parmrk", PARMRK, MD_INP}, 16884260Sobrien#endif /* PARMRK */ 16984260Sobrien#ifdef INPCK 17084260Sobrien {"inpck", INPCK, MD_INP}, 17184260Sobrien#endif /* INPCK */ 17284260Sobrien#ifdef ISTRIP 17384260Sobrien {"istrip", ISTRIP, MD_INP}, 17484260Sobrien#endif /* ISTRIP */ 17584260Sobrien#ifdef INLCR 17684260Sobrien {"inlcr", INLCR, MD_INP}, 17784260Sobrien#endif /* INLCR */ 17884260Sobrien#ifdef IGNCR 17984260Sobrien {"igncr", IGNCR, MD_INP}, 18084260Sobrien#endif /* IGNCR */ 18184260Sobrien#ifdef ICRNL 18284260Sobrien {"icrnl", ICRNL, MD_INP}, 18384260Sobrien#endif /* ICRNL */ 18484260Sobrien#ifdef IUCLC 18584260Sobrien {"iuclc", IUCLC, MD_INP}, 18684260Sobrien#endif /* IUCLC */ 18784260Sobrien#ifdef IXON 18884260Sobrien {"ixon", IXON, MD_INP}, 18984260Sobrien#endif /* IXON */ 19084260Sobrien#ifdef IXANY 19184260Sobrien {"ixany", IXANY, MD_INP}, 19284260Sobrien#endif /* IXANY */ 19384260Sobrien#ifdef IXOFF 19484260Sobrien {"ixoff", IXOFF, MD_INP}, 19584260Sobrien#endif /* IXOFF */ 19684260Sobrien#ifdef IMAXBEL 19784260Sobrien {"imaxbel", IMAXBEL, MD_INP}, 19884260Sobrien#endif /* IMAXBEL */ 1991573Srgrimes 20084260Sobrien#ifdef OPOST 20184260Sobrien {"opost", OPOST, MD_OUT}, 20284260Sobrien#endif /* OPOST */ 20384260Sobrien#ifdef OLCUC 20484260Sobrien {"olcuc", OLCUC, MD_OUT}, 20584260Sobrien#endif /* OLCUC */ 20684260Sobrien#ifdef ONLCR 20784260Sobrien {"onlcr", ONLCR, MD_OUT}, 20884260Sobrien#endif /* ONLCR */ 20984260Sobrien#ifdef OCRNL 21084260Sobrien {"ocrnl", OCRNL, MD_OUT}, 21184260Sobrien#endif /* OCRNL */ 21284260Sobrien#ifdef ONOCR 21384260Sobrien {"onocr", ONOCR, MD_OUT}, 21484260Sobrien#endif /* ONOCR */ 21584260Sobrien#ifdef ONOEOT 21684260Sobrien {"onoeot", ONOEOT, MD_OUT}, 21784260Sobrien#endif /* ONOEOT */ 21884260Sobrien#ifdef ONLRET 21984260Sobrien {"onlret", ONLRET, MD_OUT}, 22084260Sobrien#endif /* ONLRET */ 22184260Sobrien#ifdef OFILL 22284260Sobrien {"ofill", OFILL, MD_OUT}, 22384260Sobrien#endif /* OFILL */ 22484260Sobrien#ifdef OFDEL 22584260Sobrien {"ofdel", OFDEL, MD_OUT}, 22684260Sobrien#endif /* OFDEL */ 22784260Sobrien#ifdef NLDLY 22884260Sobrien {"nldly", NLDLY, MD_OUT}, 22984260Sobrien#endif /* NLDLY */ 23084260Sobrien#ifdef CRDLY 23184260Sobrien {"crdly", CRDLY, MD_OUT}, 23284260Sobrien#endif /* CRDLY */ 23384260Sobrien#ifdef TABDLY 23484260Sobrien {"tabdly", TABDLY, MD_OUT}, 23584260Sobrien#endif /* TABDLY */ 23684260Sobrien#ifdef XTABS 23784260Sobrien {"xtabs", XTABS, MD_OUT}, 23884260Sobrien#endif /* XTABS */ 23984260Sobrien#ifdef BSDLY 24084260Sobrien {"bsdly", BSDLY, MD_OUT}, 24184260Sobrien#endif /* BSDLY */ 24284260Sobrien#ifdef VTDLY 24384260Sobrien {"vtdly", VTDLY, MD_OUT}, 24484260Sobrien#endif /* VTDLY */ 24584260Sobrien#ifdef FFDLY 24684260Sobrien {"ffdly", FFDLY, MD_OUT}, 24784260Sobrien#endif /* FFDLY */ 24884260Sobrien#ifdef PAGEOUT 24984260Sobrien {"pageout", PAGEOUT, MD_OUT}, 25084260Sobrien#endif /* PAGEOUT */ 25184260Sobrien#ifdef WRAP 25284260Sobrien {"wrap", WRAP, MD_OUT}, 25384260Sobrien#endif /* WRAP */ 2541573Srgrimes 25584260Sobrien#ifdef CIGNORE 25684260Sobrien {"cignore", CIGNORE, MD_CTL}, 25784260Sobrien#endif /* CBAUD */ 25884260Sobrien#ifdef CBAUD 25984260Sobrien {"cbaud", CBAUD, MD_CTL}, 26084260Sobrien#endif /* CBAUD */ 26184260Sobrien#ifdef CSTOPB 26284260Sobrien {"cstopb", CSTOPB, MD_CTL}, 26384260Sobrien#endif /* CSTOPB */ 26484260Sobrien#ifdef CREAD 26584260Sobrien {"cread", CREAD, MD_CTL}, 26684260Sobrien#endif /* CREAD */ 26784260Sobrien#ifdef PARENB 26884260Sobrien {"parenb", PARENB, MD_CTL}, 26984260Sobrien#endif /* PARENB */ 27084260Sobrien#ifdef PARODD 27184260Sobrien {"parodd", PARODD, MD_CTL}, 27284260Sobrien#endif /* PARODD */ 27384260Sobrien#ifdef HUPCL 27484260Sobrien {"hupcl", HUPCL, MD_CTL}, 27584260Sobrien#endif /* HUPCL */ 27684260Sobrien#ifdef CLOCAL 27784260Sobrien {"clocal", CLOCAL, MD_CTL}, 27884260Sobrien#endif /* CLOCAL */ 27984260Sobrien#ifdef LOBLK 28084260Sobrien {"loblk", LOBLK, MD_CTL}, 28184260Sobrien#endif /* LOBLK */ 28284260Sobrien#ifdef CIBAUD 28384260Sobrien {"cibaud", CIBAUD, MD_CTL}, 28484260Sobrien#endif /* CIBAUD */ 28584260Sobrien#ifdef CRTSCTS 28684260Sobrien#ifdef CCTS_OFLOW 28784260Sobrien {"ccts_oflow", CCTS_OFLOW, MD_CTL}, 28884260Sobrien#else 28984260Sobrien {"crtscts", CRTSCTS, MD_CTL}, 29084260Sobrien#endif /* CCTS_OFLOW */ 29184260Sobrien#endif /* CRTSCTS */ 29284260Sobrien#ifdef CRTS_IFLOW 29384260Sobrien {"crts_iflow", CRTS_IFLOW, MD_CTL}, 29484260Sobrien#endif /* CRTS_IFLOW */ 29584260Sobrien#ifdef CDTRCTS 29684260Sobrien {"cdtrcts", CDTRCTS, MD_CTL}, 29784260Sobrien#endif /* CDTRCTS */ 29884260Sobrien#ifdef MDMBUF 29984260Sobrien {"mdmbuf", MDMBUF, MD_CTL}, 30084260Sobrien#endif /* MDMBUF */ 30184260Sobrien#ifdef RCV1EN 30284260Sobrien {"rcv1en", RCV1EN, MD_CTL}, 30384260Sobrien#endif /* RCV1EN */ 30484260Sobrien#ifdef XMT1EN 30584260Sobrien {"xmt1en", XMT1EN, MD_CTL}, 30684260Sobrien#endif /* XMT1EN */ 3071573Srgrimes 30884260Sobrien#ifdef ISIG 30984260Sobrien {"isig", ISIG, MD_LIN}, 31084260Sobrien#endif /* ISIG */ 31184260Sobrien#ifdef ICANON 31284260Sobrien {"icanon", ICANON, MD_LIN}, 31384260Sobrien#endif /* ICANON */ 31484260Sobrien#ifdef XCASE 31584260Sobrien {"xcase", XCASE, MD_LIN}, 31684260Sobrien#endif /* XCASE */ 31784260Sobrien#ifdef ECHO 31884260Sobrien {"echo", ECHO, MD_LIN}, 31984260Sobrien#endif /* ECHO */ 32084260Sobrien#ifdef ECHOE 32184260Sobrien {"echoe", ECHOE, MD_LIN}, 32284260Sobrien#endif /* ECHOE */ 32384260Sobrien#ifdef ECHOK 32484260Sobrien {"echok", ECHOK, MD_LIN}, 32584260Sobrien#endif /* ECHOK */ 32684260Sobrien#ifdef ECHONL 32784260Sobrien {"echonl", ECHONL, MD_LIN}, 32884260Sobrien#endif /* ECHONL */ 32984260Sobrien#ifdef NOFLSH 33084260Sobrien {"noflsh", NOFLSH, MD_LIN}, 33184260Sobrien#endif /* NOFLSH */ 33284260Sobrien#ifdef TOSTOP 33384260Sobrien {"tostop", TOSTOP, MD_LIN}, 33484260Sobrien#endif /* TOSTOP */ 33584260Sobrien#ifdef ECHOCTL 33684260Sobrien {"echoctl", ECHOCTL, MD_LIN}, 33784260Sobrien#endif /* ECHOCTL */ 33884260Sobrien#ifdef ECHOPRT 33984260Sobrien {"echoprt", ECHOPRT, MD_LIN}, 34084260Sobrien#endif /* ECHOPRT */ 34184260Sobrien#ifdef ECHOKE 34284260Sobrien {"echoke", ECHOKE, MD_LIN}, 34384260Sobrien#endif /* ECHOKE */ 34484260Sobrien#ifdef DEFECHO 34584260Sobrien {"defecho", DEFECHO, MD_LIN}, 34684260Sobrien#endif /* DEFECHO */ 34784260Sobrien#ifdef FLUSHO 34884260Sobrien {"flusho", FLUSHO, MD_LIN}, 34984260Sobrien#endif /* FLUSHO */ 35084260Sobrien#ifdef PENDIN 35184260Sobrien {"pendin", PENDIN, MD_LIN}, 35284260Sobrien#endif /* PENDIN */ 35384260Sobrien#ifdef IEXTEN 35484260Sobrien {"iexten", IEXTEN, MD_LIN}, 35584260Sobrien#endif /* IEXTEN */ 35684260Sobrien#ifdef NOKERNINFO 35784260Sobrien {"nokerninfo", NOKERNINFO, MD_LIN}, 35884260Sobrien#endif /* NOKERNINFO */ 35984260Sobrien#ifdef ALTWERASE 36084260Sobrien {"altwerase", ALTWERASE, MD_LIN}, 36184260Sobrien#endif /* ALTWERASE */ 36284260Sobrien#ifdef EXTPROC 36384260Sobrien {"extproc", EXTPROC, MD_LIN}, 36484260Sobrien#endif /* EXTPROC */ 3651573Srgrimes 36684260Sobrien#if defined(VINTR) 36784260Sobrien {"intr", C_SH(C_INTR), MD_CHAR}, 36884260Sobrien#endif /* VINTR */ 36984260Sobrien#if defined(VQUIT) 37084260Sobrien {"quit", C_SH(C_QUIT), MD_CHAR}, 37184260Sobrien#endif /* VQUIT */ 37284260Sobrien#if defined(VERASE) 37384260Sobrien {"erase", C_SH(C_ERASE), MD_CHAR}, 37484260Sobrien#endif /* VERASE */ 37584260Sobrien#if defined(VKILL) 37684260Sobrien {"kill", C_SH(C_KILL), MD_CHAR}, 37784260Sobrien#endif /* VKILL */ 37884260Sobrien#if defined(VEOF) 37984260Sobrien {"eof", C_SH(C_EOF), MD_CHAR}, 38084260Sobrien#endif /* VEOF */ 38184260Sobrien#if defined(VEOL) 38284260Sobrien {"eol", C_SH(C_EOL), MD_CHAR}, 38384260Sobrien#endif /* VEOL */ 38484260Sobrien#if defined(VEOL2) 38584260Sobrien {"eol2", C_SH(C_EOL2), MD_CHAR}, 38684260Sobrien#endif /* VEOL2 */ 38784260Sobrien#if defined(VSWTCH) 38884260Sobrien {"swtch", C_SH(C_SWTCH), MD_CHAR}, 38984260Sobrien#endif /* VSWTCH */ 39084260Sobrien#if defined(VDSWTCH) 39184260Sobrien {"dswtch", C_SH(C_DSWTCH), MD_CHAR}, 39284260Sobrien#endif /* VDSWTCH */ 39384260Sobrien#if defined(VERASE2) 39484260Sobrien {"erase2", C_SH(C_ERASE2), MD_CHAR}, 39584260Sobrien#endif /* VERASE2 */ 39684260Sobrien#if defined(VSTART) 39784260Sobrien {"start", C_SH(C_START), MD_CHAR}, 39884260Sobrien#endif /* VSTART */ 39984260Sobrien#if defined(VSTOP) 40084260Sobrien {"stop", C_SH(C_STOP), MD_CHAR}, 40184260Sobrien#endif /* VSTOP */ 40284260Sobrien#if defined(VWERASE) 40384260Sobrien {"werase", C_SH(C_WERASE), MD_CHAR}, 40484260Sobrien#endif /* VWERASE */ 40584260Sobrien#if defined(VSUSP) 40684260Sobrien {"susp", C_SH(C_SUSP), MD_CHAR}, 40784260Sobrien#endif /* VSUSP */ 40884260Sobrien#if defined(VDSUSP) 40984260Sobrien {"dsusp", C_SH(C_DSUSP), MD_CHAR}, 41084260Sobrien#endif /* VDSUSP */ 41184260Sobrien#if defined(VREPRINT) 41284260Sobrien {"reprint", C_SH(C_REPRINT), MD_CHAR}, 41384260Sobrien#endif /* VREPRINT */ 41484260Sobrien#if defined(VDISCARD) 41584260Sobrien {"discard", C_SH(C_DISCARD), MD_CHAR}, 41684260Sobrien#endif /* VDISCARD */ 41784260Sobrien#if defined(VLNEXT) 41884260Sobrien {"lnext", C_SH(C_LNEXT), MD_CHAR}, 41984260Sobrien#endif /* VLNEXT */ 42084260Sobrien#if defined(VSTATUS) 42184260Sobrien {"status", C_SH(C_STATUS), MD_CHAR}, 42284260Sobrien#endif /* VSTATUS */ 42384260Sobrien#if defined(VPAGE) 42484260Sobrien {"page", C_SH(C_PAGE), MD_CHAR}, 42584260Sobrien#endif /* VPAGE */ 42684260Sobrien#if defined(VPGOFF) 42784260Sobrien {"pgoff", C_SH(C_PGOFF), MD_CHAR}, 42884260Sobrien#endif /* VPGOFF */ 42984260Sobrien#if defined(VKILL2) 43084260Sobrien {"kill2", C_SH(C_KILL2), MD_CHAR}, 43184260Sobrien#endif /* VKILL2 */ 43284260Sobrien#if defined(VBRK) 43384260Sobrien {"brk", C_SH(C_BRK), MD_CHAR}, 43484260Sobrien#endif /* VBRK */ 43584260Sobrien#if defined(VMIN) 43684260Sobrien {"min", C_SH(C_MIN), MD_CHAR}, 43784260Sobrien#endif /* VMIN */ 43884260Sobrien#if defined(VTIME) 43984260Sobrien {"time", C_SH(C_TIME), MD_CHAR}, 44084260Sobrien#endif /* VTIME */ 44184260Sobrien {NULL, 0, -1}, 4421573Srgrimes}; 4431573Srgrimes 4441573Srgrimes 4451573Srgrimes 44684260Sobrien#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) 44784260Sobrien#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) 44884260Sobrien#define tty__cooked_mode(td) ((td)->c_lflag & ICANON) 4491573Srgrimes 450268782Spfgprivate int tty_getty(EditLine *, struct termios *); 451268782Spfgprivate int tty_setty(EditLine *, int, const struct termios *); 452148834Sstefanfprivate int tty__getcharindex(int); 45384260Sobrienprivate void tty__getchar(struct termios *, unsigned char *); 45484260Sobrienprivate void tty__setchar(struct termios *, unsigned char *); 45584260Sobrienprivate speed_t tty__getspeed(struct termios *); 45684260Sobrienprivate int tty_setup(EditLine *); 4571573Srgrimes 45884260Sobrien#define t_qu t_ts 4591573Srgrimes 460268782Spfg/* tty_getty(): 461268782Spfg * Wrapper for tcgetattr to handle EINTR 462268782Spfg */ 463268782Spfgprivate int 464268782Spfgtty_getty(EditLine *el, struct termios *t) 465268782Spfg{ 466268782Spfg int rv; 467268782Spfg while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR) 468268782Spfg continue; 469268782Spfg return rv; 470268782Spfg} 4711573Srgrimes 472268782Spfg/* tty_setty(): 473268782Spfg * Wrapper for tcsetattr to handle EINTR 474268782Spfg */ 475268782Spfgprivate int 476268782Spfgtty_setty(EditLine *el, int action, const struct termios *t) 477268782Spfg{ 478268782Spfg int rv; 479268782Spfg while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR) 480268782Spfg continue; 481268782Spfg return rv; 482268782Spfg} 483268782Spfg 4841573Srgrimes/* tty_setup(): 4851573Srgrimes * Get the tty parameters and initialize the editing state 4861573Srgrimes */ 4878870Srgrimesprivate int 48884260Sobrientty_setup(EditLine *el) 4891573Srgrimes{ 49084260Sobrien int rst = 1; 49184260Sobrien 49284260Sobrien if (el->el_flags & EDIT_DISABLED) 49384260Sobrien return (0); 49484260Sobrien 49584260Sobrien if (tty_getty(el, &el->el_tty.t_ed) == -1) { 4961573Srgrimes#ifdef DEBUG_TTY 49784260Sobrien (void) fprintf(el->el_errfile, 49884260Sobrien "tty_setup: tty_getty: %s\n", strerror(errno)); 4991573Srgrimes#endif /* DEBUG_TTY */ 50084260Sobrien return (-1); 50184260Sobrien } 50284260Sobrien el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; 5031573Srgrimes 50484260Sobrien el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); 50584260Sobrien el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); 50684260Sobrien el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); 5071573Srgrimes 50884260Sobrien /* 50984260Sobrien * Reset the tty chars to reasonable defaults 51084260Sobrien * If they are disabled, then enable them. 51184260Sobrien */ 51284260Sobrien if (rst) { 51384260Sobrien if (tty__cooked_mode(&el->el_tty.t_ts)) { 51484260Sobrien tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); 51584260Sobrien /* 51684260Sobrien * Don't affect CMIN and CTIME for the editor mode 51784260Sobrien */ 51884260Sobrien for (rst = 0; rst < C_NCC - 2; rst++) 51984260Sobrien if (el->el_tty.t_c[TS_IO][rst] != 52084260Sobrien el->el_tty.t_vdisable 52184260Sobrien && el->el_tty.t_c[ED_IO][rst] != 52284260Sobrien el->el_tty.t_vdisable) 52384260Sobrien el->el_tty.t_c[ED_IO][rst] = 52484260Sobrien el->el_tty.t_c[TS_IO][rst]; 52584260Sobrien for (rst = 0; rst < C_NCC; rst++) 52684260Sobrien if (el->el_tty.t_c[TS_IO][rst] != 52784260Sobrien el->el_tty.t_vdisable) 52884260Sobrien el->el_tty.t_c[EX_IO][rst] = 52984260Sobrien el->el_tty.t_c[TS_IO][rst]; 53084260Sobrien } 53184260Sobrien } 5321573Srgrimes 53384260Sobrien el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; 53484260Sobrien el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; 5351573Srgrimes 53684260Sobrien el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; 53784260Sobrien el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; 5381573Srgrimes 53984260Sobrien el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; 54084260Sobrien el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; 5411573Srgrimes 54284260Sobrien el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; 54384260Sobrien el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; 5441573Srgrimes 54584260Sobrien tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); 54684260Sobrien tty_bind_char(el, 1); 54784260Sobrien return (0); 5481573Srgrimes} 5491573Srgrimes 5501573Srgrimesprotected int 55184260Sobrientty_init(EditLine *el) 5521573Srgrimes{ 5531573Srgrimes 55484260Sobrien el->el_tty.t_mode = EX_IO; 55584260Sobrien el->el_tty.t_vdisable = _POSIX_VDISABLE; 55684260Sobrien (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); 55784260Sobrien (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); 55884260Sobrien return (tty_setup(el)); 55984260Sobrien} 5601573Srgrimes 56184260Sobrien 5621573Srgrimes/* tty_end(): 5631573Srgrimes * Restore the tty to its original settings 5641573Srgrimes */ 5651573Srgrimesprotected void 5661573Srgrimes/*ARGSUSED*/ 567148834Sstefanftty_end(EditLine *el __unused) 5681573Srgrimes{ 56984260Sobrien 57084260Sobrien /* XXX: Maybe reset to an initial state? */ 5711573Srgrimes} 5721573Srgrimes 5731573Srgrimes 5741573Srgrimes/* tty__getspeed(): 5751573Srgrimes * Get the tty speed 5761573Srgrimes */ 5771573Srgrimesprivate speed_t 57884260Sobrientty__getspeed(struct termios *td) 5791573Srgrimes{ 58084260Sobrien speed_t spd; 5811573Srgrimes 58284260Sobrien if ((spd = cfgetispeed(td)) == 0) 58384260Sobrien spd = cfgetospeed(td); 58484260Sobrien return (spd); 58584260Sobrien} 5861573Srgrimes 587148834Sstefanf/* tty__getspeed(): 588148834Sstefanf * Return the index of the asked char in the c_cc array 589148834Sstefanf */ 590148834Sstefanfprivate int 591148834Sstefanftty__getcharindex(int i) 592148834Sstefanf{ 593148834Sstefanf switch (i) { 594148834Sstefanf#ifdef VINTR 595148834Sstefanf case C_INTR: 596148834Sstefanf return VINTR; 597148834Sstefanf#endif /* VINTR */ 598148834Sstefanf#ifdef VQUIT 599148834Sstefanf case C_QUIT: 600148834Sstefanf return VQUIT; 601148834Sstefanf#endif /* VQUIT */ 602148834Sstefanf#ifdef VERASE 603148834Sstefanf case C_ERASE: 604148834Sstefanf return VERASE; 605148834Sstefanf#endif /* VERASE */ 606148834Sstefanf#ifdef VKILL 607148834Sstefanf case C_KILL: 608148834Sstefanf return VKILL; 609148834Sstefanf#endif /* VKILL */ 610148834Sstefanf#ifdef VEOF 611148834Sstefanf case C_EOF: 612148834Sstefanf return VEOF; 613148834Sstefanf#endif /* VEOF */ 614148834Sstefanf#ifdef VEOL 615148834Sstefanf case C_EOL: 616148834Sstefanf return VEOL; 617148834Sstefanf#endif /* VEOL */ 618148834Sstefanf#ifdef VEOL2 619148834Sstefanf case C_EOL2: 620148834Sstefanf return VEOL2; 621148834Sstefanf#endif /* VEOL2 */ 622148834Sstefanf#ifdef VSWTCH 623148834Sstefanf case C_SWTCH: 624148834Sstefanf return VSWTCH; 625148834Sstefanf#endif /* VSWTCH */ 626148834Sstefanf#ifdef VDSWTCH 627148834Sstefanf case C_DSWTCH: 628148834Sstefanf return VDSWTCH; 629148834Sstefanf#endif /* VDSWTCH */ 630148834Sstefanf#ifdef VERASE2 631148834Sstefanf case C_ERASE2: 632148834Sstefanf return VERASE2; 633148834Sstefanf#endif /* VERASE2 */ 634148834Sstefanf#ifdef VSTART 635148834Sstefanf case C_START: 636148834Sstefanf return VSTART; 637148834Sstefanf#endif /* VSTART */ 638148834Sstefanf#ifdef VSTOP 639148834Sstefanf case C_STOP: 640148834Sstefanf return VSTOP; 641148834Sstefanf#endif /* VSTOP */ 642148834Sstefanf#ifdef VWERASE 643148834Sstefanf case C_WERASE: 644148834Sstefanf return VWERASE; 645148834Sstefanf#endif /* VWERASE */ 646148834Sstefanf#ifdef VSUSP 647148834Sstefanf case C_SUSP: 648148834Sstefanf return VSUSP; 649148834Sstefanf#endif /* VSUSP */ 650148834Sstefanf#ifdef VDSUSP 651148834Sstefanf case C_DSUSP: 652148834Sstefanf return VDSUSP; 653148834Sstefanf#endif /* VDSUSP */ 654148834Sstefanf#ifdef VREPRINT 655148834Sstefanf case C_REPRINT: 656148834Sstefanf return VREPRINT; 657148834Sstefanf#endif /* VREPRINT */ 658148834Sstefanf#ifdef VDISCARD 659148834Sstefanf case C_DISCARD: 660148834Sstefanf return VDISCARD; 661148834Sstefanf#endif /* VDISCARD */ 662148834Sstefanf#ifdef VLNEXT 663148834Sstefanf case C_LNEXT: 664148834Sstefanf return VLNEXT; 665148834Sstefanf#endif /* VLNEXT */ 666148834Sstefanf#ifdef VSTATUS 667148834Sstefanf case C_STATUS: 668148834Sstefanf return VSTATUS; 669148834Sstefanf#endif /* VSTATUS */ 670148834Sstefanf#ifdef VPAGE 671148834Sstefanf case C_PAGE: 672148834Sstefanf return VPAGE; 673148834Sstefanf#endif /* VPAGE */ 674148834Sstefanf#ifdef VPGOFF 675148834Sstefanf case C_PGOFF: 676148834Sstefanf return VPGOFF; 677148834Sstefanf#endif /* VPGOFF */ 678148834Sstefanf#ifdef VKILL2 679148834Sstefanf case C_KILL2: 680148834Sstefanf return VKILL2; 681148834Sstefanf#endif /* KILL2 */ 682148834Sstefanf#ifdef VMIN 683148834Sstefanf case C_MIN: 684148834Sstefanf return VMIN; 685148834Sstefanf#endif /* VMIN */ 686148834Sstefanf#ifdef VTIME 687148834Sstefanf case C_TIME: 688148834Sstefanf return VTIME; 689148834Sstefanf#endif /* VTIME */ 690148834Sstefanf default: 691148834Sstefanf return -1; 692148834Sstefanf } 693148834Sstefanf} 6941573Srgrimes 6951573Srgrimes/* tty__getchar(): 6961573Srgrimes * Get the tty characters 6971573Srgrimes */ 6981573Srgrimesprivate void 69984260Sobrientty__getchar(struct termios *td, unsigned char *s) 7008870Srgrimes{ 7011573Srgrimes 70284260Sobrien#ifdef VINTR 70384260Sobrien s[C_INTR] = td->c_cc[VINTR]; 70484260Sobrien#endif /* VINTR */ 70584260Sobrien#ifdef VQUIT 70684260Sobrien s[C_QUIT] = td->c_cc[VQUIT]; 70784260Sobrien#endif /* VQUIT */ 70884260Sobrien#ifdef VERASE 70984260Sobrien s[C_ERASE] = td->c_cc[VERASE]; 71084260Sobrien#endif /* VERASE */ 71184260Sobrien#ifdef VKILL 71284260Sobrien s[C_KILL] = td->c_cc[VKILL]; 71384260Sobrien#endif /* VKILL */ 71484260Sobrien#ifdef VEOF 71584260Sobrien s[C_EOF] = td->c_cc[VEOF]; 71684260Sobrien#endif /* VEOF */ 71784260Sobrien#ifdef VEOL 71884260Sobrien s[C_EOL] = td->c_cc[VEOL]; 71984260Sobrien#endif /* VEOL */ 72084260Sobrien#ifdef VEOL2 72184260Sobrien s[C_EOL2] = td->c_cc[VEOL2]; 72284260Sobrien#endif /* VEOL2 */ 72384260Sobrien#ifdef VSWTCH 72484260Sobrien s[C_SWTCH] = td->c_cc[VSWTCH]; 72584260Sobrien#endif /* VSWTCH */ 72684260Sobrien#ifdef VDSWTCH 72784260Sobrien s[C_DSWTCH] = td->c_cc[VDSWTCH]; 72884260Sobrien#endif /* VDSWTCH */ 72984260Sobrien#ifdef VERASE2 73084260Sobrien s[C_ERASE2] = td->c_cc[VERASE2]; 73184260Sobrien#endif /* VERASE2 */ 73284260Sobrien#ifdef VSTART 73384260Sobrien s[C_START] = td->c_cc[VSTART]; 73484260Sobrien#endif /* VSTART */ 73584260Sobrien#ifdef VSTOP 73684260Sobrien s[C_STOP] = td->c_cc[VSTOP]; 73784260Sobrien#endif /* VSTOP */ 73884260Sobrien#ifdef VWERASE 73984260Sobrien s[C_WERASE] = td->c_cc[VWERASE]; 74084260Sobrien#endif /* VWERASE */ 74184260Sobrien#ifdef VSUSP 74284260Sobrien s[C_SUSP] = td->c_cc[VSUSP]; 74384260Sobrien#endif /* VSUSP */ 74484260Sobrien#ifdef VDSUSP 74584260Sobrien s[C_DSUSP] = td->c_cc[VDSUSP]; 74684260Sobrien#endif /* VDSUSP */ 74784260Sobrien#ifdef VREPRINT 74884260Sobrien s[C_REPRINT] = td->c_cc[VREPRINT]; 74984260Sobrien#endif /* VREPRINT */ 75084260Sobrien#ifdef VDISCARD 75184260Sobrien s[C_DISCARD] = td->c_cc[VDISCARD]; 75284260Sobrien#endif /* VDISCARD */ 75384260Sobrien#ifdef VLNEXT 75484260Sobrien s[C_LNEXT] = td->c_cc[VLNEXT]; 75584260Sobrien#endif /* VLNEXT */ 75684260Sobrien#ifdef VSTATUS 75784260Sobrien s[C_STATUS] = td->c_cc[VSTATUS]; 75884260Sobrien#endif /* VSTATUS */ 75984260Sobrien#ifdef VPAGE 76084260Sobrien s[C_PAGE] = td->c_cc[VPAGE]; 76184260Sobrien#endif /* VPAGE */ 76284260Sobrien#ifdef VPGOFF 76384260Sobrien s[C_PGOFF] = td->c_cc[VPGOFF]; 76484260Sobrien#endif /* VPGOFF */ 76584260Sobrien#ifdef VKILL2 76684260Sobrien s[C_KILL2] = td->c_cc[VKILL2]; 76784260Sobrien#endif /* KILL2 */ 76884260Sobrien#ifdef VMIN 76984260Sobrien s[C_MIN] = td->c_cc[VMIN]; 77084260Sobrien#endif /* VMIN */ 77184260Sobrien#ifdef VTIME 77284260Sobrien s[C_TIME] = td->c_cc[VTIME]; 77384260Sobrien#endif /* VTIME */ 77484260Sobrien} /* tty__getchar */ 7751573Srgrimes 77684260Sobrien 7771573Srgrimes/* tty__setchar(): 7781573Srgrimes * Set the tty characters 7791573Srgrimes */ 7801573Srgrimesprivate void 78184260Sobrientty__setchar(struct termios *td, unsigned char *s) 7828870Srgrimes{ 7831573Srgrimes 78484260Sobrien#ifdef VINTR 78584260Sobrien td->c_cc[VINTR] = s[C_INTR]; 78684260Sobrien#endif /* VINTR */ 78784260Sobrien#ifdef VQUIT 78884260Sobrien td->c_cc[VQUIT] = s[C_QUIT]; 78984260Sobrien#endif /* VQUIT */ 79084260Sobrien#ifdef VERASE 79184260Sobrien td->c_cc[VERASE] = s[C_ERASE]; 79284260Sobrien#endif /* VERASE */ 79384260Sobrien#ifdef VKILL 79484260Sobrien td->c_cc[VKILL] = s[C_KILL]; 79584260Sobrien#endif /* VKILL */ 79684260Sobrien#ifdef VEOF 79784260Sobrien td->c_cc[VEOF] = s[C_EOF]; 79884260Sobrien#endif /* VEOF */ 79984260Sobrien#ifdef VEOL 80084260Sobrien td->c_cc[VEOL] = s[C_EOL]; 80184260Sobrien#endif /* VEOL */ 80284260Sobrien#ifdef VEOL2 80384260Sobrien td->c_cc[VEOL2] = s[C_EOL2]; 80484260Sobrien#endif /* VEOL2 */ 80584260Sobrien#ifdef VSWTCH 80684260Sobrien td->c_cc[VSWTCH] = s[C_SWTCH]; 80784260Sobrien#endif /* VSWTCH */ 80884260Sobrien#ifdef VDSWTCH 80984260Sobrien td->c_cc[VDSWTCH] = s[C_DSWTCH]; 81084260Sobrien#endif /* VDSWTCH */ 81184260Sobrien#ifdef VERASE2 81284260Sobrien td->c_cc[VERASE2] = s[C_ERASE2]; 81384260Sobrien#endif /* VERASE2 */ 81484260Sobrien#ifdef VSTART 81584260Sobrien td->c_cc[VSTART] = s[C_START]; 81684260Sobrien#endif /* VSTART */ 81784260Sobrien#ifdef VSTOP 81884260Sobrien td->c_cc[VSTOP] = s[C_STOP]; 81984260Sobrien#endif /* VSTOP */ 82084260Sobrien#ifdef VWERASE 82184260Sobrien td->c_cc[VWERASE] = s[C_WERASE]; 82284260Sobrien#endif /* VWERASE */ 82384260Sobrien#ifdef VSUSP 82484260Sobrien td->c_cc[VSUSP] = s[C_SUSP]; 82584260Sobrien#endif /* VSUSP */ 82684260Sobrien#ifdef VDSUSP 82784260Sobrien td->c_cc[VDSUSP] = s[C_DSUSP]; 82884260Sobrien#endif /* VDSUSP */ 82984260Sobrien#ifdef VREPRINT 83084260Sobrien td->c_cc[VREPRINT] = s[C_REPRINT]; 83184260Sobrien#endif /* VREPRINT */ 83284260Sobrien#ifdef VDISCARD 83384260Sobrien td->c_cc[VDISCARD] = s[C_DISCARD]; 83484260Sobrien#endif /* VDISCARD */ 83584260Sobrien#ifdef VLNEXT 83684260Sobrien td->c_cc[VLNEXT] = s[C_LNEXT]; 83784260Sobrien#endif /* VLNEXT */ 83884260Sobrien#ifdef VSTATUS 83984260Sobrien td->c_cc[VSTATUS] = s[C_STATUS]; 84084260Sobrien#endif /* VSTATUS */ 84184260Sobrien#ifdef VPAGE 84284260Sobrien td->c_cc[VPAGE] = s[C_PAGE]; 84384260Sobrien#endif /* VPAGE */ 84484260Sobrien#ifdef VPGOFF 84584260Sobrien td->c_cc[VPGOFF] = s[C_PGOFF]; 84684260Sobrien#endif /* VPGOFF */ 84784260Sobrien#ifdef VKILL2 84884260Sobrien td->c_cc[VKILL2] = s[C_KILL2]; 84984260Sobrien#endif /* VKILL2 */ 85084260Sobrien#ifdef VMIN 85184260Sobrien td->c_cc[VMIN] = s[C_MIN]; 85284260Sobrien#endif /* VMIN */ 85384260Sobrien#ifdef VTIME 85484260Sobrien td->c_cc[VTIME] = s[C_TIME]; 85584260Sobrien#endif /* VTIME */ 85684260Sobrien} /* tty__setchar */ 8571573Srgrimes 85884260Sobrien 8591573Srgrimes/* tty_bind_char(): 8601573Srgrimes * Rebind the editline functions 8611573Srgrimes */ 8621573Srgrimesprotected void 86384260Sobrientty_bind_char(EditLine *el, int force) 8641573Srgrimes{ 8651573Srgrimes 86684260Sobrien unsigned char *t_n = el->el_tty.t_c[ED_IO]; 86784260Sobrien unsigned char *t_o = el->el_tty.t_ed.c_cc; 86884260Sobrien unsigned char new[2], old[2]; 86984260Sobrien const ttymap_t *tp; 87084260Sobrien el_action_t *map, *alt; 87184260Sobrien const el_action_t *dmap, *dalt; 87284260Sobrien new[1] = old[1] = '\0'; 8731573Srgrimes 87484260Sobrien map = el->el_map.key; 87584260Sobrien alt = el->el_map.alt; 87684260Sobrien if (el->el_map.type == MAP_VI) { 87784260Sobrien dmap = el->el_map.vii; 87884260Sobrien dalt = el->el_map.vic; 87984260Sobrien } else { 88084260Sobrien dmap = el->el_map.emacs; 88184260Sobrien dalt = NULL; 88284260Sobrien } 8831573Srgrimes 88484260Sobrien for (tp = tty_map; tp->nch != -1; tp++) { 88584260Sobrien new[0] = t_n[tp->nch]; 88684260Sobrien old[0] = t_o[tp->och]; 88784260Sobrien if (new[0] == old[0] && !force) 88884260Sobrien continue; 88984260Sobrien /* Put the old default binding back, and set the new binding */ 89084260Sobrien key_clear(el, map, (char *)old); 89184260Sobrien map[old[0]] = dmap[old[0]]; 89284260Sobrien key_clear(el, map, (char *)new); 89384260Sobrien /* MAP_VI == 1, MAP_EMACS == 0... */ 89484260Sobrien map[new[0]] = tp->bind[el->el_map.type]; 89584260Sobrien if (dalt) { 89684260Sobrien key_clear(el, alt, (char *)old); 89784260Sobrien alt[old[0]] = dalt[old[0]]; 89884260Sobrien key_clear(el, alt, (char *)new); 89984260Sobrien alt[new[0]] = tp->bind[el->el_map.type + 1]; 90084260Sobrien } 9011573Srgrimes } 9021573Srgrimes} 9031573Srgrimes 90484260Sobrien 9051573Srgrimes/* tty_rawmode(): 9061573Srgrimes * Set terminal into 1 character at a time mode. 9071573Srgrimes */ 9081573Srgrimesprotected int 90984260Sobrientty_rawmode(EditLine *el) 9101573Srgrimes{ 9111573Srgrimes 91284260Sobrien if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO) 91384260Sobrien return (0); 91484260Sobrien 91584260Sobrien if (el->el_flags & EDIT_DISABLED) 91684260Sobrien return (0); 91784260Sobrien 91884260Sobrien if (tty_getty(el, &el->el_tty.t_ts) == -1) { 9191573Srgrimes#ifdef DEBUG_TTY 92084260Sobrien (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", 92184260Sobrien strerror(errno)); 9221573Srgrimes#endif /* DEBUG_TTY */ 92384260Sobrien return (-1); 9241573Srgrimes } 92584260Sobrien /* 92684260Sobrien * We always keep up with the eight bit setting and the speed of the 92784260Sobrien * tty. But only we only believe changes that are made to cooked mode! 92884260Sobrien */ 92984260Sobrien el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); 93084260Sobrien el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); 9311573Srgrimes 93284260Sobrien if (tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { 93384260Sobrien (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); 93484260Sobrien (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); 9351573Srgrimes } 93684260Sobrien if (tty__cooked_mode(&el->el_tty.t_ts)) { 93784260Sobrien if ((el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) && 93884260Sobrien (el->el_tty.t_ts.c_cflag != el->el_tty.t_ed.c_cflag)) { 93984260Sobrien el->el_tty.t_ed.c_cflag = 94084260Sobrien el->el_tty.t_ts.c_cflag; 94184260Sobrien el->el_tty.t_ed.c_cflag &= 94284260Sobrien ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; 94384260Sobrien el->el_tty.t_ed.c_cflag |= 94484260Sobrien el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; 94584260Sobrien } 94684260Sobrien if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) && 94784260Sobrien (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) { 94884260Sobrien el->el_tty.t_ed.c_lflag = 94984260Sobrien el->el_tty.t_ts.c_lflag; 95084260Sobrien el->el_tty.t_ed.c_lflag &= 95184260Sobrien ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; 95284260Sobrien el->el_tty.t_ed.c_lflag |= 95384260Sobrien el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; 95484260Sobrien } 95584260Sobrien if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) && 95684260Sobrien (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) { 95784260Sobrien el->el_tty.t_ed.c_iflag = 95884260Sobrien el->el_tty.t_ts.c_iflag; 95984260Sobrien el->el_tty.t_ed.c_iflag &= 96084260Sobrien ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; 96184260Sobrien el->el_tty.t_ed.c_iflag |= 96284260Sobrien el->el_tty.t_t[ED_IO][MD_INP].t_setmask; 96384260Sobrien } 96484260Sobrien if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) && 96584260Sobrien (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) { 96684260Sobrien el->el_tty.t_ed.c_oflag = 96784260Sobrien el->el_tty.t_ts.c_oflag; 96884260Sobrien el->el_tty.t_ed.c_oflag &= 96984260Sobrien ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; 97084260Sobrien el->el_tty.t_ed.c_oflag |= 97184260Sobrien el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; 97284260Sobrien } 97384260Sobrien if (tty__gettabs(&el->el_tty.t_ex) == 0) 97484260Sobrien el->el_tty.t_tabs = 0; 97584260Sobrien else 97684260Sobrien el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; 9771573Srgrimes 97884260Sobrien { 97984260Sobrien int i; 9801573Srgrimes 98184260Sobrien tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); 98284260Sobrien /* 98384260Sobrien * Check if the user made any changes. 98484260Sobrien * If he did, then propagate the changes to the 98584260Sobrien * edit and execute data structures. 98684260Sobrien */ 98784260Sobrien for (i = 0; i < C_NCC; i++) 98884260Sobrien if (el->el_tty.t_c[TS_IO][i] != 98984260Sobrien el->el_tty.t_c[EX_IO][i]) 99084260Sobrien break; 9911573Srgrimes 99284260Sobrien if (i != C_NCC) { 99384260Sobrien /* 99484260Sobrien * Propagate changes only to the unprotected 99584260Sobrien * chars that have been modified just now. 99684260Sobrien */ 99784260Sobrien for (i = 0; i < C_NCC; i++) { 99884260Sobrien if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i))) 99984260Sobrien && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) 100084260Sobrien el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i]; 100184260Sobrien if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i)) 100284260Sobrien el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable; 100384260Sobrien } 100484260Sobrien tty_bind_char(el, 0); 100584260Sobrien tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); 10061573Srgrimes 100784260Sobrien for (i = 0; i < C_NCC; i++) { 100884260Sobrien if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i))) 100984260Sobrien && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) 101084260Sobrien el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i]; 101184260Sobrien if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i)) 101284260Sobrien el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable; 101384260Sobrien } 101484260Sobrien } 10151573Srgrimes } 10161573Srgrimes } 10171573Srgrimes 101884260Sobrien if (el->el_tty.t_mode == EX_IO) 101984260Sobrien el->el_tty.t_ex = el->el_tty.t_ts; 102063947Sache 1021268782Spfg if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { 10221573Srgrimes#ifdef DEBUG_TTY 102384260Sobrien (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", 102484260Sobrien strerror(errno)); 10251573Srgrimes#endif /* DEBUG_TTY */ 102684260Sobrien return (-1); 102784260Sobrien } 102884260Sobrien el->el_tty.t_mode = ED_IO; 102984260Sobrien return (0); 103084260Sobrien} 10311573Srgrimes 10321573Srgrimes 10331573Srgrimes/* tty_cookedmode(): 10341573Srgrimes * Set the tty back to normal mode 10351573Srgrimes */ 10361573Srgrimesprotected int 103784260Sobrientty_cookedmode(EditLine *el) 10381573Srgrimes{ /* set tty in normal setup */ 10391573Srgrimes 104084260Sobrien if (el->el_tty.t_mode == EX_IO) 104184260Sobrien return (0); 104284260Sobrien 104384260Sobrien if (el->el_flags & EDIT_DISABLED) 104484260Sobrien return (0); 104584260Sobrien 1046268782Spfg if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { 10471573Srgrimes#ifdef DEBUG_TTY 104884260Sobrien (void) fprintf(el->el_errfile, 104984260Sobrien "tty_cookedmode: tty_setty: %s\n", 105084260Sobrien strerror(errno)); 10511573Srgrimes#endif /* DEBUG_TTY */ 105284260Sobrien return (-1); 105384260Sobrien } 105484260Sobrien el->el_tty.t_mode = EX_IO; 105584260Sobrien return (0); 105684260Sobrien} 10571573Srgrimes 10581573Srgrimes 10591573Srgrimes/* tty_quotemode(): 10601573Srgrimes * Turn on quote mode 10611573Srgrimes */ 10621573Srgrimesprotected int 106384260Sobrientty_quotemode(EditLine *el) 10641573Srgrimes{ 106584260Sobrien if (el->el_tty.t_mode == QU_IO) 106684260Sobrien return (0); 10671573Srgrimes 106884260Sobrien el->el_tty.t_qu = el->el_tty.t_ed; 10691573Srgrimes 107084260Sobrien el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask; 107184260Sobrien el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask; 10721573Srgrimes 107384260Sobrien el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask; 107484260Sobrien el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask; 10751573Srgrimes 107684260Sobrien el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask; 107784260Sobrien el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask; 10781573Srgrimes 107984260Sobrien el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; 108084260Sobrien el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; 10811573Srgrimes 1082268782Spfg if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) { 10831573Srgrimes#ifdef DEBUG_TTY 108484260Sobrien (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", 108584260Sobrien strerror(errno)); 10861573Srgrimes#endif /* DEBUG_TTY */ 108784260Sobrien return (-1); 108884260Sobrien } 108984260Sobrien el->el_tty.t_mode = QU_IO; 109084260Sobrien return (0); 109184260Sobrien} 10921573Srgrimes 10931573Srgrimes 10941573Srgrimes/* tty_noquotemode(): 10951573Srgrimes * Turn off quote mode 10961573Srgrimes */ 10971573Srgrimesprotected int 109884260Sobrientty_noquotemode(EditLine *el) 10991573Srgrimes{ 110084260Sobrien 110184260Sobrien if (el->el_tty.t_mode != QU_IO) 110284260Sobrien return (0); 1103268782Spfg if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { 11041573Srgrimes#ifdef DEBUG_TTY 110584260Sobrien (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", 110684260Sobrien strerror(errno)); 11071573Srgrimes#endif /* DEBUG_TTY */ 110884260Sobrien return (-1); 110984260Sobrien } 111084260Sobrien el->el_tty.t_mode = ED_IO; 111184260Sobrien return (0); 11121573Srgrimes} 11131573Srgrimes 111484260Sobrien 11151573Srgrimes/* tty_stty(): 11161573Srgrimes * Stty builtin 11171573Srgrimes */ 11181573Srgrimesprotected int 11191573Srgrimes/*ARGSUSED*/ 1120148834Sstefanftty_stty(EditLine *el, int argc __unused, const char **argv) 11211573Srgrimes{ 112284260Sobrien const ttymodes_t *m; 1123148834Sstefanf char x; 112484260Sobrien int aflag = 0; 1125148834Sstefanf const char *s, *d; 1126148834Sstefanf const char *name; 1127148834Sstefanf struct termios *tios = &el->el_tty.t_ex; 112884260Sobrien int z = EX_IO; 11291573Srgrimes 113084260Sobrien if (argv == NULL) 113184260Sobrien return (-1); 113284260Sobrien name = *argv++; 11331573Srgrimes 113484260Sobrien while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') 113584260Sobrien switch (argv[0][1]) { 113684260Sobrien case 'a': 113784260Sobrien aflag++; 113884260Sobrien argv++; 113984260Sobrien break; 114084260Sobrien case 'd': 114184260Sobrien argv++; 1142148834Sstefanf tios = &el->el_tty.t_ed; 114384260Sobrien z = ED_IO; 114484260Sobrien break; 114584260Sobrien case 'x': 114684260Sobrien argv++; 1147148834Sstefanf tios = &el->el_tty.t_ex; 114884260Sobrien z = EX_IO; 114984260Sobrien break; 115084260Sobrien case 'q': 115184260Sobrien argv++; 1152148834Sstefanf tios = &el->el_tty.t_ts; 115384260Sobrien z = QU_IO; 115484260Sobrien break; 115584260Sobrien default: 115684260Sobrien (void) fprintf(el->el_errfile, 115784260Sobrien "%s: Unknown switch `%c'.\n", 115884260Sobrien name, argv[0][1]); 115984260Sobrien return (-1); 116084260Sobrien } 11611573Srgrimes 116284260Sobrien if (!argv || !*argv) { 116384260Sobrien int i = -1; 1164268782Spfg size_t len = 0, st = 0, cu; 116584260Sobrien for (m = ttymodes; m->m_name; m++) { 116684260Sobrien if (m->m_type != i) { 116784260Sobrien (void) fprintf(el->el_outfile, "%s%s", 116884260Sobrien i != -1 ? "\n" : "", 116984260Sobrien el->el_tty.t_t[z][m->m_type].t_name); 117084260Sobrien i = m->m_type; 117184260Sobrien st = len = 117284260Sobrien strlen(el->el_tty.t_t[z][m->m_type].t_name); 117384260Sobrien } 1174167464Sstefanf if (i != -1) { 1175167464Sstefanf x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) 1176167464Sstefanf ? '+' : '\0'; 1177167464Sstefanf x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) 1178167464Sstefanf ? '-' : x; 1179167464Sstefanf } else { 1180167464Sstefanf x = '\0'; 1181167464Sstefanf } 11821573Srgrimes 118384260Sobrien if (x != '\0' || aflag) { 11841573Srgrimes 118584260Sobrien cu = strlen(m->m_name) + (x != '\0') + 1; 11861573Srgrimes 1187268782Spfg if (len + cu >= (size_t)el->el_term.t_size.h) { 118884260Sobrien (void) fprintf(el->el_outfile, "\n%*s", 1189268782Spfg (int)st, ""); 119084260Sobrien len = st + cu; 119184260Sobrien } else 119284260Sobrien len += cu; 11931573Srgrimes 119484260Sobrien if (x != '\0') 119584260Sobrien (void) fprintf(el->el_outfile, "%c%s ", 119684260Sobrien x, m->m_name); 119784260Sobrien else 119884260Sobrien (void) fprintf(el->el_outfile, "%s ", 119984260Sobrien m->m_name); 120084260Sobrien } 12011573Srgrimes } 120284260Sobrien (void) fprintf(el->el_outfile, "\n"); 120384260Sobrien return (0); 12041573Srgrimes } 120584260Sobrien while (argv && (s = *argv++)) { 1206148834Sstefanf const char *p; 120784260Sobrien switch (*s) { 120884260Sobrien case '+': 120984260Sobrien case '-': 121084260Sobrien x = *s++; 121184260Sobrien break; 121284260Sobrien default: 121384260Sobrien x = '\0'; 121484260Sobrien break; 121584260Sobrien } 121684260Sobrien d = s; 1217148834Sstefanf p = strchr(s, '='); 121884260Sobrien for (m = ttymodes; m->m_name; m++) 1219148834Sstefanf if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) : 1220148834Sstefanf strcmp(m->m_name, d)) == 0 && 1221148834Sstefanf (p == NULL || m->m_type == MD_CHAR)) 122284260Sobrien break; 12231573Srgrimes 122484260Sobrien if (!m->m_name) { 122584260Sobrien (void) fprintf(el->el_errfile, 122684260Sobrien "%s: Invalid argument `%s'.\n", name, d); 122784260Sobrien return (-1); 122884260Sobrien } 1229148834Sstefanf if (p) { 1230148834Sstefanf int c = ffs((int)m->m_value); 1231148834Sstefanf int v = *++p ? parse__escape((const char **) &p) : 1232148834Sstefanf el->el_tty.t_vdisable; 1233268782Spfg assert(c != 0); 1234268782Spfg c--; 1235148834Sstefanf c = tty__getcharindex(c); 1236148834Sstefanf assert(c != -1); 1237148834Sstefanf tios->c_cc[c] = v; 1238148834Sstefanf continue; 1239148834Sstefanf } 124084260Sobrien switch (x) { 124184260Sobrien case '+': 124284260Sobrien el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value; 124384260Sobrien el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; 124484260Sobrien break; 124584260Sobrien case '-': 124684260Sobrien el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; 124784260Sobrien el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value; 124884260Sobrien break; 124984260Sobrien default: 125084260Sobrien el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; 125184260Sobrien el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; 125284260Sobrien break; 125384260Sobrien } 12541573Srgrimes } 1255268782Spfg 1256268782Spfg if (el->el_tty.t_mode == z) { 1257268782Spfg if (tty_setty(el, TCSADRAIN, tios) == -1) { 1258268782Spfg#ifdef DEBUG_TTY 1259268782Spfg (void) fprintf(el->el_errfile, 1260268782Spfg "tty_stty: tty_setty: %s\n", strerror(errno)); 1261268782Spfg#endif /* DEBUG_TTY */ 1262268782Spfg return (-1); 1263268782Spfg } 1264268782Spfg } 1265268782Spfg 126684260Sobrien return (0); 126784260Sobrien} 12681573Srgrimes 12691573Srgrimes 12701573Srgrimes#ifdef notyet 12711573Srgrimes/* tty_printchar(): 12721573Srgrimes * DEbugging routine to print the tty characters 12731573Srgrimes */ 12741573Srgrimesprivate void 127584260Sobrientty_printchar(EditLine *el, unsigned char *s) 12761573Srgrimes{ 127784260Sobrien ttyperm_t *m; 127884260Sobrien int i; 12791573Srgrimes 128084260Sobrien for (i = 0; i < C_NCC; i++) { 128184260Sobrien for (m = el->el_tty.t_t; m->m_name; m++) 128284260Sobrien if (m->m_type == MD_CHAR && C_SH(i) == m->m_value) 128384260Sobrien break; 128484260Sobrien if (m->m_name) 128584260Sobrien (void) fprintf(el->el_errfile, "%s ^%c ", 128684260Sobrien m->m_name, s[i] + 'A' - 1); 128784260Sobrien if (i % 5 == 0) 128884260Sobrien (void) fprintf(el->el_errfile, "\n"); 128984260Sobrien } 129084260Sobrien (void) fprintf(el->el_errfile, "\n"); 12911573Srgrimes} 12921573Srgrimes#endif /* notyet */ 1293