/contrib/tcsh/ed.term.c
https://bitbucket.org/freebsd/freebsd-head/ · C · 1141 lines · 1021 code · 64 blank · 56 comment · 131 complexity · 0557706028600e5853c82f3c1f9ae76e MD5 · raw file
- /* $Header: /p/tcsh/cvsroot/tcsh/ed.term.c,v 1.38 2011/02/25 23:58:34 christos Exp $ */
- /*
- * ed.term.c: Low level terminal interface
- */
- /*-
- * Copyright (c) 1980, 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- #include "sh.h"
- #ifndef WINNT_NATIVE
- RCSID("$tcsh: ed.term.c,v 1.38 2011/02/25 23:58:34 christos Exp $")
- #include <assert.h>
- #include "ed.h"
- int didsetty = 0;
- ttyperm_t ttylist = {
- {
- #if defined(POSIX) || defined(TERMIO)
- { "iflag:", ICRNL, (INLCR|IGNCR) },
- { "oflag:", (OPOST|ONLCR), ONLRET },
- { "cflag:", 0, 0 },
- { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
- (NOFLSH|ECHONL|EXTPROC|FLUSHO|IDEFAULT) },
- #else /* GSTTY */
- { "nrmal:", (ECHO|CRMOD|ANYP), (CBREAK|RAW|LCASE|VTDELAY|ALLDELAY) },
- { "local:", (LCRTBS|LCRTERA|LCRTKIL), (LPRTERA|LFLUSHO) },
- #endif /* POSIX || TERMIO */
- { "chars:", 0, 0 },
- },
- {
- #if defined(POSIX) || defined(TERMIO)
- { "iflag:", (INLCR|ICRNL), IGNCR },
- { "oflag:", (OPOST|ONLCR), ONLRET },
- { "cflag:", 0, 0 },
- { "lflag:", ISIG,
- (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO|
- IDEFAULT) },
- #else /* GSTTY */
- { "nrmal:", (CBREAK|CRMOD|ANYP), (RAW|ECHO|LCASE|VTDELAY|ALLDELAY) },
- { "local:", (LCRTBS|LCRTERA|LCRTKIL), (LPRTERA|LFLUSHO) },
- #endif /* POSIX || TERMIO */
- { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
- C_SH(C_WERASE)|C_SH(C_REPRINT)|C_SH(C_SUSP)|C_SH(C_DSUSP)|
- C_SH(C_EOF)|C_SH(C_EOL)|C_SH(C_DISCARD)|C_SH(C_PGOFF)|
- C_SH(C_KILL2)|C_SH(C_PAGE)|C_SH(C_STATUS)|C_SH(C_LNEXT)),
- 0 }
- },
- {
- #if defined(POSIX) || defined(TERMIO)
- { "iflag:", 0, IXON | IXOFF },
- { "oflag:", 0, 0 },
- { "cflag:", 0, 0 },
- { "lflag:", 0, ISIG | IEXTEN },
- #else /* GSTTY */
- { "nrmal:", RAW, CBREAK },
- { "local:", 0, 0 },
- #endif /* POSIX || TERMIO */
- { "chars:", 0, 0 },
- }
- };
- static const struct tcshmodes {
- const char *m_name;
- #ifdef SOLARIS2
- unsigned long m_value;
- #else /* !SOLARIS2 */
- int m_value;
- #endif /* SOLARIS2 */
- int m_type;
- } modelist[] = {
- #if defined(POSIX) || defined(TERMIO)
- # ifdef IGNBRK
- { "ignbrk", IGNBRK, M_INPUT },
- # endif /* IGNBRK */
- # ifdef BRKINT
- { "brkint", BRKINT, M_INPUT },
- # endif /* BRKINT */
- # ifdef IGNPAR
- { "ignpar", IGNPAR, M_INPUT },
- # endif /* IGNPAR */
- # ifdef PARMRK
- { "parmrk", PARMRK, M_INPUT },
- # endif /* PARMRK */
- # ifdef INPCK
- { "inpck", INPCK, M_INPUT },
- # endif /* INPCK */
- # ifdef ISTRIP
- { "istrip", ISTRIP, M_INPUT },
- # endif /* ISTRIP */
- # ifdef INLCR
- { "inlcr", INLCR, M_INPUT },
- # endif /* INLCR */
- # ifdef IGNCR
- { "igncr", IGNCR, M_INPUT },
- # endif /* IGNCR */
- # ifdef ICRNL
- { "icrnl", ICRNL, M_INPUT },
- # endif /* ICRNL */
- # ifdef IUCLC
- { "iuclc", IUCLC, M_INPUT },
- # endif /* IUCLC */
- # ifdef IXON
- { "ixon", IXON, M_INPUT },
- # endif /* IXON */
- # ifdef IXANY
- { "ixany", IXANY, M_INPUT },
- # endif /* IXANY */
- # ifdef IXOFF
- { "ixoff", IXOFF, M_INPUT },
- # endif /* IXOFF */
- # ifdef IMAXBEL
- { "imaxbel",IMAXBEL,M_INPUT },
- # endif /* IMAXBEL */
- # ifdef IDELETE
- { "idelete",IDELETE,M_INPUT },
- # endif /* IDELETE */
- # ifdef OPOST
- { "opost", OPOST, M_OUTPUT },
- # endif /* OPOST */
- # ifdef OLCUC
- { "olcuc", OLCUC, M_OUTPUT },
- # endif /* OLCUC */
- # ifdef ONLCR
- { "onlcr", ONLCR, M_OUTPUT },
- # endif /* ONLCR */
- # ifdef OCRNL
- { "ocrnl", OCRNL, M_OUTPUT },
- # endif /* OCRNL */
- # ifdef ONOCR
- { "onocr", ONOCR, M_OUTPUT },
- # endif /* ONOCR */
- # ifdef ONOEOT
- { "onoeot", ONOEOT, M_OUTPUT },
- # endif /* ONOEOT */
- # ifdef ONLRET
- { "onlret", ONLRET, M_OUTPUT },
- # endif /* ONLRET */
- # ifdef OFILL
- { "ofill", OFILL, M_OUTPUT },
- # endif /* OFILL */
- # ifdef OFDEL
- { "ofdel", OFDEL, M_OUTPUT },
- # endif /* OFDEL */
- # ifdef NLDLY
- { "nldly", NLDLY, M_OUTPUT },
- # endif /* NLDLY */
- # ifdef CRDLY
- { "crdly", CRDLY, M_OUTPUT },
- # endif /* CRDLY */
- # ifdef TABDLY
- { "tabdly", TABDLY, M_OUTPUT },
- # endif /* TABDLY */
- # ifdef XTABS
- { "xtabs", XTABS, M_OUTPUT },
- # endif /* XTABS */
- # ifdef BSDLY
- { "bsdly", BSDLY, M_OUTPUT },
- # endif /* BSDLY */
- # ifdef VTDLY
- { "vtdly", VTDLY, M_OUTPUT },
- # endif /* VTDLY */
- # ifdef FFDLY
- { "ffdly", FFDLY, M_OUTPUT },
- # endif /* FFDLY */
- # ifdef PAGEOUT
- { "pageout",PAGEOUT,M_OUTPUT },
- # endif /* PAGEOUT */
- # ifdef WRAP
- { "wrap", WRAP, M_OUTPUT },
- # endif /* WRAP */
- # ifdef CIGNORE
- { "cignore",CIGNORE,M_CONTROL },
- # endif /* CBAUD */
- # ifdef CBAUD
- { "cbaud", CBAUD, M_CONTROL },
- # endif /* CBAUD */
- # ifdef CSTOPB
- { "cstopb", CSTOPB, M_CONTROL },
- # endif /* CSTOPB */
- # ifdef CREAD
- { "cread", CREAD, M_CONTROL },
- # endif /* CREAD */
- # ifdef PARENB
- { "parenb", PARENB, M_CONTROL },
- # endif /* PARENB */
- # ifdef PARODD
- { "parodd", PARODD, M_CONTROL },
- # endif /* PARODD */
- # ifdef HUPCL
- { "hupcl", HUPCL, M_CONTROL },
- # endif /* HUPCL */
- # ifdef CLOCAL
- { "clocal", CLOCAL, M_CONTROL },
- # endif /* CLOCAL */
- # ifdef LOBLK
- { "loblk", LOBLK, M_CONTROL },
- # endif /* LOBLK */
- # ifdef CIBAUD
- { "cibaud", CIBAUD, M_CONTROL },
- # endif /* CIBAUD */
- # ifdef CRTSCTS
- # ifdef CCTS_OFLOW
- { "ccts_oflow",CCTS_OFLOW,M_CONTROL },
- # else
- { "crtscts",CRTSCTS,M_CONTROL },
- # endif /* CCTS_OFLOW */
- # endif /* CRTSCTS */
- # ifdef CRTS_IFLOW
- { "crts_iflow",CRTS_IFLOW,M_CONTROL },
- # endif /* CRTS_IFLOW */
- # ifdef MDMBUF
- { "mdmbuf", MDMBUF, M_CONTROL },
- # endif /* MDMBUF */
- # ifdef RCV1EN
- { "rcv1en", RCV1EN, M_CONTROL },
- # endif /* RCV1EN */
- # ifdef XMT1EN
- { "xmt1en", XMT1EN, M_CONTROL },
- # endif /* XMT1EN */
- # ifdef ISIG
- { "isig", ISIG, M_LINED },
- # endif /* ISIG */
- # ifdef ICANON
- { "icanon", ICANON, M_LINED },
- # endif /* ICANON */
- # ifdef XCASE
- { "xcase", XCASE, M_LINED },
- # endif /* XCASE */
- # ifdef ECHO
- { "echo", ECHO, M_LINED },
- # endif /* ECHO */
- # ifdef ECHOE
- { "echoe", ECHOE, M_LINED },
- # endif /* ECHOE */
- # ifdef ECHOK
- { "echok", ECHOK, M_LINED },
- # endif /* ECHOK */
- # ifdef ECHONL
- { "echonl", ECHONL, M_LINED },
- # endif /* ECHONL */
- # ifdef NOFLSH
- { "noflsh", NOFLSH, M_LINED },
- # endif /* NOFLSH */
- # ifdef TOSTOP
- { "tostop", TOSTOP, M_LINED },
- # endif /* TOSTOP */
- # ifdef ECHOCTL
- { "echoctl",ECHOCTL,M_LINED },
- # endif /* ECHOCTL */
- # ifdef ECHOPRT
- { "echoprt",ECHOPRT,M_LINED },
- # endif /* ECHOPRT */
- # ifdef ECHOKE
- { "echoke", ECHOKE, M_LINED },
- # endif /* ECHOKE */
- # ifdef DEFECHO
- { "defecho",DEFECHO,M_LINED },
- # endif /* DEFECHO */
- # ifdef FLUSHO
- { "flusho", FLUSHO, M_LINED },
- # endif /* FLUSHO */
- # ifdef PENDIN
- { "pendin", PENDIN, M_LINED },
- # endif /* PENDIN */
- # ifdef IEXTEN
- { "iexten", IEXTEN, M_LINED },
- # endif /* IEXTEN */
- # ifdef NOKERNINFO
- { "nokerninfo",NOKERNINFO,M_LINED },
- # endif /* NOKERNINFO */
- # ifdef ALTWERASE
- { "altwerase",ALTWERASE,M_LINED },
- # endif /* ALTWERASE */
- # ifdef EXTPROC
- { "extproc",EXTPROC,M_LINED },
- # endif /* EXTPROC */
- # ifdef IDEFAULT
- { "idefault",IDEFAULT,M_LINED },
- # endif /* IDEFAULT */
- #else /* GSTTY */
- # ifdef TANDEM
- { "tandem", TANDEM, M_CONTROL },
- # endif /* TANDEM */
- # ifdef CBREAK
- { "cbreak", CBREAK, M_CONTROL },
- # endif /* CBREAK */
- # ifdef LCASE
- { "lcase", LCASE, M_CONTROL },
- # endif /* LCASE */
- # ifdef ECHO
- { "echo", ECHO, M_CONTROL },
- # endif /* ECHO */
- # ifdef CRMOD
- { "crmod", CRMOD, M_CONTROL },
- # endif /* CRMOD */
- # ifdef RAW
- { "raw", RAW, M_CONTROL },
- # endif /* RAW */
- # ifdef ODDP
- { "oddp", ODDP, M_CONTROL },
- # endif /* ODDP */
- # ifdef EVENP
- { "evenp", EVENP, M_CONTROL },
- # endif /* EVENP */
- # ifdef ANYP
- { "anyp", ANYP, M_CONTROL },
- # endif /* ANYP */
- # ifdef NLDELAY
- { "nldelay",NLDELAY,M_CONTROL },
- # endif /* NLDELAY */
- # ifdef TBDELAY
- { "tbdelay",TBDELAY,M_CONTROL },
- # endif /* TBDELAY */
- # ifdef XTABS
- { "xtabs", XTABS, M_CONTROL },
- # endif /* XTABS */
- # ifdef CRDELAY
- { "crdelay",CRDELAY,M_CONTROL },
- # endif /* CRDELAY */
- # ifdef VTDELAY
- { "vtdelay",VTDELAY,M_CONTROL },
- # endif /* VTDELAY */
- # ifdef BSDELAY
- { "bsdelay",BSDELAY,M_CONTROL },
- # endif /* BSDELAY */
- # ifdef CRTBS
- { "crtbs", CRTBS, M_CONTROL },
- # endif /* CRTBS */
- # ifdef PRTERA
- { "prtera", PRTERA, M_CONTROL },
- # endif /* PRTERA */
- # ifdef CRTERA
- { "crtera", CRTERA, M_CONTROL },
- # endif /* CRTERA */
- # ifdef TILDE
- { "tilde", TILDE, M_CONTROL },
- # endif /* TILDE */
- # ifdef MDMBUF
- { "mdmbuf", MDMBUF, M_CONTROL },
- # endif /* MDMBUF */
- # ifdef LITOUT
- { "litout", LITOUT, M_CONTROL },
- # endif /* LITOUT */
- # ifdef TOSTOP
- { "tostop", TOSTOP, M_CONTROL },
- # endif /* TOSTOP */
- # ifdef FLUSHO
- { "flusho", FLUSHO, M_CONTROL },
- # endif /* FLUSHO */
- # ifdef NOHANG
- { "nohang", NOHANG, M_CONTROL },
- # endif /* NOHANG */
- # ifdef L001000
- { "l001000",L001000,M_CONTROL },
- # endif /* L001000 */
- # ifdef CRTKIL
- { "crtkil", CRTKIL, M_CONTROL },
- # endif /* CRTKIL */
- # ifdef PASS8
- { "pass8", PASS8, M_CONTROL },
- # endif /* PASS8 */
- # ifdef CTLECH
- { "ctlech", CTLECH, M_CONTROL },
- # endif /* CTLECH */
- # ifdef PENDIN
- { "pendin", PENDIN, M_CONTROL },
- # endif /* PENDIN */
- # ifdef DECCTQ
- { "decctq", DECCTQ, M_CONTROL },
- # endif /* DECCTQ */
- # ifdef NOFLSH
- { "noflsh", NOFLSH, M_CONTROL },
- # endif /* NOFLSH */
- # ifdef LCRTBS
- { "lcrtbs", LCRTBS, M_LOCAL },
- # endif /* LCRTBS */
- # ifdef LPRTERA
- { "lprtera",LPRTERA,M_LOCAL },
- # endif /* LPRTERA */
- # ifdef LCRTERA
- { "lcrtera",LCRTERA,M_LOCAL },
- # endif /* LCRTERA */
- # ifdef LTILDE
- { "ltilde", LTILDE, M_LOCAL },
- # endif /* LTILDE */
- # ifdef LMDMBUF
- { "lmdmbuf",LMDMBUF,M_LOCAL },
- # endif /* LMDMBUF */
- # ifdef LLITOUT
- { "llitout",LLITOUT,M_LOCAL },
- # endif /* LLITOUT */
- # ifdef LTOSTOP
- { "ltostop",LTOSTOP,M_LOCAL },
- # endif /* LTOSTOP */
- # ifdef LFLUSHO
- { "lflusho",LFLUSHO,M_LOCAL },
- # endif /* LFLUSHO */
- # ifdef LNOHANG
- { "lnohang",LNOHANG,M_LOCAL },
- # endif /* LNOHANG */
- # ifdef LCRTKIL
- { "lcrtkil",LCRTKIL,M_LOCAL },
- # endif /* LCRTKIL */
- # ifdef LPASS8
- { "lpass8", LPASS8, M_LOCAL },
- # endif /* LPASS8 */
- # ifdef LCTLECH
- { "lctlech",LCTLECH,M_LOCAL },
- # endif /* LCTLECH */
- # ifdef LPENDIN
- { "lpendin",LPENDIN,M_LOCAL },
- # endif /* LPENDIN */
- # ifdef LDECCTQ
- { "ldecctq",LDECCTQ,M_LOCAL },
- # endif /* LDECCTQ */
- # ifdef LNOFLSH
- { "lnoflsh",LNOFLSH,M_LOCAL },
- # endif /* LNOFLSH */
- #endif /* POSIX || TERMIO */
- # if defined(VINTR) || defined(TIOCGETC)
- { "intr", C_SH(C_INTR), M_CHAR },
- # endif /* VINTR */
- # if defined(VQUIT) || defined(TIOCGETC)
- { "quit", C_SH(C_QUIT), M_CHAR },
- # endif /* VQUIT */
- # if defined(VERASE) || defined(TIOCGETP)
- { "erase", C_SH(C_ERASE), M_CHAR },
- # endif /* VERASE */
- # if defined(VKILL) || defined(TIOCGETP)
- { "kill", C_SH(C_KILL), M_CHAR },
- # endif /* VKILL */
- # if defined(VEOF) || defined(TIOCGETC)
- { "eof", C_SH(C_EOF), M_CHAR },
- # endif /* VEOF */
- # if defined(VEOL)
- { "eol", C_SH(C_EOL), M_CHAR },
- # endif /* VEOL */
- # if defined(VEOL2)
- { "eol2", C_SH(C_EOL2), M_CHAR },
- # endif /* VEOL2 */
- # if defined(VSWTCH)
- { "swtch", C_SH(C_SWTCH), M_CHAR },
- # endif /* VSWTCH */
- # if defined(VDSWTCH)
- { "dswtch", C_SH(C_DSWTCH), M_CHAR },
- # endif /* VDSWTCH */
- # if defined(VERASE2)
- { "erase2", C_SH(C_ERASE2), M_CHAR },
- # endif /* VERASE2 */
- # if defined(VSTART) || defined(TIOCGETC)
- { "start", C_SH(C_START), M_CHAR },
- # endif /* VSTART */
- # if defined(VSTOP) || defined(TIOCGETC)
- { "stop", C_SH(C_STOP), M_CHAR },
- # endif /* VSTOP */
- # if defined(VWERASE) || defined(TIOCGLTC)
- { "werase", C_SH(C_WERASE), M_CHAR },
- # endif /* VWERASE */
- # if defined(VSUSP) || defined(TIOCGLTC)
- { "susp", C_SH(C_SUSP), M_CHAR },
- # endif /* VSUSP */
- # if defined(VDSUSP) || defined(TIOCGLTC)
- { "dsusp", C_SH(C_DSUSP), M_CHAR },
- # endif /* VDSUSP */
- # if defined(VREPRINT) || defined(TIOCGLTC)
- { "reprint", C_SH(C_REPRINT),M_CHAR },
- # endif /* WREPRINT */
- # if defined(VDISCARD) || defined(TIOCGLTC)
- { "discard", C_SH(C_DISCARD),M_CHAR },
- # endif /* VDISCARD */
- # if defined(VLNEXT) || defined(TIOCGLTC)
- { "lnext", C_SH(C_LNEXT), M_CHAR },
- # endif /* VLNEXT */
- # if defined(VSTATUS) || defined(TIOCGPAGE)
- { "status", C_SH(C_STATUS), M_CHAR },
- # endif /* VSTATUS */
- # if defined(VPAGE) || defined(TIOCGPAGE)
- { "page", C_SH(C_PAGE), M_CHAR },
- # endif /* VPAGE */
- # if defined(VPGOFF) || defined(TIOCGPAGE)
- { "pgoff", C_SH(C_PGOFF), M_CHAR },
- # endif /* VPGOFF */
- # if defined(VKILL2)
- { "kill2", C_SH(C_KILL2), M_CHAR },
- # endif /* VKILL2 */
- # if defined(VBRK) || defined(TIOCGETC)
- { "brk", C_SH(C_BRK), M_CHAR },
- # endif /* VBRK */
- # if defined(VMIN)
- { "min", C_SH(C_MIN), M_CHAR },
- # endif /* VMIN */
- # if defined(VTIME)
- { "time", C_SH(C_TIME), M_CHAR },
- # endif /* VTIME */
- { NULL, 0, -1 },
- };
- /*
- * If EAGAIN and/or EWOULDBLOCK are defined, we can't just return -1 in all
- * situations where ioctl() does.
- *
- * On AIX 4.1.5 (and presumably some other versions and OSes), as you
- * perform the manual test suite in the README, if you 'bg' vi immediately
- * after suspending it, all is well, but if you wait a few seconds,
- * usually ioctl() will return -1, which previously caused tty_setty() to
- * return -1, causing Rawmode() to return -1, causing Inputl() to return
- * 0, causing bgetc() to return -1, causing readc() to set doneinp to 1,
- * causing process() to break out of the main loop, causing tcsh to exit
- * prematurely.
- *
- * If ioctl()'s errno is EAGAIN/EWOULDBLOCK ("Resource temporarily
- * unavailable"), apparently the tty is being messed with by the OS and we
- * need to try again. In my testing, ioctl() was never called more than
- * twice in a row.
- *
- * -- Dan Harkless <dan@wave.eng.uci.edu>
- *
- * So, I retry all ioctl's in case others happen to fail too (christos)
- */
- #if defined(EAGAIN) && defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
- # define OKERROR(e) (((e) == EAGAIN) || ((e) == EWOULDBLOCK) || ((e) == EINTR))
- #elif defined(EAGAIN)
- # define OKERROR(e) (((e) == EAGAIN) || ((e) == EINTR))
- #elif defined(EWOULDBLOCK)
- # define OKERROR(e) (((e) == EWOULDBLOCK) || ((e) == EINTR))
- #else
- # define OKERROR(e) ((e) == EINTR)
- #endif
- #ifdef __NetBSD__
- #define KLUDGE (errno == ENOTTY && count < 10)
- #else
- #define KLUDGE 0
- #endif
- /* Retry a system call */
- #define RETRY(x) \
- do { \
- int count; \
- \
- for (count = 0;; count++) \
- if ((x) == -1) { \
- if (OKERROR(errno) || KLUDGE) \
- continue; \
- else \
- return -1; \
- } \
- else \
- break; \
- } while (0)
- /*ARGSUSED*/
- void
- dosetty(Char **v, struct command *t)
- {
- const struct tcshmodes *m;
- char x, *d, *cmdname;
- int aflag = 0;
- Char *s;
- int z = EX_IO;
- USE(t);
- cmdname = strsave(short2str(*v++));
- cleanup_push(cmdname, xfree);
- setname(cmdname);
- while (v && *v && v[0][0] == '-' && v[0][2] == '\0')
- switch (v[0][1]) {
- case 'a':
- aflag++;
- v++;
- break;
- case 'd':
- v++;
- z = ED_IO;
- break;
- case 'x':
- v++;
- z = EX_IO;
- break;
- case 'q':
- v++;
- z = QU_IO;
- break;
- default:
- stderror(ERR_NAME | ERR_SYSTEM, short2str(v[0]),
- CGETS(8, 1, "Unknown switch"));
- break;
- }
- didsetty = 1;
- if (!v || !*v) {
- int i = -1;
- int len = 0, st = 0, cu;
- for (m = modelist; m->m_name; m++) {
- if (m->m_type != i) {
- xprintf("%s%s", i != -1 ? "\n" : "",
- ttylist[z][m->m_type].t_name);
- i = m->m_type;
- st = len = strlen(ttylist[z][m->m_type].t_name);
- }
- assert(i != -1);
- x = (ttylist[z][i].t_setmask & m->m_value) ? '+' : '\0';
- x = (ttylist[z][i].t_clrmask & m->m_value) ? '-' : x;
- if (x != '\0' || aflag) {
- cu = strlen(m->m_name) + (x != '\0') + 1;
- if (len + cu >= TermH) {
- xprintf("\n%*s", st, "");
- len = st + cu;
- }
- else
- len += cu;
- if (x != '\0')
- xprintf("%c%s ", x, m->m_name);
- else
- xprintf("%s ", m->m_name);
- }
- }
- xputchar('\n');
- cleanup_until(cmdname);
- return;
- }
- while (v && (s = *v++)) {
- switch (*s) {
- case '+':
- case '-':
- x = *s++;
- break;
- default:
- x = '\0';
- break;
- }
- d = short2str(s);
- for (m = modelist; m->m_name; m++)
- if (strcmp(m->m_name, d) == 0)
- break;
- if (!m->m_name)
- stderror(ERR_NAME | ERR_SYSTEM, d, CGETS(8, 2, "Invalid argument"));
- switch (x) {
- case '+':
- ttylist[z][m->m_type].t_setmask |= m->m_value;
- ttylist[z][m->m_type].t_clrmask &= ~m->m_value;
- break;
- case '-':
- ttylist[z][m->m_type].t_setmask &= ~m->m_value;
- ttylist[z][m->m_type].t_clrmask |= m->m_value;
- break;
- default:
- ttylist[z][m->m_type].t_setmask &= ~m->m_value;
- ttylist[z][m->m_type].t_clrmask &= ~m->m_value;
- break;
- }
- }
- cleanup_until(cmdname);
- } /* end dosetty */
- int
- tty_getty(int fd, ttydata_t *td)
- {
- #ifdef POSIX
- RETRY(tcgetattr(fd, &td->d_t));
- #else /* TERMIO || GSTTY */
- # ifdef TERMIO
- RETRY(ioctl(fd, TCGETA, (ioctl_t) &td->d_t));
- # else /* GSTTY */
- # ifdef TIOCGETP
- RETRY(ioctl(fd, TIOCGETP, (ioctl_t) &td->d_t));
- # endif /* TIOCGETP */
- # ifdef TIOCGETC
- RETRY(ioctl(fd, TIOCGETC, (ioctl_t) &td->d_tc));
- # endif /* TIOCGETC */
- # ifdef TIOCGPAGE
- RETRY(ioctl(fd, TIOCGPAGE, (ioctl_t) &td->d_pc));
- # endif /* TIOCGPAGE */
- # ifdef TIOCLGET
- RETRY(ioctl(fd, TIOCLGET, (ioctl_t) &td->d_lb));
- # endif /* TIOCLGET */
- # endif /* TERMIO */
- #endif /* POSIX */
- #ifdef TIOCGLTC
- RETRY(ioctl(fd, TIOCGLTC, (ioctl_t) &td->d_ltc));
- #endif /* TIOCGLTC */
- return 0;
- }
- int
- tty_setty(int fd, ttydata_t *td)
- {
- #ifdef POSIX
- RETRY(xtcsetattr(fd, TCSADRAIN, &td->d_t));
- #else
- # ifdef TERMIO
- RETRY(ioctl(fd, TCSETAW, (ioctl_t) &td->d_t));
- # else
- # ifdef TIOCSETN
- RETRY(ioctl(fd, TIOCSETN, (ioctl_t) &td->d_t));
- # endif /* TIOCSETN */
- # ifdef TIOCGETC
- RETRY(ioctl(fd, TIOCSETC, (ioctl_t) &td->d_tc));
- # endif /* TIOCGETC */
- # ifdef TIOCGPAGE
- RETRY(ioctl(fd, TIOCSPAGE, (ioctl_t) &td->d_pc));
- # endif /* TIOCGPAGE */
- # ifdef TIOCLGET
- RETRY(ioctl(fd, TIOCLSET, (ioctl_t) &td->d_lb));
- # endif /* TIOCLGET */
- # endif /* TERMIO */
- #endif /* POSIX */
- #ifdef TIOCGLTC
- RETRY(ioctl(fd, TIOCSLTC, (ioctl_t) &td->d_ltc));
- #endif /* TIOCGLTC */
- return 0;
- }
- void
- tty_getchar(ttydata_t *td, unsigned char *s)
- {
- #ifdef TIOCGLTC
- {
- struct ltchars *n = &td->d_ltc;
- s[C_SUSP] = n->t_suspc;
- s[C_DSUSP] = n->t_dsuspc;
- s[C_REPRINT] = n->t_rprntc;
- s[C_DISCARD] = n->t_flushc;
- s[C_WERASE] = n->t_werasc;
- s[C_LNEXT] = n->t_lnextc;
- }
- #endif /* TIOCGLTC */
- #if defined(POSIX) || defined(TERMIO)
- {
- # ifdef POSIX
- struct termios *n = &td->d_t;
- # else
- struct termio *n = &td->d_t;
- # endif /* POSIX */
- # ifdef VINTR
- s[C_INTR] = n->c_cc[VINTR];
- # endif /* VINTR */
- # ifdef VQUIT
- s[C_QUIT] = n->c_cc[VQUIT];
- # endif /* VQUIT */
- # ifdef VERASE
- s[C_ERASE] = n->c_cc[VERASE];
- # endif /* VERASE */
- # ifdef VKILL
- s[C_KILL] = n->c_cc[VKILL];
- # endif /* VKILL */
- # ifdef VEOF
- s[C_EOF] = n->c_cc[VEOF];
- # endif /* VEOF */
- # ifdef VEOL
- s[C_EOL] = n->c_cc[VEOL];
- # endif /* VEOL */
- # ifdef VEOL2
- s[C_EOL2] = n->c_cc[VEOL2];
- # endif /* VEOL2 */
- # ifdef VSWTCH
- s[C_SWTCH] = n->c_cc[VSWTCH];
- # endif /* VSWTCH */
- # ifdef VDSWTCH
- s[C_DSWTCH] = n->c_cc[VDSWTCH];
- # endif /* VDSWTCH */
- # ifdef VERASE2
- s[C_ERASE2] = n->c_cc[VERASE2];
- # endif /* VERASE2 */
- # ifdef VSTART
- s[C_START] = n->c_cc[VSTART];
- # endif /* VSTART */
- # ifdef VSTOP
- s[C_STOP] = n->c_cc[VSTOP];
- # endif /* VSTOP */
- # ifdef VWERASE
- s[C_WERASE] = n->c_cc[VWERASE];
- # endif /* VWERASE */
- # ifdef VSUSP
- s[C_SUSP] = n->c_cc[VSUSP];
- # endif /* VSUSP */
- # ifdef VDSUSP
- s[C_DSUSP] = n->c_cc[VDSUSP];
- # endif /* VDSUSP */
- # ifdef VREPRINT
- s[C_REPRINT] = n->c_cc[VREPRINT];
- # endif /* WREPRINT */
- # ifdef VDISCARD
- s[C_DISCARD] = n->c_cc[VDISCARD];
- # endif /* VDISCARD */
- # ifdef VLNEXT
- s[C_LNEXT] = n->c_cc[VLNEXT];
- # endif /* VLNEXT */
- # ifdef VSTATUS
- s[C_STATUS] = n->c_cc[VSTATUS];
- # endif /* VSTATUS */
- # ifdef VPAGE
- s[C_PAGE] = n->c_cc[VPAGE];
- # endif /* VPAGE */
- # ifdef VPGOFF
- s[C_PGOFF] = n->c_cc[VPGOFF];
- # endif /* VPGOFF */
- # ifdef VKILL2
- s[C_KILL2] = n->c_cc[VKILL2];
- # endif /* KILL2 */
- # ifdef VMIN
- s[C_MIN] = n->c_cc[VMIN];
- # endif /* VMIN */
- # ifdef VTIME
- s[C_TIME] = n->c_cc[VTIME];
- # endif /* VTIME */
- }
- #else /* SGTTY */
- # ifdef TIOCGPAGE
- {
- struct ttypagestat *n = &td->d_pc;
- s[C_STATUS] = n->tps_statc;
- s[C_PAGE] = n->tps_pagec;
- s[C_PGOFF] = n->tps_pgoffc;
- }
- # endif /* TIOCGPAGE */
- # ifdef TIOCGETC
- {
- struct tchars *n = &td->d_tc;
- s[C_INTR] = n->t_intrc;
- s[C_QUIT] = n->t_quitc;
- s[C_START] = n->t_startc;
- s[C_STOP] = n->t_stopc;
- s[C_EOF] = n->t_eofc;
- s[C_BRK] = n->t_brkc;
- }
- # endif /* TIOCGETC */
- # ifdef TIOCGETP
- {
- struct sgttyb *n = &td->d_t;
- s[C_ERASE] = n->sg_erase;
- s[C_KILL] = n->sg_kill;
- }
- # endif /* TIOCGETP */
- #endif /* !POSIX || TERMIO */
- } /* tty_getchar */
- void
- tty_setchar(ttydata_t *td, unsigned char *s)
- {
- #ifdef TIOCGLTC
- {
- struct ltchars *n = &td->d_ltc;
- n->t_suspc = s[C_SUSP];
- n->t_dsuspc = s[C_DSUSP];
- n->t_rprntc = s[C_REPRINT];
- n->t_flushc = s[C_DISCARD];
- n->t_werasc = s[C_WERASE];
- n->t_lnextc = s[C_LNEXT];
- }
- #endif /* TIOCGLTC */
- #if defined(POSIX) || defined(TERMIO)
- {
- # ifdef POSIX
- struct termios *n = &td->d_t;
- # else
- struct termio *n = &td->d_t;
- # endif /* POSIX */
- # ifdef VINTR
- n->c_cc[VINTR] = s[C_INTR];
- # endif /* VINTR */
- # ifdef VQUIT
- n->c_cc[VQUIT] = s[C_QUIT];
- # endif /* VQUIT */
- # ifdef VERASE
- n->c_cc[VERASE] = s[C_ERASE];
- # endif /* VERASE */
- # ifdef VKILL
- n->c_cc[VKILL] = s[C_KILL];
- # endif /* VKILL */
- # ifdef VEOF
- n->c_cc[VEOF] = s[C_EOF];
- # endif /* VEOF */
- # ifdef VEOL
- n->c_cc[VEOL] = s[C_EOL];
- # endif /* VEOL */
- # ifdef VEOL2
- n->c_cc[VEOL2] = s[C_EOL2];
- # endif /* VEOL2 */
- # ifdef VSWTCH
- n->c_cc[VSWTCH] = s[C_SWTCH];
- # endif /* VSWTCH */
- # ifdef VDSWTCH
- n->c_cc[VDSWTCH] = s[C_DSWTCH];
- # endif /* VDSWTCH */
- # ifdef VERASE2
- n->c_cc[VERASE2] = s[C_ERASE2];
- # endif /* VERASE2 */
- # ifdef VSTART
- n->c_cc[VSTART] = s[C_START];
- # endif /* VSTART */
- # ifdef VSTOP
- n->c_cc[VSTOP] = s[C_STOP];
- # endif /* VSTOP */
- # ifdef VWERASE
- n->c_cc[VWERASE] = s[C_WERASE];
- # endif /* VWERASE */
- # ifdef VSUSP
- n->c_cc[VSUSP] = s[C_SUSP];
- # endif /* VSUSP */
- # ifdef VDSUSP
- n->c_cc[VDSUSP] = s[C_DSUSP];
- # endif /* VDSUSP */
- # ifdef VREPRINT
- n->c_cc[VREPRINT] = s[C_REPRINT];
- # endif /* WREPRINT */
- # ifdef VDISCARD
- n->c_cc[VDISCARD] = s[C_DISCARD];
- # endif /* VDISCARD */
- # ifdef VLNEXT
- n->c_cc[VLNEXT] = s[C_LNEXT];
- # endif /* VLNEXT */
- # ifdef VSTATUS
- n->c_cc[VSTATUS] = s[C_STATUS];
- # endif /* VSTATUS */
- # ifdef VPAGE
- n->c_cc[VPAGE] = s[C_PAGE];
- # endif /* VPAGE */
- # ifdef VPGOFF
- n->c_cc[VPGOFF] = s[C_PGOFF];
- # endif /* VPGOFF */
- # ifdef VKILL2
- n->c_cc[VKILL2] = s[C_KILL2];
- # endif /* VKILL2 */
- # ifdef VMIN
- n->c_cc[VMIN] = s[C_MIN];
- # endif /* VMIN */
- # ifdef VTIME
- n->c_cc[VTIME] = s[C_TIME];
- # endif /* VTIME */
- }
- #else /* GSTTY */
- # ifdef TIOCGPAGE
- {
- struct ttypagestat *n = &td->d_pc;
- n->tps_length = 0;
- n->tps_lpos = 0;
- n->tps_statc = s[C_STATUS];
- n->tps_pagec = s[C_PAGE];
- n->tps_pgoffc = s[C_PGOFF];
- n->tps_flag = 0;
- }
- # endif /* TIOCGPAGE */
- # ifdef TIOCGETC
- {
- struct tchars *n = &td->d_tc;
- n->t_intrc = s[C_INTR];
- n->t_quitc = s[C_QUIT];
- n->t_startc = s[C_START];
- n->t_stopc = s[C_STOP];
- n->t_eofc = s[C_EOF];
- n->t_brkc = s[C_BRK];
- }
- # endif /* TIOCGETC */
- # ifdef TIOCGETP
- {
- struct sgttyb *n = &td->d_t;
- n->sg_erase = s[C_ERASE];
- n->sg_kill = s[C_KILL];
- }
- # endif /* TIOCGETP */
- #endif /* !POSIX || TERMIO */
- } /* tty_setchar */
- speed_t
- tty_getspeed(ttydata_t *td)
- {
- speed_t spd;
- #ifdef POSIX
- if ((spd = cfgetispeed(&td->d_t)) == 0)
- spd = cfgetospeed(&td->d_t);
- #else /* ! POSIX */
- # ifdef TERMIO
- # ifdef CBAUD
- spd = td->d_t.c_cflag & CBAUD;
- # else
- spd = 0;
- # endif
- # else /* SGTTY */
- spd = td->d_t.sg_ispeed;
- # endif /* TERMIO */
- #endif /* POSIX */
- return spd;
- } /* end tty_getspeed */
- int
- tty_gettabs(ttydata_t *td)
- {
- #if defined(POSIX) || defined(TERMIO)
- return ((td->d_t.c_oflag & TAB3) == TAB3) ? 0 : 1;
- #else /* SGTTY */
- return (td->d_t.sg_flags & XTABS) == XTABS ? 0 : 1;
- #endif /* POSIX || TERMIO */
- } /* end tty_gettabs */
- int
- tty_geteightbit(ttydata_t *td)
- {
- #if defined(POSIX) || defined(TERMIO)
- return (td->d_t.c_cflag & CSIZE) == CS8;
- #else /* SGTTY */
- return td->d_lb & (LPASS8 | LLITOUT);
- #endif /* POSIX || TERMIO */
- } /* end tty_geteightbit */
- int
- tty_cooked_mode(ttydata_t *td)
- {
- #if defined(POSIX) || defined(TERMIO)
- return (td->d_t.c_lflag & ICANON);
- #else /* SGTTY */
- return !(td->d_t.sg_flags & (RAW | CBREAK));
- #endif /* POSIX || TERMIO */
- } /* end tty_cooked_mode */
- #ifdef _IBMR2
- void
- tty_setdisc(int fd, int dis)
- {
- static int edit_discipline = 0;
- static union txname tx_disc;
- extern char strPOSIX[];
- switch (dis) {
- case EX_IO:
- if (edit_discipline) {
- if (ioctl(fd, TXSETLD, (ioctl_t) & tx_disc) == -1)
- return;
- edit_discipline = 0;
- }
- return;
- case ED_IO:
- tx_disc.tx_which = 0;
- if (ioctl(fd, TXGETLD, (ioctl_t) & tx_disc) == -1)
- return;
- if (strcmp(tx_disc.tx_name, strPOSIX) != 0) {
- edit_discipline = 1;
- if (ioctl(fd, TXSETLD, (ioctl_t) strPOSIX) == -1)
- return;
- }
- return;
- default:
- return;
- }
- } /* end tty_setdisc */
- #endif /* _IBMR2 */
- #ifdef DEBUG_TTY
- static void
- tty_printchar(unsigned char *s)
- {
- struct tcshmodes *m;
- int i;
- for (i = 0; i < C_NCC; i++) {
- for (m = modelist; m->m_name; m++)
- if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
- break;
- if (m->m_name)
- xprintf("%s ^%c ", m->m_name, s[i] + 'A' - 1);
- if (i % 5 == 0)
- xputchar('\n');
- }
- xputchar('\n');
- }
- #endif /* DEBUG_TTY */
- #else /* WINNT_NATIVE */
- int
- tty_cooked_mode(void *td)
- {
- return do_nt_check_cooked_mode();
- }
- #endif /* !WINNT_NATIVE */