Home | History | Annotate | Line # | Download | only in libedit
tty.c revision 1.33
      1  1.33  christos /*	$NetBSD: tty.c,v 1.33 2010/04/18 21:17:22 christos Exp $	*/
      2   1.2     lukem 
      3   1.1       cgd /*-
      4   1.1       cgd  * Copyright (c) 1992, 1993
      5   1.1       cgd  *	The Regents of the University of California.  All rights reserved.
      6   1.1       cgd  *
      7   1.1       cgd  * This code is derived from software contributed to Berkeley by
      8   1.1       cgd  * Christos Zoulas of Cornell University.
      9   1.1       cgd  *
     10   1.1       cgd  * Redistribution and use in source and binary forms, with or without
     11   1.1       cgd  * modification, are permitted provided that the following conditions
     12   1.1       cgd  * are met:
     13   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     14   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     15   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     17   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     18  1.18       agc  * 3. Neither the name of the University nor the names of its contributors
     19   1.1       cgd  *    may be used to endorse or promote products derived from this software
     20   1.1       cgd  *    without specific prior written permission.
     21   1.1       cgd  *
     22   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32   1.1       cgd  * SUCH DAMAGE.
     33   1.1       cgd  */
     34   1.1       cgd 
     35  1.16  christos #include "config.h"
     36   1.1       cgd #if !defined(lint) && !defined(SCCSID)
     37   1.2     lukem #if 0
     38   1.1       cgd static char sccsid[] = "@(#)tty.c	8.1 (Berkeley) 6/4/93";
     39   1.2     lukem #else
     40  1.33  christos __RCSID("$NetBSD: tty.c,v 1.33 2010/04/18 21:17:22 christos Exp $");
     41   1.2     lukem #endif
     42   1.1       cgd #endif /* not lint && not SCCSID */
     43   1.1       cgd 
     44  1.11    simonb /*
     45   1.1       cgd  * tty.c: tty interface stuff
     46   1.1       cgd  */
     47  1.19  christos #include <assert.h>
     48  1.28    sketch #include <errno.h>
     49  1.33  christos #include <strings.h>	/* for ffs */
     50  1.32  christos #include "el.h"
     51   1.1       cgd #include "tty.h"
     52   1.1       cgd 
     53   1.1       cgd typedef struct ttymodes_t {
     54  1.14  jdolecek 	const char *m_name;
     55  1.23     lukem 	unsigned int m_value;
     56  1.13     lukem 	int m_type;
     57  1.13     lukem }          ttymodes_t;
     58   1.1       cgd 
     59   1.1       cgd typedef struct ttymap_t {
     60  1.32  christos 	Int nch, och;		/* Internal and termio rep of chars */
     61  1.13     lukem 	el_action_t bind[3];	/* emacs, vi, and vi-cmd */
     62  1.16  christos } ttymap_t;
     63   1.1       cgd 
     64   1.1       cgd 
     65  1.14  jdolecek private const ttyperm_t ttyperm = {
     66  1.13     lukem 	{
     67  1.13     lukem 		{"iflag:", ICRNL, (INLCR | IGNCR)},
     68  1.13     lukem 		{"oflag:", (OPOST | ONLCR), ONLRET},
     69  1.13     lukem 		{"cflag:", 0, 0},
     70  1.13     lukem 		{"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
     71  1.13     lukem 		(NOFLSH | ECHONL | EXTPROC | FLUSHO)},
     72  1.13     lukem 		{"chars:", 0, 0},
     73  1.13     lukem 	},
     74  1.13     lukem 	{
     75  1.13     lukem 		{"iflag:", (INLCR | ICRNL), IGNCR},
     76  1.13     lukem 		{"oflag:", (OPOST | ONLCR), ONLRET},
     77  1.13     lukem 		{"cflag:", 0, 0},
     78  1.13     lukem 		{"lflag:", ISIG,
     79  1.13     lukem 		(NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
     80  1.13     lukem 		{"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
     81  1.13     lukem 			    C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
     82  1.13     lukem 		    C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
     83  1.13     lukem 	},
     84  1.13     lukem 	{
     85  1.13     lukem 		{"iflag:", 0, IXON | IXOFF | INLCR | ICRNL},
     86  1.13     lukem 		{"oflag:", 0, 0},
     87  1.13     lukem 		{"cflag:", 0, 0},
     88  1.13     lukem 		{"lflag:", 0, ISIG | IEXTEN},
     89  1.13     lukem 		{"chars:", 0, 0},
     90  1.13     lukem 	}
     91   1.1       cgd };
     92   1.1       cgd 
     93  1.14  jdolecek private const ttychar_t ttychar = {
     94  1.13     lukem 	{
     95  1.13     lukem 		CINTR, CQUIT, CERASE, CKILL,
     96  1.13     lukem 		CEOF, CEOL, CEOL2, CSWTCH,
     97  1.13     lukem 		CDSWTCH, CERASE2, CSTART, CSTOP,
     98  1.13     lukem 		CWERASE, CSUSP, CDSUSP, CREPRINT,
     99  1.13     lukem 		CDISCARD, CLNEXT, CSTATUS, CPAGE,
    100  1.13     lukem 		CPGOFF, CKILL2, CBRK, CMIN,
    101  1.13     lukem 		CTIME
    102  1.13     lukem 	},
    103  1.13     lukem 	{
    104  1.13     lukem 		CINTR, CQUIT, CERASE, CKILL,
    105  1.13     lukem 		_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
    106  1.13     lukem 		_POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
    107  1.13     lukem 		_POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
    108  1.13     lukem 		CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
    109  1.13     lukem 		_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
    110  1.13     lukem 		0
    111  1.13     lukem 	},
    112  1.13     lukem 	{
    113  1.13     lukem 		0, 0, 0, 0,
    114  1.13     lukem 		0, 0, 0, 0,
    115  1.13     lukem 		0, 0, 0, 0,
    116  1.13     lukem 		0, 0, 0, 0,
    117  1.13     lukem 		0, 0, 0, 0,
    118  1.13     lukem 		0, 0, 0, 0,
    119  1.13     lukem 		0
    120  1.13     lukem 	}
    121   1.1       cgd };
    122   1.1       cgd 
    123  1.14  jdolecek private const ttymap_t tty_map[] = {
    124   1.1       cgd #ifdef VERASE
    125  1.13     lukem 	{C_ERASE, VERASE,
    126  1.21   mycroft 	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
    127   1.1       cgd #endif /* VERASE */
    128   1.1       cgd #ifdef VERASE2
    129  1.13     lukem 	{C_ERASE2, VERASE2,
    130  1.21   mycroft 	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
    131   1.1       cgd #endif /* VERASE2 */
    132   1.1       cgd #ifdef VKILL
    133  1.13     lukem 	{C_KILL, VKILL,
    134  1.13     lukem 	{EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
    135   1.1       cgd #endif /* VKILL */
    136   1.1       cgd #ifdef VKILL2
    137  1.13     lukem 	{C_KILL2, VKILL2,
    138  1.13     lukem 	{EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
    139   1.1       cgd #endif /* VKILL2 */
    140   1.1       cgd #ifdef VEOF
    141  1.13     lukem 	{C_EOF, VEOF,
    142  1.13     lukem 	{EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}},
    143   1.1       cgd #endif /* VEOF */
    144   1.1       cgd #ifdef VWERASE
    145  1.13     lukem 	{C_WERASE, VWERASE,
    146  1.13     lukem 	{ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}},
    147   1.1       cgd #endif /* VWERASE */
    148   1.1       cgd #ifdef VREPRINT
    149  1.13     lukem 	{C_REPRINT, VREPRINT,
    150  1.13     lukem 	{ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}},
    151   1.1       cgd #endif /* VREPRINT */
    152   1.1       cgd #ifdef VLNEXT
    153  1.13     lukem 	{C_LNEXT, VLNEXT,
    154  1.13     lukem 	{ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
    155   1.1       cgd #endif /* VLNEXT */
    156  1.13     lukem 	{-1, -1,
    157  1.13     lukem 	{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
    158  1.13     lukem };
    159   1.1       cgd 
    160  1.14  jdolecek private const ttymodes_t ttymodes[] = {
    161  1.13     lukem #ifdef	IGNBRK
    162  1.13     lukem 	{"ignbrk", IGNBRK, MD_INP},
    163  1.13     lukem #endif /* IGNBRK */
    164  1.13     lukem #ifdef	BRKINT
    165  1.13     lukem 	{"brkint", BRKINT, MD_INP},
    166  1.13     lukem #endif /* BRKINT */
    167  1.13     lukem #ifdef	IGNPAR
    168  1.13     lukem 	{"ignpar", IGNPAR, MD_INP},
    169  1.13     lukem #endif /* IGNPAR */
    170  1.13     lukem #ifdef	PARMRK
    171  1.13     lukem 	{"parmrk", PARMRK, MD_INP},
    172  1.13     lukem #endif /* PARMRK */
    173  1.13     lukem #ifdef	INPCK
    174  1.13     lukem 	{"inpck", INPCK, MD_INP},
    175  1.13     lukem #endif /* INPCK */
    176  1.13     lukem #ifdef	ISTRIP
    177  1.13     lukem 	{"istrip", ISTRIP, MD_INP},
    178  1.13     lukem #endif /* ISTRIP */
    179  1.13     lukem #ifdef	INLCR
    180  1.13     lukem 	{"inlcr", INLCR, MD_INP},
    181  1.13     lukem #endif /* INLCR */
    182  1.13     lukem #ifdef	IGNCR
    183  1.13     lukem 	{"igncr", IGNCR, MD_INP},
    184  1.13     lukem #endif /* IGNCR */
    185  1.13     lukem #ifdef	ICRNL
    186  1.13     lukem 	{"icrnl", ICRNL, MD_INP},
    187  1.13     lukem #endif /* ICRNL */
    188  1.13     lukem #ifdef	IUCLC
    189  1.13     lukem 	{"iuclc", IUCLC, MD_INP},
    190  1.13     lukem #endif /* IUCLC */
    191  1.13     lukem #ifdef	IXON
    192  1.13     lukem 	{"ixon", IXON, MD_INP},
    193  1.13     lukem #endif /* IXON */
    194  1.13     lukem #ifdef	IXANY
    195  1.13     lukem 	{"ixany", IXANY, MD_INP},
    196  1.13     lukem #endif /* IXANY */
    197  1.13     lukem #ifdef	IXOFF
    198  1.13     lukem 	{"ixoff", IXOFF, MD_INP},
    199  1.13     lukem #endif /* IXOFF */
    200  1.13     lukem #ifdef  IMAXBEL
    201  1.13     lukem 	{"imaxbel", IMAXBEL, MD_INP},
    202  1.13     lukem #endif /* IMAXBEL */
    203  1.13     lukem 
    204  1.13     lukem #ifdef	OPOST
    205  1.13     lukem 	{"opost", OPOST, MD_OUT},
    206  1.13     lukem #endif /* OPOST */
    207  1.13     lukem #ifdef	OLCUC
    208  1.13     lukem 	{"olcuc", OLCUC, MD_OUT},
    209  1.13     lukem #endif /* OLCUC */
    210  1.13     lukem #ifdef	ONLCR
    211  1.13     lukem 	{"onlcr", ONLCR, MD_OUT},
    212  1.13     lukem #endif /* ONLCR */
    213  1.13     lukem #ifdef	OCRNL
    214  1.13     lukem 	{"ocrnl", OCRNL, MD_OUT},
    215  1.13     lukem #endif /* OCRNL */
    216  1.13     lukem #ifdef	ONOCR
    217  1.13     lukem 	{"onocr", ONOCR, MD_OUT},
    218  1.13     lukem #endif /* ONOCR */
    219  1.13     lukem #ifdef ONOEOT
    220  1.13     lukem 	{"onoeot", ONOEOT, MD_OUT},
    221  1.13     lukem #endif /* ONOEOT */
    222  1.13     lukem #ifdef	ONLRET
    223  1.13     lukem 	{"onlret", ONLRET, MD_OUT},
    224  1.13     lukem #endif /* ONLRET */
    225  1.13     lukem #ifdef	OFILL
    226  1.13     lukem 	{"ofill", OFILL, MD_OUT},
    227  1.13     lukem #endif /* OFILL */
    228  1.13     lukem #ifdef	OFDEL
    229  1.13     lukem 	{"ofdel", OFDEL, MD_OUT},
    230  1.13     lukem #endif /* OFDEL */
    231  1.13     lukem #ifdef	NLDLY
    232  1.13     lukem 	{"nldly", NLDLY, MD_OUT},
    233  1.13     lukem #endif /* NLDLY */
    234  1.13     lukem #ifdef	CRDLY
    235  1.13     lukem 	{"crdly", CRDLY, MD_OUT},
    236  1.13     lukem #endif /* CRDLY */
    237  1.13     lukem #ifdef	TABDLY
    238  1.13     lukem 	{"tabdly", TABDLY, MD_OUT},
    239  1.13     lukem #endif /* TABDLY */
    240  1.13     lukem #ifdef	XTABS
    241  1.13     lukem 	{"xtabs", XTABS, MD_OUT},
    242  1.13     lukem #endif /* XTABS */
    243  1.13     lukem #ifdef	BSDLY
    244  1.13     lukem 	{"bsdly", BSDLY, MD_OUT},
    245  1.13     lukem #endif /* BSDLY */
    246  1.13     lukem #ifdef	VTDLY
    247  1.13     lukem 	{"vtdly", VTDLY, MD_OUT},
    248  1.13     lukem #endif /* VTDLY */
    249  1.13     lukem #ifdef	FFDLY
    250  1.13     lukem 	{"ffdly", FFDLY, MD_OUT},
    251  1.13     lukem #endif /* FFDLY */
    252  1.13     lukem #ifdef	PAGEOUT
    253  1.13     lukem 	{"pageout", PAGEOUT, MD_OUT},
    254  1.13     lukem #endif /* PAGEOUT */
    255  1.13     lukem #ifdef	WRAP
    256  1.13     lukem 	{"wrap", WRAP, MD_OUT},
    257  1.13     lukem #endif /* WRAP */
    258  1.13     lukem 
    259  1.13     lukem #ifdef	CIGNORE
    260  1.13     lukem 	{"cignore", CIGNORE, MD_CTL},
    261  1.13     lukem #endif /* CBAUD */
    262  1.13     lukem #ifdef	CBAUD
    263  1.13     lukem 	{"cbaud", CBAUD, MD_CTL},
    264  1.13     lukem #endif /* CBAUD */
    265  1.13     lukem #ifdef	CSTOPB
    266  1.13     lukem 	{"cstopb", CSTOPB, MD_CTL},
    267  1.13     lukem #endif /* CSTOPB */
    268  1.13     lukem #ifdef	CREAD
    269  1.13     lukem 	{"cread", CREAD, MD_CTL},
    270  1.13     lukem #endif /* CREAD */
    271  1.13     lukem #ifdef	PARENB
    272  1.13     lukem 	{"parenb", PARENB, MD_CTL},
    273  1.13     lukem #endif /* PARENB */
    274  1.13     lukem #ifdef	PARODD
    275  1.13     lukem 	{"parodd", PARODD, MD_CTL},
    276  1.13     lukem #endif /* PARODD */
    277  1.13     lukem #ifdef	HUPCL
    278  1.13     lukem 	{"hupcl", HUPCL, MD_CTL},
    279  1.13     lukem #endif /* HUPCL */
    280  1.13     lukem #ifdef	CLOCAL
    281  1.13     lukem 	{"clocal", CLOCAL, MD_CTL},
    282  1.13     lukem #endif /* CLOCAL */
    283  1.13     lukem #ifdef	LOBLK
    284  1.13     lukem 	{"loblk", LOBLK, MD_CTL},
    285  1.13     lukem #endif /* LOBLK */
    286  1.13     lukem #ifdef	CIBAUD
    287  1.13     lukem 	{"cibaud", CIBAUD, MD_CTL},
    288  1.13     lukem #endif /* CIBAUD */
    289  1.13     lukem #ifdef CRTSCTS
    290  1.13     lukem #ifdef CCTS_OFLOW
    291  1.13     lukem 	{"ccts_oflow", CCTS_OFLOW, MD_CTL},
    292  1.13     lukem #else
    293  1.13     lukem 	{"crtscts", CRTSCTS, MD_CTL},
    294  1.13     lukem #endif /* CCTS_OFLOW */
    295  1.13     lukem #endif /* CRTSCTS */
    296  1.13     lukem #ifdef CRTS_IFLOW
    297  1.13     lukem 	{"crts_iflow", CRTS_IFLOW, MD_CTL},
    298  1.13     lukem #endif /* CRTS_IFLOW */
    299  1.13     lukem #ifdef CDTRCTS
    300  1.13     lukem 	{"cdtrcts", CDTRCTS, MD_CTL},
    301  1.13     lukem #endif /* CDTRCTS */
    302  1.13     lukem #ifdef MDMBUF
    303  1.13     lukem 	{"mdmbuf", MDMBUF, MD_CTL},
    304  1.13     lukem #endif /* MDMBUF */
    305  1.13     lukem #ifdef RCV1EN
    306  1.13     lukem 	{"rcv1en", RCV1EN, MD_CTL},
    307  1.13     lukem #endif /* RCV1EN */
    308  1.13     lukem #ifdef XMT1EN
    309  1.13     lukem 	{"xmt1en", XMT1EN, MD_CTL},
    310  1.13     lukem #endif /* XMT1EN */
    311  1.13     lukem 
    312  1.13     lukem #ifdef	ISIG
    313  1.13     lukem 	{"isig", ISIG, MD_LIN},
    314  1.13     lukem #endif /* ISIG */
    315  1.13     lukem #ifdef	ICANON
    316  1.13     lukem 	{"icanon", ICANON, MD_LIN},
    317  1.13     lukem #endif /* ICANON */
    318  1.13     lukem #ifdef	XCASE
    319  1.13     lukem 	{"xcase", XCASE, MD_LIN},
    320  1.13     lukem #endif /* XCASE */
    321  1.13     lukem #ifdef	ECHO
    322  1.13     lukem 	{"echo", ECHO, MD_LIN},
    323  1.13     lukem #endif /* ECHO */
    324  1.13     lukem #ifdef	ECHOE
    325  1.13     lukem 	{"echoe", ECHOE, MD_LIN},
    326  1.13     lukem #endif /* ECHOE */
    327  1.13     lukem #ifdef	ECHOK
    328  1.13     lukem 	{"echok", ECHOK, MD_LIN},
    329  1.13     lukem #endif /* ECHOK */
    330  1.13     lukem #ifdef	ECHONL
    331  1.13     lukem 	{"echonl", ECHONL, MD_LIN},
    332  1.13     lukem #endif /* ECHONL */
    333  1.13     lukem #ifdef	NOFLSH
    334  1.13     lukem 	{"noflsh", NOFLSH, MD_LIN},
    335  1.13     lukem #endif /* NOFLSH */
    336  1.13     lukem #ifdef	TOSTOP
    337  1.13     lukem 	{"tostop", TOSTOP, MD_LIN},
    338  1.13     lukem #endif /* TOSTOP */
    339  1.13     lukem #ifdef	ECHOCTL
    340  1.13     lukem 	{"echoctl", ECHOCTL, MD_LIN},
    341  1.13     lukem #endif /* ECHOCTL */
    342  1.13     lukem #ifdef	ECHOPRT
    343  1.13     lukem 	{"echoprt", ECHOPRT, MD_LIN},
    344  1.13     lukem #endif /* ECHOPRT */
    345  1.13     lukem #ifdef	ECHOKE
    346  1.13     lukem 	{"echoke", ECHOKE, MD_LIN},
    347  1.13     lukem #endif /* ECHOKE */
    348  1.13     lukem #ifdef	DEFECHO
    349  1.13     lukem 	{"defecho", DEFECHO, MD_LIN},
    350  1.13     lukem #endif /* DEFECHO */
    351  1.13     lukem #ifdef	FLUSHO
    352  1.13     lukem 	{"flusho", FLUSHO, MD_LIN},
    353  1.13     lukem #endif /* FLUSHO */
    354  1.13     lukem #ifdef	PENDIN
    355  1.13     lukem 	{"pendin", PENDIN, MD_LIN},
    356  1.13     lukem #endif /* PENDIN */
    357  1.13     lukem #ifdef	IEXTEN
    358  1.13     lukem 	{"iexten", IEXTEN, MD_LIN},
    359  1.13     lukem #endif /* IEXTEN */
    360  1.13     lukem #ifdef	NOKERNINFO
    361  1.13     lukem 	{"nokerninfo", NOKERNINFO, MD_LIN},
    362  1.13     lukem #endif /* NOKERNINFO */
    363  1.13     lukem #ifdef	ALTWERASE
    364  1.13     lukem 	{"altwerase", ALTWERASE, MD_LIN},
    365  1.13     lukem #endif /* ALTWERASE */
    366  1.13     lukem #ifdef	EXTPROC
    367  1.13     lukem 	{"extproc", EXTPROC, MD_LIN},
    368  1.13     lukem #endif /* EXTPROC */
    369  1.13     lukem 
    370  1.13     lukem #if defined(VINTR)
    371  1.13     lukem 	{"intr", C_SH(C_INTR), MD_CHAR},
    372  1.13     lukem #endif /* VINTR */
    373  1.13     lukem #if defined(VQUIT)
    374  1.13     lukem 	{"quit", C_SH(C_QUIT), MD_CHAR},
    375  1.13     lukem #endif /* VQUIT */
    376  1.13     lukem #if defined(VERASE)
    377  1.13     lukem 	{"erase", C_SH(C_ERASE), MD_CHAR},
    378  1.13     lukem #endif /* VERASE */
    379  1.13     lukem #if defined(VKILL)
    380  1.13     lukem 	{"kill", C_SH(C_KILL), MD_CHAR},
    381  1.13     lukem #endif /* VKILL */
    382  1.13     lukem #if defined(VEOF)
    383  1.13     lukem 	{"eof", C_SH(C_EOF), MD_CHAR},
    384  1.13     lukem #endif /* VEOF */
    385  1.13     lukem #if defined(VEOL)
    386  1.13     lukem 	{"eol", C_SH(C_EOL), MD_CHAR},
    387  1.13     lukem #endif /* VEOL */
    388  1.13     lukem #if defined(VEOL2)
    389  1.13     lukem 	{"eol2", C_SH(C_EOL2), MD_CHAR},
    390  1.13     lukem #endif /* VEOL2 */
    391  1.13     lukem #if defined(VSWTCH)
    392  1.13     lukem 	{"swtch", C_SH(C_SWTCH), MD_CHAR},
    393  1.13     lukem #endif /* VSWTCH */
    394  1.13     lukem #if defined(VDSWTCH)
    395  1.13     lukem 	{"dswtch", C_SH(C_DSWTCH), MD_CHAR},
    396  1.13     lukem #endif /* VDSWTCH */
    397  1.13     lukem #if defined(VERASE2)
    398  1.13     lukem 	{"erase2", C_SH(C_ERASE2), MD_CHAR},
    399  1.13     lukem #endif /* VERASE2 */
    400  1.13     lukem #if defined(VSTART)
    401  1.13     lukem 	{"start", C_SH(C_START), MD_CHAR},
    402  1.13     lukem #endif /* VSTART */
    403  1.13     lukem #if defined(VSTOP)
    404  1.13     lukem 	{"stop", C_SH(C_STOP), MD_CHAR},
    405  1.13     lukem #endif /* VSTOP */
    406  1.13     lukem #if defined(VWERASE)
    407  1.13     lukem 	{"werase", C_SH(C_WERASE), MD_CHAR},
    408  1.13     lukem #endif /* VWERASE */
    409  1.13     lukem #if defined(VSUSP)
    410  1.13     lukem 	{"susp", C_SH(C_SUSP), MD_CHAR},
    411  1.13     lukem #endif /* VSUSP */
    412  1.13     lukem #if defined(VDSUSP)
    413  1.13     lukem 	{"dsusp", C_SH(C_DSUSP), MD_CHAR},
    414  1.13     lukem #endif /* VDSUSP */
    415  1.13     lukem #if defined(VREPRINT)
    416  1.13     lukem 	{"reprint", C_SH(C_REPRINT), MD_CHAR},
    417  1.13     lukem #endif /* VREPRINT */
    418  1.13     lukem #if defined(VDISCARD)
    419  1.13     lukem 	{"discard", C_SH(C_DISCARD), MD_CHAR},
    420  1.13     lukem #endif /* VDISCARD */
    421  1.13     lukem #if defined(VLNEXT)
    422  1.13     lukem 	{"lnext", C_SH(C_LNEXT), MD_CHAR},
    423  1.13     lukem #endif /* VLNEXT */
    424  1.13     lukem #if defined(VSTATUS)
    425  1.13     lukem 	{"status", C_SH(C_STATUS), MD_CHAR},
    426  1.13     lukem #endif /* VSTATUS */
    427  1.13     lukem #if defined(VPAGE)
    428  1.13     lukem 	{"page", C_SH(C_PAGE), MD_CHAR},
    429  1.13     lukem #endif /* VPAGE */
    430  1.13     lukem #if defined(VPGOFF)
    431  1.13     lukem 	{"pgoff", C_SH(C_PGOFF), MD_CHAR},
    432  1.13     lukem #endif /* VPGOFF */
    433  1.13     lukem #if defined(VKILL2)
    434  1.13     lukem 	{"kill2", C_SH(C_KILL2), MD_CHAR},
    435  1.13     lukem #endif /* VKILL2 */
    436  1.13     lukem #if defined(VBRK)
    437  1.13     lukem 	{"brk", C_SH(C_BRK), MD_CHAR},
    438  1.13     lukem #endif /* VBRK */
    439  1.13     lukem #if defined(VMIN)
    440  1.13     lukem 	{"min", C_SH(C_MIN), MD_CHAR},
    441  1.13     lukem #endif /* VMIN */
    442  1.13     lukem #if defined(VTIME)
    443  1.13     lukem 	{"time", C_SH(C_TIME), MD_CHAR},
    444  1.13     lukem #endif /* VTIME */
    445  1.13     lukem 	{NULL, 0, -1},
    446   1.1       cgd };
    447   1.1       cgd 
    448   1.1       cgd 
    449   1.1       cgd 
    450  1.13     lukem #define	tty__gettabs(td)	((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
    451  1.13     lukem #define	tty__geteightbit(td)	(((td)->c_cflag & CSIZE) == CS8)
    452  1.13     lukem #define	tty__cooked_mode(td)	((td)->c_lflag & ICANON)
    453  1.13     lukem 
    454  1.26  christos private int	tty_getty(EditLine *, struct termios *);
    455  1.26  christos private int	tty_setty(EditLine *, int, const struct termios *);
    456  1.19  christos private int	tty__getcharindex(int);
    457  1.13     lukem private void	tty__getchar(struct termios *, unsigned char *);
    458  1.13     lukem private void	tty__setchar(struct termios *, unsigned char *);
    459  1.13     lukem private speed_t	tty__getspeed(struct termios *);
    460  1.13     lukem private int	tty_setup(EditLine *);
    461   1.1       cgd 
    462  1.13     lukem #define	t_qu	t_ts
    463   1.1       cgd 
    464  1.26  christos /* tty_getty():
    465  1.26  christos  *	Wrapper for tcgetattr to handle EINTR
    466  1.26  christos  */
    467  1.26  christos private int
    468  1.26  christos tty_getty(EditLine *el, struct termios *t)
    469  1.26  christos {
    470  1.26  christos 	int rv;
    471  1.26  christos 	while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR)
    472  1.26  christos 		continue;
    473  1.26  christos 	return rv;
    474  1.26  christos }
    475  1.26  christos 
    476  1.26  christos /* tty_setty():
    477  1.26  christos  *	Wrapper for tcsetattr to handle EINTR
    478  1.26  christos  */
    479  1.26  christos private int
    480  1.26  christos tty_setty(EditLine *el, int action, const struct termios *t)
    481  1.26  christos {
    482  1.26  christos 	int rv;
    483  1.26  christos 	while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR)
    484  1.26  christos 		continue;
    485  1.26  christos 	return rv;
    486  1.26  christos }
    487   1.1       cgd 
    488   1.1       cgd /* tty_setup():
    489   1.1       cgd  *	Get the tty parameters and initialize the editing state
    490   1.1       cgd  */
    491  1.11    simonb private int
    492  1.13     lukem tty_setup(EditLine *el)
    493   1.1       cgd {
    494  1.13     lukem 	int rst = 1;
    495  1.12  sommerfe 
    496  1.13     lukem 	if (el->el_flags & EDIT_DISABLED)
    497  1.13     lukem 		return (0);
    498  1.13     lukem 
    499  1.13     lukem 	if (tty_getty(el, &el->el_tty.t_ed) == -1) {
    500   1.1       cgd #ifdef DEBUG_TTY
    501  1.13     lukem 		(void) fprintf(el->el_errfile,
    502  1.13     lukem 		    "tty_setup: tty_getty: %s\n", strerror(errno));
    503   1.1       cgd #endif /* DEBUG_TTY */
    504  1.13     lukem 		return (-1);
    505  1.13     lukem 	}
    506  1.13     lukem 	el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
    507  1.13     lukem 
    508  1.13     lukem 	el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
    509  1.13     lukem 	el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
    510  1.13     lukem 	el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
    511  1.13     lukem 
    512  1.13     lukem 	el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
    513  1.13     lukem 	el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
    514  1.13     lukem 
    515  1.13     lukem 	el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
    516  1.13     lukem 	el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
    517  1.13     lukem 
    518  1.13     lukem 	el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
    519  1.13     lukem 	el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
    520  1.13     lukem 
    521  1.13     lukem 	el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
    522  1.13     lukem 	el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
    523  1.13     lukem 
    524  1.13     lukem 	/*
    525  1.13     lukem          * Reset the tty chars to reasonable defaults
    526  1.13     lukem          * If they are disabled, then enable them.
    527  1.13     lukem          */
    528  1.13     lukem 	if (rst) {
    529  1.13     lukem 		if (tty__cooked_mode(&el->el_tty.t_ts)) {
    530  1.13     lukem 			tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
    531  1.13     lukem 			/*
    532  1.13     lukem 	                 * Don't affect CMIN and CTIME for the editor mode
    533  1.13     lukem 	                 */
    534  1.13     lukem 			for (rst = 0; rst < C_NCC - 2; rst++)
    535  1.13     lukem 				if (el->el_tty.t_c[TS_IO][rst] !=
    536  1.13     lukem 				      el->el_tty.t_vdisable
    537  1.13     lukem 				    && el->el_tty.t_c[ED_IO][rst] !=
    538  1.13     lukem 				      el->el_tty.t_vdisable)
    539  1.13     lukem 					el->el_tty.t_c[ED_IO][rst] =
    540  1.13     lukem 					    el->el_tty.t_c[TS_IO][rst];
    541  1.13     lukem 			for (rst = 0; rst < C_NCC; rst++)
    542  1.13     lukem 				if (el->el_tty.t_c[TS_IO][rst] !=
    543  1.13     lukem 				    el->el_tty.t_vdisable)
    544  1.13     lukem 					el->el_tty.t_c[EX_IO][rst] =
    545  1.13     lukem 					    el->el_tty.t_c[TS_IO][rst];
    546  1.13     lukem 		}
    547  1.13     lukem 		tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
    548  1.26  christos 		if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
    549   1.1       cgd #ifdef DEBUG_TTY
    550  1.13     lukem 			(void) fprintf(el->el_errfile,
    551  1.13     lukem 			    "tty_setup: tty_setty: %s\n",
    552  1.13     lukem 			    strerror(errno));
    553   1.1       cgd #endif /* DEBUG_TTY */
    554  1.13     lukem 			return (-1);
    555  1.13     lukem 		}
    556  1.25  christos 	}
    557  1.25  christos #ifdef notdef
    558  1.25  christos 	else
    559  1.13     lukem 		tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
    560  1.25  christos #endif
    561  1.13     lukem 
    562  1.13     lukem 	el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
    563  1.13     lukem 	el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
    564  1.13     lukem 
    565  1.13     lukem 	el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
    566  1.13     lukem 	el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
    567  1.13     lukem 
    568  1.13     lukem 	el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
    569  1.13     lukem 	el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
    570  1.13     lukem 
    571  1.13     lukem 	el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
    572  1.13     lukem 	el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
    573  1.13     lukem 
    574  1.13     lukem 	tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
    575  1.13     lukem 	tty_bind_char(el, 1);
    576  1.13     lukem 	return (0);
    577   1.1       cgd }
    578   1.1       cgd 
    579   1.1       cgd protected int
    580  1.13     lukem tty_init(EditLine *el)
    581   1.1       cgd {
    582  1.13     lukem 
    583  1.13     lukem 	el->el_tty.t_mode = EX_IO;
    584  1.13     lukem 	el->el_tty.t_vdisable = _POSIX_VDISABLE;
    585  1.13     lukem 	(void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
    586  1.13     lukem 	(void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
    587  1.13     lukem 	return (tty_setup(el));
    588  1.13     lukem }
    589   1.1       cgd 
    590   1.1       cgd 
    591   1.1       cgd /* tty_end():
    592   1.1       cgd  *	Restore the tty to its original settings
    593   1.1       cgd  */
    594   1.1       cgd protected void
    595   1.1       cgd /*ARGSUSED*/
    596  1.17  christos tty_end(EditLine *el __attribute__((__unused__)))
    597   1.1       cgd {
    598  1.13     lukem 
    599  1.13     lukem 	/* XXX: Maybe reset to an initial state? */
    600   1.1       cgd }
    601   1.1       cgd 
    602   1.1       cgd 
    603   1.1       cgd /* tty__getspeed():
    604   1.1       cgd  *	Get the tty speed
    605   1.1       cgd  */
    606   1.1       cgd private speed_t
    607  1.13     lukem tty__getspeed(struct termios *td)
    608   1.1       cgd {
    609  1.13     lukem 	speed_t spd;
    610   1.1       cgd 
    611  1.13     lukem 	if ((spd = cfgetispeed(td)) == 0)
    612  1.13     lukem 		spd = cfgetospeed(td);
    613  1.13     lukem 	return (spd);
    614  1.13     lukem }
    615   1.1       cgd 
    616  1.19  christos /* tty__getspeed():
    617  1.19  christos  *	Return the index of the asked char in the c_cc array
    618  1.19  christos  */
    619  1.19  christos private int
    620  1.19  christos tty__getcharindex(int i)
    621  1.19  christos {
    622  1.19  christos 	switch (i) {
    623  1.19  christos #ifdef VINTR
    624  1.19  christos 	case C_INTR:
    625  1.19  christos 		return VINTR;
    626  1.19  christos #endif /* VINTR */
    627  1.19  christos #ifdef VQUIT
    628  1.19  christos 	case C_QUIT:
    629  1.19  christos 		return VQUIT;
    630  1.19  christos #endif /* VQUIT */
    631  1.19  christos #ifdef VERASE
    632  1.19  christos 	case C_ERASE:
    633  1.19  christos 		return VERASE;
    634  1.19  christos #endif /* VERASE */
    635  1.19  christos #ifdef VKILL
    636  1.19  christos 	case C_KILL:
    637  1.19  christos 		return VKILL;
    638  1.19  christos #endif /* VKILL */
    639  1.19  christos #ifdef VEOF
    640  1.19  christos 	case C_EOF:
    641  1.19  christos 		return VEOF;
    642  1.19  christos #endif /* VEOF */
    643  1.19  christos #ifdef VEOL
    644  1.19  christos 	case C_EOL:
    645  1.19  christos 		return VEOL;
    646  1.19  christos #endif /* VEOL */
    647  1.19  christos #ifdef VEOL2
    648  1.19  christos 	case C_EOL2:
    649  1.19  christos 		return VEOL2;
    650  1.19  christos #endif /* VEOL2 */
    651  1.19  christos #ifdef VSWTCH
    652  1.19  christos 	case C_SWTCH:
    653  1.19  christos 		return VSWTCH;
    654  1.19  christos #endif /* VSWTCH */
    655  1.19  christos #ifdef VDSWTCH
    656  1.19  christos 	case C_DSWTCH:
    657  1.19  christos 		return VDSWTCH;
    658  1.19  christos #endif /* VDSWTCH */
    659  1.19  christos #ifdef VERASE2
    660  1.19  christos 	case C_ERASE2:
    661  1.19  christos 		return VERASE2;
    662  1.19  christos #endif /* VERASE2 */
    663  1.19  christos #ifdef VSTART
    664  1.19  christos 	case C_START:
    665  1.19  christos 		return VSTART;
    666  1.19  christos #endif /* VSTART */
    667  1.19  christos #ifdef VSTOP
    668  1.19  christos 	case C_STOP:
    669  1.19  christos 		return VSTOP;
    670  1.19  christos #endif /* VSTOP */
    671  1.19  christos #ifdef VWERASE
    672  1.19  christos 	case C_WERASE:
    673  1.19  christos 		return VWERASE;
    674  1.19  christos #endif /* VWERASE */
    675  1.19  christos #ifdef VSUSP
    676  1.19  christos 	case C_SUSP:
    677  1.19  christos 		return VSUSP;
    678  1.19  christos #endif /* VSUSP */
    679  1.19  christos #ifdef VDSUSP
    680  1.19  christos 	case C_DSUSP:
    681  1.19  christos 		return VDSUSP;
    682  1.19  christos #endif /* VDSUSP */
    683  1.19  christos #ifdef VREPRINT
    684  1.19  christos 	case C_REPRINT:
    685  1.19  christos 		return VREPRINT;
    686  1.19  christos #endif /* VREPRINT */
    687  1.19  christos #ifdef VDISCARD
    688  1.19  christos 	case C_DISCARD:
    689  1.19  christos 		return VDISCARD;
    690  1.19  christos #endif /* VDISCARD */
    691  1.19  christos #ifdef VLNEXT
    692  1.19  christos 	case C_LNEXT:
    693  1.19  christos 		return VLNEXT;
    694  1.19  christos #endif /* VLNEXT */
    695  1.19  christos #ifdef VSTATUS
    696  1.19  christos 	case C_STATUS:
    697  1.19  christos 		return VSTATUS;
    698  1.19  christos #endif /* VSTATUS */
    699  1.19  christos #ifdef VPAGE
    700  1.19  christos 	case C_PAGE:
    701  1.19  christos 		return VPAGE;
    702  1.19  christos #endif /* VPAGE */
    703  1.19  christos #ifdef VPGOFF
    704  1.19  christos 	case C_PGOFF:
    705  1.19  christos 		return VPGOFF;
    706  1.19  christos #endif /* VPGOFF */
    707  1.19  christos #ifdef VKILL2
    708  1.19  christos 	case C_KILL2:
    709  1.19  christos 		return VKILL2;
    710  1.19  christos #endif /* KILL2 */
    711  1.19  christos #ifdef VMIN
    712  1.19  christos 	case C_MIN:
    713  1.19  christos 		return VMIN;
    714  1.19  christos #endif /* VMIN */
    715  1.19  christos #ifdef VTIME
    716  1.19  christos 	case C_TIME:
    717  1.19  christos 		return VTIME;
    718  1.19  christos #endif /* VTIME */
    719  1.19  christos 	default:
    720  1.19  christos 		return -1;
    721  1.19  christos 	}
    722  1.19  christos }
    723   1.1       cgd 
    724   1.1       cgd /* tty__getchar():
    725   1.1       cgd  *	Get the tty characters
    726   1.1       cgd  */
    727   1.1       cgd private void
    728  1.13     lukem tty__getchar(struct termios *td, unsigned char *s)
    729  1.11    simonb {
    730  1.13     lukem 
    731  1.13     lukem #ifdef VINTR
    732  1.13     lukem 	s[C_INTR] = td->c_cc[VINTR];
    733  1.13     lukem #endif /* VINTR */
    734  1.13     lukem #ifdef VQUIT
    735  1.13     lukem 	s[C_QUIT] = td->c_cc[VQUIT];
    736  1.13     lukem #endif /* VQUIT */
    737  1.13     lukem #ifdef VERASE
    738  1.13     lukem 	s[C_ERASE] = td->c_cc[VERASE];
    739  1.13     lukem #endif /* VERASE */
    740  1.13     lukem #ifdef VKILL
    741  1.13     lukem 	s[C_KILL] = td->c_cc[VKILL];
    742  1.13     lukem #endif /* VKILL */
    743  1.13     lukem #ifdef VEOF
    744  1.13     lukem 	s[C_EOF] = td->c_cc[VEOF];
    745  1.13     lukem #endif /* VEOF */
    746  1.13     lukem #ifdef VEOL
    747  1.13     lukem 	s[C_EOL] = td->c_cc[VEOL];
    748  1.13     lukem #endif /* VEOL */
    749  1.13     lukem #ifdef VEOL2
    750  1.13     lukem 	s[C_EOL2] = td->c_cc[VEOL2];
    751  1.13     lukem #endif /* VEOL2 */
    752  1.13     lukem #ifdef VSWTCH
    753  1.13     lukem 	s[C_SWTCH] = td->c_cc[VSWTCH];
    754  1.13     lukem #endif /* VSWTCH */
    755  1.13     lukem #ifdef VDSWTCH
    756  1.13     lukem 	s[C_DSWTCH] = td->c_cc[VDSWTCH];
    757  1.13     lukem #endif /* VDSWTCH */
    758  1.13     lukem #ifdef VERASE2
    759  1.13     lukem 	s[C_ERASE2] = td->c_cc[VERASE2];
    760  1.13     lukem #endif /* VERASE2 */
    761  1.13     lukem #ifdef VSTART
    762  1.13     lukem 	s[C_START] = td->c_cc[VSTART];
    763  1.13     lukem #endif /* VSTART */
    764  1.13     lukem #ifdef VSTOP
    765  1.13     lukem 	s[C_STOP] = td->c_cc[VSTOP];
    766  1.13     lukem #endif /* VSTOP */
    767  1.13     lukem #ifdef VWERASE
    768  1.13     lukem 	s[C_WERASE] = td->c_cc[VWERASE];
    769  1.13     lukem #endif /* VWERASE */
    770  1.13     lukem #ifdef VSUSP
    771  1.13     lukem 	s[C_SUSP] = td->c_cc[VSUSP];
    772  1.13     lukem #endif /* VSUSP */
    773  1.13     lukem #ifdef VDSUSP
    774  1.13     lukem 	s[C_DSUSP] = td->c_cc[VDSUSP];
    775  1.13     lukem #endif /* VDSUSP */
    776  1.13     lukem #ifdef VREPRINT
    777  1.13     lukem 	s[C_REPRINT] = td->c_cc[VREPRINT];
    778  1.13     lukem #endif /* VREPRINT */
    779  1.13     lukem #ifdef VDISCARD
    780  1.13     lukem 	s[C_DISCARD] = td->c_cc[VDISCARD];
    781  1.13     lukem #endif /* VDISCARD */
    782  1.13     lukem #ifdef VLNEXT
    783  1.13     lukem 	s[C_LNEXT] = td->c_cc[VLNEXT];
    784  1.13     lukem #endif /* VLNEXT */
    785  1.13     lukem #ifdef VSTATUS
    786  1.13     lukem 	s[C_STATUS] = td->c_cc[VSTATUS];
    787  1.13     lukem #endif /* VSTATUS */
    788  1.13     lukem #ifdef VPAGE
    789  1.13     lukem 	s[C_PAGE] = td->c_cc[VPAGE];
    790  1.13     lukem #endif /* VPAGE */
    791  1.13     lukem #ifdef VPGOFF
    792  1.13     lukem 	s[C_PGOFF] = td->c_cc[VPGOFF];
    793  1.13     lukem #endif /* VPGOFF */
    794  1.13     lukem #ifdef VKILL2
    795  1.13     lukem 	s[C_KILL2] = td->c_cc[VKILL2];
    796  1.13     lukem #endif /* KILL2 */
    797  1.13     lukem #ifdef VMIN
    798  1.13     lukem 	s[C_MIN] = td->c_cc[VMIN];
    799  1.13     lukem #endif /* VMIN */
    800  1.13     lukem #ifdef VTIME
    801  1.13     lukem 	s[C_TIME] = td->c_cc[VTIME];
    802  1.13     lukem #endif /* VTIME */
    803  1.13     lukem }				/* tty__getchar */
    804   1.1       cgd 
    805   1.1       cgd 
    806   1.1       cgd /* tty__setchar():
    807   1.1       cgd  *	Set the tty characters
    808   1.1       cgd  */
    809   1.1       cgd private void
    810  1.13     lukem tty__setchar(struct termios *td, unsigned char *s)
    811  1.11    simonb {
    812  1.13     lukem 
    813  1.13     lukem #ifdef VINTR
    814  1.13     lukem 	td->c_cc[VINTR] = s[C_INTR];
    815  1.13     lukem #endif /* VINTR */
    816  1.13     lukem #ifdef VQUIT
    817  1.13     lukem 	td->c_cc[VQUIT] = s[C_QUIT];
    818  1.13     lukem #endif /* VQUIT */
    819  1.13     lukem #ifdef VERASE
    820  1.13     lukem 	td->c_cc[VERASE] = s[C_ERASE];
    821  1.13     lukem #endif /* VERASE */
    822  1.13     lukem #ifdef VKILL
    823  1.13     lukem 	td->c_cc[VKILL] = s[C_KILL];
    824  1.13     lukem #endif /* VKILL */
    825  1.13     lukem #ifdef VEOF
    826  1.13     lukem 	td->c_cc[VEOF] = s[C_EOF];
    827  1.13     lukem #endif /* VEOF */
    828  1.13     lukem #ifdef VEOL
    829  1.13     lukem 	td->c_cc[VEOL] = s[C_EOL];
    830  1.13     lukem #endif /* VEOL */
    831  1.13     lukem #ifdef VEOL2
    832  1.13     lukem 	td->c_cc[VEOL2] = s[C_EOL2];
    833  1.13     lukem #endif /* VEOL2 */
    834  1.13     lukem #ifdef VSWTCH
    835  1.13     lukem 	td->c_cc[VSWTCH] = s[C_SWTCH];
    836  1.13     lukem #endif /* VSWTCH */
    837  1.13     lukem #ifdef VDSWTCH
    838  1.13     lukem 	td->c_cc[VDSWTCH] = s[C_DSWTCH];
    839  1.13     lukem #endif /* VDSWTCH */
    840  1.13     lukem #ifdef VERASE2
    841  1.13     lukem 	td->c_cc[VERASE2] = s[C_ERASE2];
    842  1.13     lukem #endif /* VERASE2 */
    843  1.13     lukem #ifdef VSTART
    844  1.13     lukem 	td->c_cc[VSTART] = s[C_START];
    845  1.13     lukem #endif /* VSTART */
    846  1.13     lukem #ifdef VSTOP
    847  1.13     lukem 	td->c_cc[VSTOP] = s[C_STOP];
    848  1.13     lukem #endif /* VSTOP */
    849  1.13     lukem #ifdef VWERASE
    850  1.13     lukem 	td->c_cc[VWERASE] = s[C_WERASE];
    851  1.13     lukem #endif /* VWERASE */
    852  1.13     lukem #ifdef VSUSP
    853  1.13     lukem 	td->c_cc[VSUSP] = s[C_SUSP];
    854  1.13     lukem #endif /* VSUSP */
    855  1.13     lukem #ifdef VDSUSP
    856  1.13     lukem 	td->c_cc[VDSUSP] = s[C_DSUSP];
    857  1.13     lukem #endif /* VDSUSP */
    858  1.13     lukem #ifdef VREPRINT
    859  1.13     lukem 	td->c_cc[VREPRINT] = s[C_REPRINT];
    860  1.13     lukem #endif /* VREPRINT */
    861  1.13     lukem #ifdef VDISCARD
    862  1.13     lukem 	td->c_cc[VDISCARD] = s[C_DISCARD];
    863  1.13     lukem #endif /* VDISCARD */
    864  1.13     lukem #ifdef VLNEXT
    865  1.13     lukem 	td->c_cc[VLNEXT] = s[C_LNEXT];
    866  1.13     lukem #endif /* VLNEXT */
    867  1.13     lukem #ifdef VSTATUS
    868  1.13     lukem 	td->c_cc[VSTATUS] = s[C_STATUS];
    869  1.13     lukem #endif /* VSTATUS */
    870  1.13     lukem #ifdef VPAGE
    871  1.13     lukem 	td->c_cc[VPAGE] = s[C_PAGE];
    872  1.13     lukem #endif /* VPAGE */
    873  1.13     lukem #ifdef VPGOFF
    874  1.13     lukem 	td->c_cc[VPGOFF] = s[C_PGOFF];
    875  1.13     lukem #endif /* VPGOFF */
    876  1.13     lukem #ifdef VKILL2
    877  1.13     lukem 	td->c_cc[VKILL2] = s[C_KILL2];
    878  1.13     lukem #endif /* VKILL2 */
    879  1.13     lukem #ifdef VMIN
    880  1.13     lukem 	td->c_cc[VMIN] = s[C_MIN];
    881  1.13     lukem #endif /* VMIN */
    882  1.13     lukem #ifdef VTIME
    883  1.13     lukem 	td->c_cc[VTIME] = s[C_TIME];
    884  1.13     lukem #endif /* VTIME */
    885  1.13     lukem }				/* tty__setchar */
    886   1.1       cgd 
    887   1.1       cgd 
    888   1.1       cgd /* tty_bind_char():
    889   1.1       cgd  *	Rebind the editline functions
    890   1.1       cgd  */
    891   1.1       cgd protected void
    892  1.13     lukem tty_bind_char(EditLine *el, int force)
    893   1.1       cgd {
    894  1.13     lukem 
    895  1.13     lukem 	unsigned char *t_n = el->el_tty.t_c[ED_IO];
    896  1.13     lukem 	unsigned char *t_o = el->el_tty.t_ed.c_cc;
    897  1.32  christos 	Char new[2], old[2];
    898  1.14  jdolecek 	const ttymap_t *tp;
    899  1.14  jdolecek 	el_action_t *map, *alt;
    900  1.14  jdolecek 	const el_action_t *dmap, *dalt;
    901  1.13     lukem 	new[1] = old[1] = '\0';
    902  1.13     lukem 
    903  1.13     lukem 	map = el->el_map.key;
    904  1.13     lukem 	alt = el->el_map.alt;
    905  1.13     lukem 	if (el->el_map.type == MAP_VI) {
    906  1.13     lukem 		dmap = el->el_map.vii;
    907  1.13     lukem 		dalt = el->el_map.vic;
    908  1.13     lukem 	} else {
    909  1.13     lukem 		dmap = el->el_map.emacs;
    910  1.13     lukem 		dalt = NULL;
    911  1.13     lukem 	}
    912  1.13     lukem 
    913  1.13     lukem 	for (tp = tty_map; tp->nch != -1; tp++) {
    914  1.13     lukem 		new[0] = t_n[tp->nch];
    915  1.13     lukem 		old[0] = t_o[tp->och];
    916  1.13     lukem 		if (new[0] == old[0] && !force)
    917  1.13     lukem 			continue;
    918  1.13     lukem 		/* Put the old default binding back, and set the new binding */
    919  1.32  christos 		key_clear(el, map, old);
    920  1.32  christos 		map[UC(old[0])] = dmap[UC(old[0])];
    921  1.32  christos 		key_clear(el, map, new);
    922  1.13     lukem 		/* MAP_VI == 1, MAP_EMACS == 0... */
    923  1.32  christos 		map[UC(new[0])] = tp->bind[el->el_map.type];
    924  1.13     lukem 		if (dalt) {
    925  1.32  christos 			key_clear(el, alt, old);
    926  1.32  christos 			alt[UC(old[0])] = dalt[UC(old[0])];
    927  1.32  christos 			key_clear(el, alt, new);
    928  1.32  christos 			alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
    929  1.13     lukem 		}
    930   1.1       cgd 	}
    931   1.1       cgd }
    932   1.1       cgd 
    933  1.13     lukem 
    934   1.1       cgd /* tty_rawmode():
    935   1.1       cgd  * 	Set terminal into 1 character at a time mode.
    936   1.1       cgd  */
    937   1.1       cgd protected int
    938  1.13     lukem tty_rawmode(EditLine *el)
    939   1.1       cgd {
    940   1.1       cgd 
    941  1.13     lukem 	if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
    942  1.13     lukem 		return (0);
    943  1.13     lukem 
    944  1.13     lukem 	if (el->el_flags & EDIT_DISABLED)
    945  1.13     lukem 		return (0);
    946  1.12  sommerfe 
    947  1.13     lukem 	if (tty_getty(el, &el->el_tty.t_ts) == -1) {
    948   1.1       cgd #ifdef DEBUG_TTY
    949  1.13     lukem 		(void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
    950  1.13     lukem 		    strerror(errno));
    951   1.1       cgd #endif /* DEBUG_TTY */
    952  1.13     lukem 		return (-1);
    953   1.1       cgd 	}
    954  1.13     lukem 	/*
    955  1.13     lukem          * We always keep up with the eight bit setting and the speed of the
    956  1.32  christos          * tty. But we only believe changes that are made to cooked mode!
    957  1.13     lukem          */
    958  1.13     lukem 	el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
    959  1.13     lukem 	el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
    960  1.13     lukem 
    961  1.13     lukem 	if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
    962  1.13     lukem 	    tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
    963  1.13     lukem 		(void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
    964  1.13     lukem 		(void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
    965  1.13     lukem 		(void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
    966  1.13     lukem 		(void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
    967   1.1       cgd 	}
    968  1.13     lukem 	if (tty__cooked_mode(&el->el_tty.t_ts)) {
    969  1.13     lukem 		if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
    970  1.13     lukem 			el->el_tty.t_ex.c_cflag =
    971  1.13     lukem 			    el->el_tty.t_ts.c_cflag;
    972  1.13     lukem 			el->el_tty.t_ex.c_cflag &=
    973  1.13     lukem 			    ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
    974  1.13     lukem 			el->el_tty.t_ex.c_cflag |=
    975  1.13     lukem 			    el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
    976  1.13     lukem 
    977  1.13     lukem 			el->el_tty.t_ed.c_cflag =
    978  1.13     lukem 			    el->el_tty.t_ts.c_cflag;
    979  1.13     lukem 			el->el_tty.t_ed.c_cflag &=
    980  1.13     lukem 			    ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
    981  1.13     lukem 			el->el_tty.t_ed.c_cflag |=
    982  1.13     lukem 			    el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
    983  1.13     lukem 		}
    984  1.13     lukem 		if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
    985  1.13     lukem 		    (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
    986  1.13     lukem 			el->el_tty.t_ex.c_lflag =
    987  1.13     lukem 			    el->el_tty.t_ts.c_lflag;
    988  1.13     lukem 			el->el_tty.t_ex.c_lflag &=
    989  1.13     lukem 			    ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
    990  1.13     lukem 			el->el_tty.t_ex.c_lflag |=
    991  1.13     lukem 			    el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
    992  1.13     lukem 
    993  1.13     lukem 			el->el_tty.t_ed.c_lflag =
    994  1.13     lukem 			    el->el_tty.t_ts.c_lflag;
    995  1.13     lukem 			el->el_tty.t_ed.c_lflag &=
    996  1.13     lukem 			    ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
    997  1.13     lukem 			el->el_tty.t_ed.c_lflag |=
    998  1.13     lukem 			    el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
    999  1.13     lukem 		}
   1000  1.13     lukem 		if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
   1001  1.13     lukem 		    (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
   1002  1.13     lukem 			el->el_tty.t_ex.c_iflag =
   1003  1.13     lukem 			    el->el_tty.t_ts.c_iflag;
   1004  1.13     lukem 			el->el_tty.t_ex.c_iflag &=
   1005  1.13     lukem 			    ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
   1006  1.13     lukem 			el->el_tty.t_ex.c_iflag |=
   1007  1.13     lukem 			    el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
   1008  1.13     lukem 
   1009  1.13     lukem 			el->el_tty.t_ed.c_iflag =
   1010  1.13     lukem 			    el->el_tty.t_ts.c_iflag;
   1011  1.13     lukem 			el->el_tty.t_ed.c_iflag &=
   1012  1.13     lukem 			    ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
   1013  1.13     lukem 			el->el_tty.t_ed.c_iflag |=
   1014  1.13     lukem 			    el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
   1015  1.13     lukem 		}
   1016  1.13     lukem 		if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
   1017  1.13     lukem 		    (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
   1018  1.13     lukem 			el->el_tty.t_ex.c_oflag =
   1019  1.13     lukem 			    el->el_tty.t_ts.c_oflag;
   1020  1.13     lukem 			el->el_tty.t_ex.c_oflag &=
   1021  1.13     lukem 			    ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
   1022  1.13     lukem 			el->el_tty.t_ex.c_oflag |=
   1023  1.13     lukem 			    el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
   1024  1.13     lukem 
   1025  1.13     lukem 			el->el_tty.t_ed.c_oflag =
   1026  1.13     lukem 			    el->el_tty.t_ts.c_oflag;
   1027  1.13     lukem 			el->el_tty.t_ed.c_oflag &=
   1028  1.13     lukem 			    ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
   1029  1.13     lukem 			el->el_tty.t_ed.c_oflag |=
   1030  1.13     lukem 			    el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
   1031  1.13     lukem 		}
   1032  1.13     lukem 		if (tty__gettabs(&el->el_tty.t_ex) == 0)
   1033  1.13     lukem 			el->el_tty.t_tabs = 0;
   1034  1.13     lukem 		else
   1035  1.13     lukem 			el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
   1036   1.1       cgd 
   1037  1.13     lukem 		{
   1038  1.13     lukem 			int i;
   1039   1.1       cgd 
   1040  1.13     lukem 			tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
   1041  1.13     lukem 			/*
   1042  1.13     lukem 		         * Check if the user made any changes.
   1043  1.13     lukem 		         * If he did, then propagate the changes to the
   1044  1.13     lukem 		         * edit and execute data structures.
   1045  1.13     lukem 		         */
   1046  1.13     lukem 			for (i = 0; i < C_NCC; i++)
   1047  1.13     lukem 				if (el->el_tty.t_c[TS_IO][i] !=
   1048  1.13     lukem 				    el->el_tty.t_c[EX_IO][i])
   1049  1.13     lukem 					break;
   1050  1.13     lukem 
   1051  1.13     lukem 			if (i != C_NCC) {
   1052  1.13     lukem 				/*
   1053  1.13     lukem 				 * Propagate changes only to the unprotected
   1054  1.13     lukem 				 * chars that have been modified just now.
   1055  1.13     lukem 				 */
   1056  1.13     lukem 				for (i = 0; i < C_NCC; i++) {
   1057  1.13     lukem 					if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
   1058  1.13     lukem 					    && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
   1059  1.13     lukem 						el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
   1060  1.13     lukem 					if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
   1061  1.13     lukem 						el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
   1062  1.13     lukem 				}
   1063  1.13     lukem 				tty_bind_char(el, 0);
   1064  1.13     lukem 				tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
   1065  1.13     lukem 
   1066  1.13     lukem 				for (i = 0; i < C_NCC; i++) {
   1067  1.13     lukem 					if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
   1068  1.13     lukem 					    && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
   1069  1.13     lukem 						el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
   1070  1.13     lukem 					if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
   1071  1.13     lukem 						el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
   1072  1.13     lukem 				}
   1073  1.13     lukem 				tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
   1074  1.13     lukem 			}
   1075   1.1       cgd 		}
   1076   1.1       cgd 	}
   1077  1.26  christos 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
   1078   1.1       cgd #ifdef DEBUG_TTY
   1079  1.13     lukem 		(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
   1080  1.13     lukem 		    strerror(errno));
   1081   1.1       cgd #endif /* DEBUG_TTY */
   1082  1.13     lukem 		return (-1);
   1083  1.13     lukem 	}
   1084  1.13     lukem 	el->el_tty.t_mode = ED_IO;
   1085  1.13     lukem 	return (0);
   1086  1.13     lukem }
   1087   1.1       cgd 
   1088   1.1       cgd 
   1089   1.1       cgd /* tty_cookedmode():
   1090   1.1       cgd  *	Set the tty back to normal mode
   1091   1.1       cgd  */
   1092   1.1       cgd protected int
   1093  1.13     lukem tty_cookedmode(EditLine *el)
   1094   1.1       cgd {				/* set tty in normal setup */
   1095   1.1       cgd 
   1096  1.13     lukem 	if (el->el_tty.t_mode == EX_IO)
   1097  1.13     lukem 		return (0);
   1098  1.13     lukem 
   1099  1.13     lukem 	if (el->el_flags & EDIT_DISABLED)
   1100  1.13     lukem 		return (0);
   1101  1.13     lukem 
   1102  1.26  christos 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
   1103   1.1       cgd #ifdef DEBUG_TTY
   1104  1.13     lukem 		(void) fprintf(el->el_errfile,
   1105  1.13     lukem 		    "tty_cookedmode: tty_setty: %s\n",
   1106  1.13     lukem 		    strerror(errno));
   1107   1.1       cgd #endif /* DEBUG_TTY */
   1108  1.13     lukem 		return (-1);
   1109  1.13     lukem 	}
   1110  1.13     lukem 	el->el_tty.t_mode = EX_IO;
   1111  1.13     lukem 	return (0);
   1112  1.13     lukem }
   1113   1.1       cgd 
   1114   1.1       cgd 
   1115   1.1       cgd /* tty_quotemode():
   1116   1.1       cgd  *	Turn on quote mode
   1117   1.1       cgd  */
   1118   1.1       cgd protected int
   1119  1.13     lukem tty_quotemode(EditLine *el)
   1120   1.1       cgd {
   1121  1.13     lukem 	if (el->el_tty.t_mode == QU_IO)
   1122  1.13     lukem 		return (0);
   1123   1.1       cgd 
   1124  1.13     lukem 	el->el_tty.t_qu = el->el_tty.t_ed;
   1125   1.1       cgd 
   1126  1.13     lukem 	el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
   1127  1.13     lukem 	el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
   1128   1.1       cgd 
   1129  1.13     lukem 	el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
   1130  1.13     lukem 	el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
   1131   1.1       cgd 
   1132  1.13     lukem 	el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
   1133  1.13     lukem 	el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
   1134   1.1       cgd 
   1135  1.13     lukem 	el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
   1136  1.13     lukem 	el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
   1137   1.1       cgd 
   1138  1.26  christos 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
   1139   1.1       cgd #ifdef DEBUG_TTY
   1140  1.13     lukem 		(void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
   1141  1.13     lukem 		    strerror(errno));
   1142   1.1       cgd #endif /* DEBUG_TTY */
   1143  1.13     lukem 		return (-1);
   1144  1.13     lukem 	}
   1145  1.13     lukem 	el->el_tty.t_mode = QU_IO;
   1146  1.13     lukem 	return (0);
   1147  1.13     lukem }
   1148   1.1       cgd 
   1149   1.1       cgd 
   1150   1.1       cgd /* tty_noquotemode():
   1151   1.1       cgd  *	Turn off quote mode
   1152   1.1       cgd  */
   1153   1.1       cgd protected int
   1154  1.13     lukem tty_noquotemode(EditLine *el)
   1155   1.1       cgd {
   1156  1.13     lukem 
   1157  1.13     lukem 	if (el->el_tty.t_mode != QU_IO)
   1158  1.13     lukem 		return (0);
   1159  1.26  christos 	if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
   1160   1.1       cgd #ifdef DEBUG_TTY
   1161  1.13     lukem 		(void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
   1162  1.13     lukem 		    strerror(errno));
   1163   1.1       cgd #endif /* DEBUG_TTY */
   1164  1.13     lukem 		return (-1);
   1165  1.13     lukem 	}
   1166  1.13     lukem 	el->el_tty.t_mode = ED_IO;
   1167  1.13     lukem 	return (0);
   1168   1.1       cgd }
   1169   1.1       cgd 
   1170  1.13     lukem 
   1171   1.1       cgd /* tty_stty():
   1172   1.1       cgd  *	Stty builtin
   1173   1.1       cgd  */
   1174   1.1       cgd protected int
   1175   1.1       cgd /*ARGSUSED*/
   1176  1.32  christos tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
   1177   1.1       cgd {
   1178  1.14  jdolecek 	const ttymodes_t *m;
   1179  1.16  christos 	char x;
   1180  1.13     lukem 	int aflag = 0;
   1181  1.32  christos 	const Char *s, *d;
   1182  1.32  christos         char name[EL_BUFSIZ];
   1183  1.19  christos 	struct termios *tios = &el->el_tty.t_ex;
   1184  1.13     lukem 	int z = EX_IO;
   1185  1.13     lukem 
   1186  1.13     lukem 	if (argv == NULL)
   1187  1.13     lukem 		return (-1);
   1188  1.32  christos 	strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
   1189  1.32  christos         name[sizeof(name) - 1] = '\0';
   1190  1.13     lukem 
   1191  1.13     lukem 	while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
   1192  1.13     lukem 		switch (argv[0][1]) {
   1193  1.13     lukem 		case 'a':
   1194  1.13     lukem 			aflag++;
   1195  1.13     lukem 			argv++;
   1196  1.13     lukem 			break;
   1197  1.13     lukem 		case 'd':
   1198  1.13     lukem 			argv++;
   1199  1.19  christos 			tios = &el->el_tty.t_ed;
   1200  1.13     lukem 			z = ED_IO;
   1201  1.13     lukem 			break;
   1202  1.13     lukem 		case 'x':
   1203  1.13     lukem 			argv++;
   1204  1.19  christos 			tios = &el->el_tty.t_ex;
   1205  1.13     lukem 			z = EX_IO;
   1206  1.13     lukem 			break;
   1207  1.13     lukem 		case 'q':
   1208  1.13     lukem 			argv++;
   1209  1.19  christos 			tios = &el->el_tty.t_ts;
   1210  1.13     lukem 			z = QU_IO;
   1211  1.13     lukem 			break;
   1212  1.13     lukem 		default:
   1213  1.13     lukem 			(void) fprintf(el->el_errfile,
   1214  1.13     lukem 			    "%s: Unknown switch `%c'.\n",
   1215  1.13     lukem 			    name, argv[0][1]);
   1216  1.13     lukem 			return (-1);
   1217  1.13     lukem 		}
   1218   1.1       cgd 
   1219  1.13     lukem 	if (!argv || !*argv) {
   1220  1.13     lukem 		int i = -1;
   1221  1.29  christos 		size_t len = 0, st = 0, cu;
   1222  1.13     lukem 		for (m = ttymodes; m->m_name; m++) {
   1223  1.13     lukem 			if (m->m_type != i) {
   1224  1.13     lukem 				(void) fprintf(el->el_outfile, "%s%s",
   1225  1.13     lukem 				    i != -1 ? "\n" : "",
   1226  1.13     lukem 				    el->el_tty.t_t[z][m->m_type].t_name);
   1227  1.13     lukem 				i = m->m_type;
   1228  1.13     lukem 				st = len =
   1229  1.13     lukem 				    strlen(el->el_tty.t_t[z][m->m_type].t_name);
   1230  1.13     lukem 			}
   1231  1.24  christos 			if (i != -1) {
   1232  1.24  christos 			    x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
   1233  1.24  christos 				?  '+' : '\0';
   1234  1.24  christos 			    x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
   1235  1.24  christos 				? '-' : x;
   1236  1.24  christos 			} else {
   1237  1.24  christos 			    x = '\0';
   1238  1.24  christos 			}
   1239  1.13     lukem 
   1240  1.13     lukem 			if (x != '\0' || aflag) {
   1241  1.13     lukem 
   1242  1.13     lukem 				cu = strlen(m->m_name) + (x != '\0') + 1;
   1243  1.13     lukem 
   1244  1.30  christos 				if (len + cu >= (size_t)el->el_term.t_size.h) {
   1245  1.13     lukem 					(void) fprintf(el->el_outfile, "\n%*s",
   1246  1.29  christos 					    (int)st, "");
   1247  1.13     lukem 					len = st + cu;
   1248  1.13     lukem 				} else
   1249  1.13     lukem 					len += cu;
   1250  1.13     lukem 
   1251  1.13     lukem 				if (x != '\0')
   1252  1.13     lukem 					(void) fprintf(el->el_outfile, "%c%s ",
   1253  1.13     lukem 					    x, m->m_name);
   1254  1.13     lukem 				else
   1255  1.13     lukem 					(void) fprintf(el->el_outfile, "%s ",
   1256  1.13     lukem 					    m->m_name);
   1257  1.13     lukem 			}
   1258   1.1       cgd 		}
   1259  1.13     lukem 		(void) fprintf(el->el_outfile, "\n");
   1260  1.13     lukem 		return (0);
   1261   1.1       cgd 	}
   1262  1.13     lukem 	while (argv && (s = *argv++)) {
   1263  1.32  christos 		const Char *p;
   1264  1.13     lukem 		switch (*s) {
   1265  1.13     lukem 		case '+':
   1266  1.13     lukem 		case '-':
   1267  1.13     lukem 			x = *s++;
   1268  1.13     lukem 			break;
   1269  1.13     lukem 		default:
   1270  1.13     lukem 			x = '\0';
   1271  1.13     lukem 			break;
   1272  1.13     lukem 		}
   1273  1.13     lukem 		d = s;
   1274  1.32  christos 		p = Strchr(s, '=');
   1275  1.13     lukem 		for (m = ttymodes; m->m_name; m++)
   1276  1.32  christos 			if ((p ? strncmp(m->m_name, ct_encode_string(d, &el->el_scratch), (size_t)(p - d)) :
   1277  1.32  christos 			    strcmp(m->m_name, ct_encode_string(d, &el->el_scratch))) == 0 &&
   1278  1.19  christos 			    (p == NULL || m->m_type == MD_CHAR))
   1279  1.13     lukem 				break;
   1280  1.13     lukem 
   1281  1.13     lukem 		if (!m->m_name) {
   1282  1.13     lukem 			(void) fprintf(el->el_errfile,
   1283  1.32  christos 			    "%s: Invalid argument `" FSTR "'.\n", name, d);
   1284  1.13     lukem 			return (-1);
   1285  1.19  christos 		}
   1286  1.19  christos 		if (p) {
   1287  1.19  christos 			int c = ffs((int)m->m_value);
   1288  1.32  christos 			int v = *++p ? parse__escape(&p) :
   1289  1.19  christos 			    el->el_tty.t_vdisable;
   1290  1.31  christos 			assert(c != 0);
   1291  1.31  christos 			c--;
   1292  1.19  christos 			c = tty__getcharindex(c);
   1293  1.19  christos 			assert(c != -1);
   1294  1.19  christos 			tios->c_cc[c] = v;
   1295  1.19  christos 			continue;
   1296  1.13     lukem 		}
   1297  1.13     lukem 		switch (x) {
   1298  1.13     lukem 		case '+':
   1299  1.13     lukem 			el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
   1300  1.13     lukem 			el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
   1301  1.13     lukem 			break;
   1302  1.13     lukem 		case '-':
   1303  1.13     lukem 			el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
   1304  1.13     lukem 			el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
   1305  1.13     lukem 			break;
   1306  1.13     lukem 		default:
   1307  1.13     lukem 			el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
   1308  1.13     lukem 			el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
   1309  1.13     lukem 			break;
   1310  1.13     lukem 		}
   1311   1.1       cgd 	}
   1312  1.27  christos 
   1313  1.27  christos 	if (el->el_tty.t_mode == z) {
   1314  1.27  christos 		if (tty_setty(el, TCSADRAIN, tios) == -1) {
   1315  1.27  christos #ifdef DEBUG_TTY
   1316  1.27  christos 			(void) fprintf(el->el_errfile,
   1317  1.27  christos 			    "tty_stty: tty_setty: %s\n", strerror(errno));
   1318  1.27  christos #endif /* DEBUG_TTY */
   1319  1.27  christos 			return (-1);
   1320  1.27  christos 		}
   1321  1.27  christos 	}
   1322  1.27  christos 
   1323  1.13     lukem 	return (0);
   1324  1.13     lukem }
   1325   1.1       cgd 
   1326   1.1       cgd 
   1327   1.1       cgd #ifdef notyet
   1328   1.1       cgd /* tty_printchar():
   1329   1.1       cgd  *	DEbugging routine to print the tty characters
   1330   1.1       cgd  */
   1331   1.1       cgd private void
   1332  1.13     lukem tty_printchar(EditLine *el, unsigned char *s)
   1333   1.1       cgd {
   1334  1.13     lukem 	ttyperm_t *m;
   1335  1.13     lukem 	int i;
   1336   1.1       cgd 
   1337  1.13     lukem 	for (i = 0; i < C_NCC; i++) {
   1338  1.13     lukem 		for (m = el->el_tty.t_t; m->m_name; m++)
   1339  1.13     lukem 			if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
   1340  1.13     lukem 				break;
   1341  1.13     lukem 		if (m->m_name)
   1342  1.13     lukem 			(void) fprintf(el->el_errfile, "%s ^%c ",
   1343  1.13     lukem 			    m->m_name, s[i] + 'A' - 1);
   1344  1.13     lukem 		if (i % 5 == 0)
   1345  1.13     lukem 			(void) fprintf(el->el_errfile, "\n");
   1346  1.13     lukem 	}
   1347  1.13     lukem 	(void) fprintf(el->el_errfile, "\n");
   1348   1.1       cgd }
   1349   1.1       cgd #endif /* notyet */
   1350