PageRenderTime 87ms CodeModel.GetById 35ms app.highlight 44ms RepoModel.GetById 2ms app.codeStats 0ms

/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
   1/* $Header: /p/tcsh/cvsroot/tcsh/ed.term.c,v 1.38 2011/02/25 23:58:34 christos Exp $ */
   2/*
   3 * ed.term.c: Low level terminal interface
   4 */
   5/*-
   6 * Copyright (c) 1980, 1991 The Regents of the University of California.
   7 * All rights reserved.
   8 *
   9 * Redistribution and use in source and binary forms, with or without
  10 * modification, are permitted provided that the following conditions
  11 * are met:
  12 * 1. Redistributions of source code must retain the above copyright
  13 *    notice, this list of conditions and the following disclaimer.
  14 * 2. Redistributions in binary form must reproduce the above copyright
  15 *    notice, this list of conditions and the following disclaimer in the
  16 *    documentation and/or other materials provided with the distribution.
  17 * 3. Neither the name of the University nor the names of its contributors
  18 *    may be used to endorse or promote products derived from this software
  19 *    without specific prior written permission.
  20 *
  21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31 * SUCH DAMAGE.
  32 */
  33#include "sh.h"
  34#ifndef WINNT_NATIVE
  35
  36RCSID("$tcsh: ed.term.c,v 1.38 2011/02/25 23:58:34 christos Exp $")
  37#include <assert.h>
  38#include "ed.h"
  39
  40int didsetty = 0;
  41ttyperm_t ttylist = {   
  42    {
  43#if defined(POSIX) || defined(TERMIO)
  44	{ "iflag:", ICRNL, (INLCR|IGNCR) },
  45	{ "oflag:", (OPOST|ONLCR), ONLRET },
  46	{ "cflag:", 0, 0 },
  47	{ "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
  48		    (NOFLSH|ECHONL|EXTPROC|FLUSHO|IDEFAULT) },
  49#else /* GSTTY */
  50	{ "nrmal:", (ECHO|CRMOD|ANYP), (CBREAK|RAW|LCASE|VTDELAY|ALLDELAY) },
  51	{ "local:", (LCRTBS|LCRTERA|LCRTKIL), (LPRTERA|LFLUSHO) },
  52#endif /* POSIX || TERMIO */
  53	{ "chars:", 	0, 0 },
  54    },
  55    {
  56#if defined(POSIX) || defined(TERMIO)
  57	{ "iflag:", (INLCR|ICRNL), IGNCR },
  58	{ "oflag:", (OPOST|ONLCR), ONLRET },
  59	{ "cflag:", 0, 0 },
  60	{ "lflag:", ISIG,
  61		    (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO|
  62		     IDEFAULT) },
  63#else /* GSTTY */
  64	{ "nrmal:", (CBREAK|CRMOD|ANYP), (RAW|ECHO|LCASE|VTDELAY|ALLDELAY) },
  65	{ "local:", (LCRTBS|LCRTERA|LCRTKIL), (LPRTERA|LFLUSHO) },
  66#endif /* POSIX || TERMIO */
  67	{ "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
  68		     C_SH(C_WERASE)|C_SH(C_REPRINT)|C_SH(C_SUSP)|C_SH(C_DSUSP)|
  69		     C_SH(C_EOF)|C_SH(C_EOL)|C_SH(C_DISCARD)|C_SH(C_PGOFF)|
  70		     C_SH(C_KILL2)|C_SH(C_PAGE)|C_SH(C_STATUS)|C_SH(C_LNEXT)), 
  71		     0 }
  72    },
  73    {
  74#if defined(POSIX) || defined(TERMIO)
  75	{ "iflag:", 0, IXON | IXOFF },
  76	{ "oflag:", 0, 0 },
  77	{ "cflag:", 0, 0 },
  78	{ "lflag:", 0, ISIG | IEXTEN },
  79#else /* GSTTY */
  80	{ "nrmal:", RAW, CBREAK },
  81	{ "local:", 0, 0 },
  82#endif /* POSIX || TERMIO */
  83	{ "chars:", 0, 0 },
  84    }
  85};
  86
  87static const struct tcshmodes {
  88    const char *m_name;
  89#ifdef SOLARIS2
  90    unsigned long m_value;
  91#else /* !SOLARIS2 */
  92    int   m_value;
  93#endif /* SOLARIS2 */
  94    int   m_type;
  95} modelist[] = {
  96#if defined(POSIX) || defined(TERMIO)
  97
  98# ifdef	IGNBRK
  99    { "ignbrk",	IGNBRK,	M_INPUT },
 100# endif /* IGNBRK */
 101# ifdef	BRKINT
 102    { "brkint",	BRKINT,	M_INPUT },
 103# endif /* BRKINT */
 104# ifdef	IGNPAR
 105    { "ignpar",	IGNPAR,	M_INPUT },
 106# endif /* IGNPAR */
 107# ifdef	PARMRK
 108    { "parmrk",	PARMRK,	M_INPUT },
 109# endif /* PARMRK */
 110# ifdef	INPCK
 111    { "inpck",	INPCK,	M_INPUT },
 112# endif /* INPCK */
 113# ifdef	ISTRIP
 114    { "istrip",	ISTRIP,	M_INPUT },
 115# endif /* ISTRIP */
 116# ifdef	INLCR
 117    { "inlcr",	INLCR,	M_INPUT },
 118# endif /* INLCR */
 119# ifdef	IGNCR
 120    { "igncr",	IGNCR,	M_INPUT },
 121# endif /* IGNCR */
 122# ifdef	ICRNL
 123    { "icrnl",	ICRNL,	M_INPUT },
 124# endif /* ICRNL */
 125# ifdef	IUCLC
 126    { "iuclc",	IUCLC,	M_INPUT },
 127# endif /* IUCLC */
 128# ifdef	IXON
 129    { "ixon",	IXON,	M_INPUT },
 130# endif /* IXON */
 131# ifdef	IXANY
 132    { "ixany",	IXANY,	M_INPUT },
 133# endif /* IXANY */
 134# ifdef	IXOFF
 135    { "ixoff",	IXOFF,	M_INPUT },
 136# endif /* IXOFF */
 137# ifdef  IMAXBEL
 138    { "imaxbel",IMAXBEL,M_INPUT },
 139# endif /* IMAXBEL */
 140# ifdef  IDELETE
 141    { "idelete",IDELETE,M_INPUT },
 142# endif /* IDELETE */
 143
 144# ifdef	OPOST
 145    { "opost",	OPOST,	M_OUTPUT },
 146# endif /* OPOST */
 147# ifdef	OLCUC
 148    { "olcuc",	OLCUC,	M_OUTPUT },
 149# endif /* OLCUC */
 150# ifdef	ONLCR
 151    { "onlcr",	ONLCR,	M_OUTPUT },
 152# endif /* ONLCR */
 153# ifdef	OCRNL
 154    { "ocrnl",	OCRNL,	M_OUTPUT },
 155# endif /* OCRNL */
 156# ifdef	ONOCR
 157    { "onocr",	ONOCR,	M_OUTPUT },
 158# endif /* ONOCR */
 159# ifdef ONOEOT
 160    { "onoeot",	ONOEOT,	M_OUTPUT },
 161# endif /* ONOEOT */
 162# ifdef	ONLRET
 163    { "onlret",	ONLRET,	M_OUTPUT },
 164# endif /* ONLRET */
 165# ifdef	OFILL
 166    { "ofill",	OFILL,	M_OUTPUT },
 167# endif /* OFILL */
 168# ifdef	OFDEL
 169    { "ofdel",	OFDEL,	M_OUTPUT },
 170# endif /* OFDEL */
 171# ifdef	NLDLY
 172    { "nldly",	NLDLY,	M_OUTPUT },
 173# endif /* NLDLY */
 174# ifdef	CRDLY
 175    { "crdly",	CRDLY,	M_OUTPUT },
 176# endif /* CRDLY */
 177# ifdef	TABDLY
 178    { "tabdly",	TABDLY,	M_OUTPUT },
 179# endif /* TABDLY */
 180# ifdef	XTABS
 181    { "xtabs",	XTABS,	M_OUTPUT },
 182# endif /* XTABS */
 183# ifdef	BSDLY
 184    { "bsdly",	BSDLY,	M_OUTPUT },
 185# endif /* BSDLY */
 186# ifdef	VTDLY
 187    { "vtdly",	VTDLY,	M_OUTPUT },
 188# endif /* VTDLY */
 189# ifdef	FFDLY
 190    { "ffdly",	FFDLY,	M_OUTPUT },
 191# endif /* FFDLY */
 192# ifdef	PAGEOUT
 193    { "pageout",PAGEOUT,M_OUTPUT },
 194# endif /* PAGEOUT */
 195# ifdef	WRAP
 196    { "wrap",	WRAP,	M_OUTPUT },
 197# endif /* WRAP */
 198
 199# ifdef	CIGNORE
 200    { "cignore",CIGNORE,M_CONTROL },
 201# endif /* CBAUD */
 202# ifdef	CBAUD
 203    { "cbaud",	CBAUD,	M_CONTROL },
 204# endif /* CBAUD */
 205# ifdef	CSTOPB
 206    { "cstopb",	CSTOPB,	M_CONTROL },
 207# endif /* CSTOPB */
 208# ifdef	CREAD
 209    { "cread",	CREAD,	M_CONTROL },
 210# endif /* CREAD */
 211# ifdef	PARENB
 212    { "parenb",	PARENB,	M_CONTROL },
 213# endif /* PARENB */
 214# ifdef	PARODD
 215    { "parodd",	PARODD,	M_CONTROL },
 216# endif /* PARODD */
 217# ifdef	HUPCL
 218    { "hupcl",	HUPCL,	M_CONTROL },
 219# endif /* HUPCL */
 220# ifdef	CLOCAL
 221    { "clocal",	CLOCAL,	M_CONTROL },
 222# endif /* CLOCAL */
 223# ifdef	LOBLK
 224    { "loblk",	LOBLK,	M_CONTROL },
 225# endif /* LOBLK */
 226# ifdef	CIBAUD
 227    { "cibaud",	CIBAUD,	M_CONTROL },
 228# endif /* CIBAUD */
 229# ifdef CRTSCTS
 230#  ifdef CCTS_OFLOW
 231    { "ccts_oflow",CCTS_OFLOW,M_CONTROL },
 232#  else
 233    { "crtscts",CRTSCTS,M_CONTROL },
 234#  endif /* CCTS_OFLOW */
 235# endif /* CRTSCTS */
 236# ifdef CRTS_IFLOW
 237    { "crts_iflow",CRTS_IFLOW,M_CONTROL },
 238# endif /* CRTS_IFLOW */
 239# ifdef MDMBUF
 240    { "mdmbuf",	MDMBUF,	M_CONTROL },
 241# endif /* MDMBUF */
 242# ifdef RCV1EN
 243    { "rcv1en",	RCV1EN,	M_CONTROL },
 244# endif /* RCV1EN */
 245# ifdef XMT1EN
 246    { "xmt1en",	XMT1EN,	M_CONTROL },
 247# endif /* XMT1EN */
 248
 249# ifdef	ISIG
 250    { "isig",	ISIG,	M_LINED },
 251# endif /* ISIG */
 252# ifdef	ICANON
 253    { "icanon",	ICANON,	M_LINED },
 254# endif /* ICANON */
 255# ifdef	XCASE
 256    { "xcase",	XCASE,	M_LINED },
 257# endif /* XCASE */
 258# ifdef	ECHO
 259    { "echo",	ECHO,	M_LINED },
 260# endif /* ECHO */
 261# ifdef	ECHOE
 262    { "echoe",	ECHOE,	M_LINED },
 263# endif /* ECHOE */
 264# ifdef	ECHOK
 265    { "echok",	ECHOK,	M_LINED },
 266# endif /* ECHOK */
 267# ifdef	ECHONL
 268    { "echonl",	ECHONL,	M_LINED },
 269# endif /* ECHONL */
 270# ifdef	NOFLSH
 271    { "noflsh",	NOFLSH,	M_LINED },
 272# endif /* NOFLSH */
 273# ifdef	TOSTOP
 274    { "tostop",	TOSTOP,	M_LINED },
 275# endif /* TOSTOP */
 276# ifdef	ECHOCTL
 277    { "echoctl",ECHOCTL,M_LINED },
 278# endif /* ECHOCTL */
 279# ifdef	ECHOPRT
 280    { "echoprt",ECHOPRT,M_LINED },
 281# endif /* ECHOPRT */
 282# ifdef	ECHOKE
 283    { "echoke",	ECHOKE,	M_LINED },
 284# endif /* ECHOKE */
 285# ifdef	DEFECHO
 286    { "defecho",DEFECHO,M_LINED },
 287# endif /* DEFECHO */
 288# ifdef	FLUSHO
 289    { "flusho",	FLUSHO,	M_LINED },
 290# endif /* FLUSHO */
 291# ifdef	PENDIN
 292    { "pendin",	PENDIN,	M_LINED },
 293# endif /* PENDIN */
 294# ifdef	IEXTEN
 295    { "iexten",	IEXTEN,	M_LINED },
 296# endif /* IEXTEN */
 297# ifdef	NOKERNINFO
 298    { "nokerninfo",NOKERNINFO,M_LINED },
 299# endif /* NOKERNINFO */
 300# ifdef	ALTWERASE
 301    { "altwerase",ALTWERASE,M_LINED },
 302# endif /* ALTWERASE */
 303# ifdef	EXTPROC
 304    { "extproc",EXTPROC,M_LINED },
 305# endif /* EXTPROC */
 306# ifdef IDEFAULT
 307    { "idefault",IDEFAULT,M_LINED },
 308# endif /* IDEFAULT */
 309
 310#else /* GSTTY */
 311
 312# ifdef	TANDEM
 313    { "tandem",	TANDEM,	M_CONTROL },
 314# endif /* TANDEM */
 315# ifdef	CBREAK
 316    { "cbreak",	CBREAK,	M_CONTROL },
 317# endif /* CBREAK */
 318# ifdef	LCASE
 319    { "lcase",	LCASE,	M_CONTROL },
 320# endif /* LCASE */
 321# ifdef	ECHO
 322    { "echo",	ECHO,	M_CONTROL },
 323# endif /* ECHO */	
 324# ifdef	CRMOD
 325    { "crmod",	CRMOD,	M_CONTROL },
 326# endif /* CRMOD */
 327# ifdef	RAW
 328    { "raw",	RAW,	M_CONTROL },
 329# endif /* RAW */
 330# ifdef	ODDP
 331    { "oddp",	ODDP,	M_CONTROL },
 332# endif /* ODDP */
 333# ifdef	EVENP
 334    { "evenp",	EVENP,	M_CONTROL },
 335# endif /* EVENP */
 336# ifdef	ANYP
 337    { "anyp",	ANYP,	M_CONTROL },
 338# endif /* ANYP */
 339# ifdef	NLDELAY
 340    { "nldelay",NLDELAY,M_CONTROL },
 341# endif /* NLDELAY */
 342# ifdef	TBDELAY
 343    { "tbdelay",TBDELAY,M_CONTROL },
 344# endif /* TBDELAY */
 345# ifdef	XTABS
 346    { "xtabs",	XTABS,	M_CONTROL },
 347# endif /* XTABS */
 348# ifdef	CRDELAY
 349    { "crdelay",CRDELAY,M_CONTROL },
 350# endif /* CRDELAY */
 351# ifdef	VTDELAY
 352    { "vtdelay",VTDELAY,M_CONTROL },
 353# endif /* VTDELAY */
 354# ifdef	BSDELAY
 355    { "bsdelay",BSDELAY,M_CONTROL },
 356# endif /* BSDELAY */
 357# ifdef	CRTBS
 358    { "crtbs",	CRTBS,	M_CONTROL },
 359# endif /* CRTBS */
 360# ifdef	PRTERA
 361    { "prtera",	PRTERA,	M_CONTROL },
 362# endif /* PRTERA */
 363# ifdef	CRTERA
 364    { "crtera",	CRTERA,	M_CONTROL },
 365# endif /* CRTERA */
 366# ifdef	TILDE
 367    { "tilde",	TILDE,	M_CONTROL },
 368# endif /* TILDE */
 369# ifdef	MDMBUF
 370    { "mdmbuf",	MDMBUF,	M_CONTROL },
 371# endif /* MDMBUF */
 372# ifdef	LITOUT
 373    { "litout",	LITOUT,	M_CONTROL },
 374# endif /* LITOUT */
 375# ifdef	TOSTOP
 376    { "tostop",	TOSTOP,	M_CONTROL },
 377# endif /* TOSTOP */
 378# ifdef	FLUSHO
 379    { "flusho",	FLUSHO,	M_CONTROL },
 380# endif /* FLUSHO */
 381# ifdef	NOHANG
 382    { "nohang",	NOHANG,	M_CONTROL },
 383# endif /* NOHANG */
 384# ifdef	L001000
 385    { "l001000",L001000,M_CONTROL },
 386# endif /* L001000 */
 387# ifdef	CRTKIL
 388    { "crtkil",	CRTKIL,	M_CONTROL },
 389# endif /* CRTKIL */
 390# ifdef	PASS8
 391    { "pass8",	PASS8,	M_CONTROL },
 392# endif /* PASS8 */
 393# ifdef	CTLECH
 394    { "ctlech",	CTLECH,	M_CONTROL },
 395# endif /* CTLECH */
 396# ifdef	PENDIN
 397    { "pendin",	PENDIN,	M_CONTROL },
 398# endif /* PENDIN */
 399# ifdef	DECCTQ
 400    { "decctq",	DECCTQ,	M_CONTROL },
 401# endif /* DECCTQ */
 402# ifdef	NOFLSH
 403    { "noflsh",	NOFLSH,	M_CONTROL },
 404# endif /* NOFLSH */
 405
 406# ifdef	LCRTBS
 407    { "lcrtbs",	LCRTBS,	M_LOCAL },
 408# endif /* LCRTBS */
 409# ifdef	LPRTERA
 410    { "lprtera",LPRTERA,M_LOCAL },
 411# endif /* LPRTERA */
 412# ifdef	LCRTERA
 413    { "lcrtera",LCRTERA,M_LOCAL },
 414# endif /* LCRTERA */
 415# ifdef	LTILDE
 416    { "ltilde",	LTILDE,	M_LOCAL },
 417# endif /* LTILDE */
 418# ifdef	LMDMBUF
 419    { "lmdmbuf",LMDMBUF,M_LOCAL },
 420# endif /* LMDMBUF */
 421# ifdef	LLITOUT
 422    { "llitout",LLITOUT,M_LOCAL },
 423# endif /* LLITOUT */
 424# ifdef	LTOSTOP
 425    { "ltostop",LTOSTOP,M_LOCAL },
 426# endif /* LTOSTOP */
 427# ifdef	LFLUSHO
 428    { "lflusho",LFLUSHO,M_LOCAL },
 429# endif /* LFLUSHO */
 430# ifdef	LNOHANG
 431    { "lnohang",LNOHANG,M_LOCAL },
 432# endif /* LNOHANG */
 433# ifdef	LCRTKIL
 434    { "lcrtkil",LCRTKIL,M_LOCAL },
 435# endif /* LCRTKIL */
 436# ifdef	LPASS8
 437    { "lpass8",	LPASS8,	M_LOCAL },
 438# endif /* LPASS8 */	
 439# ifdef	LCTLECH
 440    { "lctlech",LCTLECH,M_LOCAL },
 441# endif /* LCTLECH */
 442# ifdef	LPENDIN
 443    { "lpendin",LPENDIN,M_LOCAL },
 444# endif /* LPENDIN */
 445# ifdef	LDECCTQ
 446    { "ldecctq",LDECCTQ,M_LOCAL },
 447# endif /* LDECCTQ */
 448# ifdef	LNOFLSH
 449    { "lnoflsh",LNOFLSH,M_LOCAL },
 450# endif /* LNOFLSH */
 451
 452#endif /* POSIX || TERMIO */
 453# if defined(VINTR) || defined(TIOCGETC)
 454    { "intr",		C_SH(C_INTR), 	M_CHAR },
 455# endif /* VINTR */
 456# if defined(VQUIT) || defined(TIOCGETC)
 457    { "quit",		C_SH(C_QUIT), 	M_CHAR },
 458# endif /* VQUIT */
 459# if defined(VERASE) || defined(TIOCGETP)
 460    { "erase",		C_SH(C_ERASE), 	M_CHAR },
 461# endif /* VERASE */
 462# if defined(VKILL) || defined(TIOCGETP)
 463    { "kill",		C_SH(C_KILL), 	M_CHAR },
 464# endif /* VKILL */
 465# if defined(VEOF) || defined(TIOCGETC)
 466    { "eof",		C_SH(C_EOF), 	M_CHAR },
 467# endif /* VEOF */
 468# if defined(VEOL)
 469    { "eol",		C_SH(C_EOL), 	M_CHAR },
 470# endif /* VEOL */
 471# if defined(VEOL2)
 472    { "eol2",		C_SH(C_EOL2), 	M_CHAR },
 473# endif  /* VEOL2 */
 474# if defined(VSWTCH)
 475    { "swtch",		C_SH(C_SWTCH), 	M_CHAR },
 476# endif /* VSWTCH */
 477# if defined(VDSWTCH)
 478    { "dswtch",		C_SH(C_DSWTCH),	M_CHAR },
 479# endif /* VDSWTCH */
 480# if defined(VERASE2)
 481    { "erase2",		C_SH(C_ERASE2),	M_CHAR },
 482# endif /* VERASE2 */
 483# if defined(VSTART) || defined(TIOCGETC)
 484    { "start",		C_SH(C_START), 	M_CHAR },
 485# endif /* VSTART */
 486# if defined(VSTOP) || defined(TIOCGETC)
 487    { "stop",		C_SH(C_STOP), 	M_CHAR },
 488# endif /* VSTOP */
 489# if defined(VWERASE) || defined(TIOCGLTC)
 490    { "werase",		C_SH(C_WERASE),	M_CHAR },
 491# endif /* VWERASE */
 492# if defined(VSUSP) || defined(TIOCGLTC)
 493    { "susp",		C_SH(C_SUSP), 	M_CHAR },
 494# endif /* VSUSP */
 495# if defined(VDSUSP) || defined(TIOCGLTC)
 496    { "dsusp",		C_SH(C_DSUSP), 	M_CHAR },
 497# endif /* VDSUSP */
 498# if defined(VREPRINT) || defined(TIOCGLTC)
 499    { "reprint",	C_SH(C_REPRINT),M_CHAR },
 500# endif /* WREPRINT */
 501# if defined(VDISCARD) || defined(TIOCGLTC)
 502    { "discard",	C_SH(C_DISCARD),M_CHAR },
 503# endif /* VDISCARD */
 504# if defined(VLNEXT) || defined(TIOCGLTC)
 505    { "lnext",		C_SH(C_LNEXT), 	M_CHAR },
 506# endif /* VLNEXT */
 507# if defined(VSTATUS) || defined(TIOCGPAGE)
 508    { "status",		C_SH(C_STATUS),	M_CHAR },
 509# endif /* VSTATUS */
 510# if defined(VPAGE) || defined(TIOCGPAGE)
 511    { "page",		C_SH(C_PAGE), 	M_CHAR },
 512# endif /* VPAGE */
 513# if defined(VPGOFF) || defined(TIOCGPAGE)
 514    { "pgoff",		C_SH(C_PGOFF), 	M_CHAR },
 515# endif /* VPGOFF */
 516# if defined(VKILL2) 
 517    { "kill2",		C_SH(C_KILL2), 	M_CHAR },
 518# endif /* VKILL2 */
 519# if defined(VBRK) || defined(TIOCGETC)
 520    { "brk",		C_SH(C_BRK), 	M_CHAR },
 521# endif /* VBRK */
 522# if defined(VMIN)
 523    { "min",		C_SH(C_MIN), 	M_CHAR },
 524# endif /* VMIN */
 525# if defined(VTIME)
 526    { "time",		C_SH(C_TIME), 	M_CHAR },
 527# endif /* VTIME */
 528    { NULL, 0, -1 },
 529};
 530
 531/*
 532 * If EAGAIN and/or EWOULDBLOCK are defined, we can't just return -1 in all
 533 * situations where ioctl() does.
 534 * 
 535 * On AIX 4.1.5 (and presumably some other versions and OSes), as you
 536 * perform the manual test suite in the README, if you 'bg' vi immediately
 537 * after suspending it, all is well, but if you wait a few seconds,
 538 * usually ioctl() will return -1, which previously caused tty_setty() to
 539 * return -1, causing Rawmode() to return -1, causing Inputl() to return
 540 * 0, causing bgetc() to return -1, causing readc() to set doneinp to 1,
 541 * causing process() to break out of the main loop, causing tcsh to exit
 542 * prematurely.
 543 * 
 544 * If ioctl()'s errno is EAGAIN/EWOULDBLOCK ("Resource temporarily
 545 * unavailable"), apparently the tty is being messed with by the OS and we
 546 * need to try again.  In my testing, ioctl() was never called more than
 547 * twice in a row.
 548 *
 549 * -- Dan Harkless <dan@wave.eng.uci.edu>
 550 *
 551 * So, I retry all ioctl's in case others happen to fail too (christos)
 552 */
 553
 554#if defined(EAGAIN) && defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
 555# define OKERROR(e) (((e) == EAGAIN) || ((e) == EWOULDBLOCK) || ((e) == EINTR))
 556#elif defined(EAGAIN)
 557# define OKERROR(e) (((e) == EAGAIN) || ((e) == EINTR))
 558#elif defined(EWOULDBLOCK)
 559# define OKERROR(e) (((e) == EWOULDBLOCK) || ((e) == EINTR))
 560#else
 561# define OKERROR(e) ((e) == EINTR)
 562#endif
 563
 564#ifdef __NetBSD__
 565#define KLUDGE (errno == ENOTTY && count < 10)
 566#else
 567#define KLUDGE 0
 568#endif
 569
 570/* Retry a system call */
 571#define RETRY(x)				\
 572do {						\
 573    int count;					\
 574						\
 575    for (count = 0;; count++)			\
 576	if ((x) == -1) {			\
 577	    if (OKERROR(errno) || KLUDGE)	\
 578		continue;			\
 579	    else				\
 580		return -1;			\
 581	}					\
 582	else					\
 583	    break;				\
 584} while (0)
 585
 586/*ARGSUSED*/
 587void
 588dosetty(Char **v, struct command *t)
 589{
 590    const struct tcshmodes *m;
 591    char x, *d, *cmdname;
 592    int aflag = 0;
 593    Char *s;
 594    int z = EX_IO;
 595
 596    USE(t);
 597    cmdname = strsave(short2str(*v++));
 598    cleanup_push(cmdname, xfree);
 599    setname(cmdname);
 600
 601    while (v && *v && v[0][0] == '-' && v[0][2] == '\0') 
 602	switch (v[0][1]) {
 603	case 'a':
 604	    aflag++;
 605	    v++;
 606	    break;
 607	case 'd':
 608	    v++;
 609	    z = ED_IO;
 610	    break;
 611	case 'x':
 612	    v++;
 613	    z = EX_IO;
 614	    break;
 615	case 'q':
 616	    v++;
 617	    z = QU_IO;
 618	    break;
 619	default:
 620	    stderror(ERR_NAME | ERR_SYSTEM, short2str(v[0]),
 621		     CGETS(8, 1, "Unknown switch"));
 622	    break;
 623	}
 624
 625    didsetty = 1;
 626    if (!v || !*v) {
 627	int i = -1;
 628	int len = 0, st = 0, cu;
 629	for (m = modelist; m->m_name; m++) {
 630	    if (m->m_type != i) {
 631		xprintf("%s%s", i != -1 ? "\n" : "",
 632			ttylist[z][m->m_type].t_name);
 633		i = m->m_type;
 634		st = len = strlen(ttylist[z][m->m_type].t_name);
 635	    }
 636	    assert(i != -1);
 637
 638	    x = (ttylist[z][i].t_setmask & m->m_value) ? '+' : '\0';
 639	    x = (ttylist[z][i].t_clrmask & m->m_value) ? '-' : x;
 640
 641	    if (x != '\0' || aflag) {
 642		cu = strlen(m->m_name) + (x != '\0') + 1;
 643		if (len + cu >= TermH) {
 644		    xprintf("\n%*s", st, "");
 645		    len = st + cu;
 646		}
 647		else 
 648		    len += cu;
 649		if (x != '\0')
 650		    xprintf("%c%s ", x, m->m_name);
 651		else
 652		    xprintf("%s ", m->m_name);
 653	    }
 654	}
 655	xputchar('\n');
 656	cleanup_until(cmdname);
 657	return;
 658    }
 659    while (v && (s = *v++)) {
 660	switch (*s) {
 661	case '+':
 662	case '-':
 663	    x = *s++;
 664	    break;
 665	default:
 666	    x = '\0';
 667	    break;
 668	}
 669	d = short2str(s);
 670	for (m = modelist; m->m_name; m++)
 671	    if (strcmp(m->m_name, d) == 0)
 672		break;
 673	if (!m->m_name) 
 674	    stderror(ERR_NAME | ERR_SYSTEM, d, CGETS(8, 2, "Invalid argument"));
 675
 676	switch (x) {
 677	case '+':
 678	    ttylist[z][m->m_type].t_setmask |= m->m_value;
 679	    ttylist[z][m->m_type].t_clrmask &= ~m->m_value;
 680	    break;
 681	case '-':
 682	    ttylist[z][m->m_type].t_setmask &= ~m->m_value;
 683	    ttylist[z][m->m_type].t_clrmask |= m->m_value;
 684	    break;
 685	default:
 686	    ttylist[z][m->m_type].t_setmask &= ~m->m_value;
 687	    ttylist[z][m->m_type].t_clrmask &= ~m->m_value;
 688	    break;
 689	}
 690    }
 691    cleanup_until(cmdname);
 692} /* end dosetty */
 693
 694int
 695tty_getty(int fd, ttydata_t *td)
 696{
 697#ifdef POSIX
 698    RETRY(tcgetattr(fd, &td->d_t));
 699#else /* TERMIO || GSTTY */
 700# ifdef TERMIO
 701    RETRY(ioctl(fd, TCGETA,    (ioctl_t) &td->d_t));
 702# else /* GSTTY */
 703#  ifdef TIOCGETP
 704    RETRY(ioctl(fd, TIOCGETP,  (ioctl_t) &td->d_t));
 705#  endif /* TIOCGETP */
 706#  ifdef TIOCGETC
 707    RETRY(ioctl(fd, TIOCGETC,  (ioctl_t) &td->d_tc));
 708#  endif /* TIOCGETC */
 709#  ifdef TIOCGPAGE
 710    RETRY(ioctl(fd, TIOCGPAGE, (ioctl_t) &td->d_pc));
 711#  endif /* TIOCGPAGE */
 712#  ifdef TIOCLGET
 713    RETRY(ioctl(fd, TIOCLGET,  (ioctl_t) &td->d_lb));
 714#  endif /* TIOCLGET */
 715# endif /* TERMIO */
 716#endif /* POSIX */
 717
 718#ifdef TIOCGLTC
 719    RETRY(ioctl(fd, TIOCGLTC,  (ioctl_t) &td->d_ltc));
 720#endif /* TIOCGLTC */
 721
 722    return 0;
 723}
 724
 725int
 726tty_setty(int fd, ttydata_t *td)
 727{
 728#ifdef POSIX
 729    RETRY(xtcsetattr(fd, TCSADRAIN, &td->d_t)); 
 730#else
 731# ifdef TERMIO
 732    RETRY(ioctl(fd, TCSETAW,    (ioctl_t) &td->d_t));
 733# else
 734#  ifdef TIOCSETN
 735    RETRY(ioctl(fd, TIOCSETN,  (ioctl_t) &td->d_t));
 736#  endif /* TIOCSETN */
 737#  ifdef TIOCGETC
 738    RETRY(ioctl(fd, TIOCSETC,  (ioctl_t) &td->d_tc));
 739#  endif /* TIOCGETC */
 740#  ifdef TIOCGPAGE
 741    RETRY(ioctl(fd, TIOCSPAGE, (ioctl_t) &td->d_pc));
 742#  endif /* TIOCGPAGE */
 743#  ifdef TIOCLGET
 744    RETRY(ioctl(fd, TIOCLSET,  (ioctl_t) &td->d_lb));
 745#  endif /* TIOCLGET */
 746# endif /* TERMIO */
 747#endif /* POSIX */
 748
 749#ifdef TIOCGLTC
 750    RETRY(ioctl(fd, TIOCSLTC,  (ioctl_t) &td->d_ltc));
 751#endif /* TIOCGLTC */
 752
 753    return 0;
 754}
 755
 756void
 757tty_getchar(ttydata_t *td, unsigned char *s)
 758{   
 759#ifdef TIOCGLTC
 760    {
 761	struct ltchars *n = &td->d_ltc;
 762
 763	s[C_SUSP]	= n->t_suspc;
 764	s[C_DSUSP]	= n->t_dsuspc;
 765	s[C_REPRINT]	= n->t_rprntc;
 766	s[C_DISCARD]	= n->t_flushc;
 767	s[C_WERASE]	= n->t_werasc;
 768	s[C_LNEXT]	= n->t_lnextc;
 769    }
 770#endif /* TIOCGLTC */
 771
 772#if defined(POSIX) || defined(TERMIO)
 773    {
 774# ifdef POSIX
 775	struct termios *n = &td->d_t;
 776# else
 777	struct termio *n = &td->d_t;
 778# endif /* POSIX */
 779
 780# ifdef VINTR
 781	s[C_INTR]	= n->c_cc[VINTR];
 782# endif /* VINTR */
 783# ifdef VQUIT
 784	s[C_QUIT]	= n->c_cc[VQUIT];
 785# endif /* VQUIT */
 786# ifdef VERASE
 787	s[C_ERASE]	= n->c_cc[VERASE];
 788# endif /* VERASE */
 789# ifdef VKILL
 790	s[C_KILL]	= n->c_cc[VKILL];
 791# endif /* VKILL */
 792# ifdef VEOF
 793	s[C_EOF]	= n->c_cc[VEOF];
 794# endif /* VEOF */
 795# ifdef VEOL
 796	s[C_EOL]	= n->c_cc[VEOL];
 797# endif /* VEOL */
 798# ifdef VEOL2
 799	s[C_EOL2]	= n->c_cc[VEOL2];
 800# endif  /* VEOL2 */
 801# ifdef VSWTCH
 802	s[C_SWTCH]	= n->c_cc[VSWTCH];
 803# endif /* VSWTCH */
 804# ifdef VDSWTCH
 805	s[C_DSWTCH]	= n->c_cc[VDSWTCH];
 806# endif /* VDSWTCH */
 807# ifdef VERASE2
 808	s[C_ERASE2]	= n->c_cc[VERASE2];
 809# endif /* VERASE2 */
 810# ifdef VSTART
 811	s[C_START]	= n->c_cc[VSTART];
 812# endif /* VSTART */
 813# ifdef VSTOP
 814	s[C_STOP]	= n->c_cc[VSTOP];
 815# endif /* VSTOP */
 816# ifdef VWERASE
 817	s[C_WERASE]	= n->c_cc[VWERASE];
 818# endif /* VWERASE */
 819# ifdef VSUSP
 820	s[C_SUSP]	= n->c_cc[VSUSP];
 821# endif /* VSUSP */
 822# ifdef VDSUSP
 823	s[C_DSUSP]	= n->c_cc[VDSUSP];
 824# endif /* VDSUSP */
 825# ifdef VREPRINT
 826	s[C_REPRINT]	= n->c_cc[VREPRINT];
 827# endif /* WREPRINT */
 828# ifdef VDISCARD
 829	s[C_DISCARD]	= n->c_cc[VDISCARD];
 830# endif /* VDISCARD */
 831# ifdef VLNEXT
 832	s[C_LNEXT]	= n->c_cc[VLNEXT];
 833# endif /* VLNEXT */
 834# ifdef VSTATUS
 835	s[C_STATUS]	= n->c_cc[VSTATUS];
 836# endif /* VSTATUS */
 837# ifdef VPAGE
 838	s[C_PAGE]	= n->c_cc[VPAGE];
 839# endif /* VPAGE */
 840# ifdef VPGOFF
 841	s[C_PGOFF]	= n->c_cc[VPGOFF];
 842# endif /* VPGOFF */
 843# ifdef VKILL2
 844	s[C_KILL2]	= n->c_cc[VKILL2];
 845# endif /* KILL2 */
 846# ifdef VMIN
 847	s[C_MIN]	= n->c_cc[VMIN];
 848# endif /* VMIN */
 849# ifdef VTIME
 850	s[C_TIME]	= n->c_cc[VTIME];
 851# endif /* VTIME */
 852    }
 853
 854#else /* SGTTY */
 855
 856# ifdef TIOCGPAGE
 857    {
 858	struct ttypagestat *n = &td->d_pc;
 859
 860	s[C_STATUS]	= n->tps_statc;
 861	s[C_PAGE]	= n->tps_pagec;
 862	s[C_PGOFF]	= n->tps_pgoffc;
 863    }
 864# endif /* TIOCGPAGE */
 865
 866# ifdef TIOCGETC
 867    {
 868	struct tchars *n = &td->d_tc;
 869
 870	s[C_INTR]	= n->t_intrc;
 871	s[C_QUIT]	= n->t_quitc;
 872	s[C_START]	= n->t_startc;
 873	s[C_STOP]	= n->t_stopc;
 874	s[C_EOF]	= n->t_eofc;
 875	s[C_BRK]	= n->t_brkc;
 876    }
 877# endif /* TIOCGETC */
 878
 879# ifdef TIOCGETP
 880    {
 881	struct sgttyb *n = &td->d_t;
 882
 883	s[C_ERASE]	= n->sg_erase;
 884	s[C_KILL]	= n->sg_kill;
 885    }
 886# endif /* TIOCGETP */
 887#endif /* !POSIX || TERMIO */
 888
 889} /* tty_getchar */
 890
 891
 892void
 893tty_setchar(ttydata_t *td, unsigned char *s)
 894{   
 895#ifdef TIOCGLTC
 896    {
 897	struct ltchars *n = &td->d_ltc; 
 898
 899	n->t_suspc 		= s[C_SUSP];
 900	n->t_dsuspc		= s[C_DSUSP];
 901	n->t_rprntc		= s[C_REPRINT];
 902	n->t_flushc		= s[C_DISCARD];
 903	n->t_werasc		= s[C_WERASE];
 904	n->t_lnextc		= s[C_LNEXT];
 905    }
 906#endif /* TIOCGLTC */
 907
 908#if defined(POSIX) || defined(TERMIO)
 909    {
 910# ifdef POSIX
 911	struct termios *n = &td->d_t;
 912# else
 913	struct termio *n = &td->d_t;
 914# endif /* POSIX */
 915
 916# ifdef VINTR
 917	n->c_cc[VINTR]		= s[C_INTR];
 918# endif /* VINTR */
 919# ifdef VQUIT
 920	n->c_cc[VQUIT]		= s[C_QUIT];
 921# endif /* VQUIT */
 922# ifdef VERASE
 923	n->c_cc[VERASE]		= s[C_ERASE];
 924# endif /* VERASE */
 925# ifdef VKILL
 926	n->c_cc[VKILL]		= s[C_KILL];
 927# endif /* VKILL */
 928# ifdef VEOF
 929	n->c_cc[VEOF]		= s[C_EOF];
 930# endif /* VEOF */
 931# ifdef VEOL
 932	n->c_cc[VEOL]		= s[C_EOL];
 933# endif /* VEOL */
 934# ifdef VEOL2
 935	n->c_cc[VEOL2]		= s[C_EOL2];
 936# endif  /* VEOL2 */
 937# ifdef VSWTCH
 938	n->c_cc[VSWTCH]		= s[C_SWTCH];
 939# endif /* VSWTCH */
 940# ifdef VDSWTCH
 941	n->c_cc[VDSWTCH]	= s[C_DSWTCH];
 942# endif /* VDSWTCH */
 943# ifdef VERASE2
 944	n->c_cc[VERASE2]	= s[C_ERASE2];
 945# endif /* VERASE2 */
 946# ifdef VSTART
 947	n->c_cc[VSTART]		= s[C_START];
 948# endif /* VSTART */
 949# ifdef VSTOP
 950	n->c_cc[VSTOP]		= s[C_STOP];
 951# endif /* VSTOP */
 952# ifdef VWERASE
 953	n->c_cc[VWERASE]	= s[C_WERASE];
 954# endif /* VWERASE */
 955# ifdef VSUSP
 956	n->c_cc[VSUSP]		= s[C_SUSP];
 957# endif /* VSUSP */
 958# ifdef VDSUSP
 959	n->c_cc[VDSUSP]		= s[C_DSUSP];
 960# endif /* VDSUSP */
 961# ifdef VREPRINT
 962	n->c_cc[VREPRINT]	= s[C_REPRINT];
 963# endif /* WREPRINT */
 964# ifdef VDISCARD
 965	n->c_cc[VDISCARD]	= s[C_DISCARD];
 966# endif /* VDISCARD */
 967# ifdef VLNEXT
 968	n->c_cc[VLNEXT]		= s[C_LNEXT];
 969# endif /* VLNEXT */
 970# ifdef VSTATUS
 971	n->c_cc[VSTATUS]	= s[C_STATUS];
 972# endif /* VSTATUS */
 973# ifdef VPAGE
 974	n->c_cc[VPAGE]		= s[C_PAGE];
 975# endif /* VPAGE */
 976# ifdef VPGOFF
 977	n->c_cc[VPGOFF]		= s[C_PGOFF];
 978# endif /* VPGOFF */
 979# ifdef VKILL2
 980	n->c_cc[VKILL2]		= s[C_KILL2];
 981# endif /* VKILL2 */
 982# ifdef VMIN
 983	n->c_cc[VMIN]		= s[C_MIN];
 984# endif /* VMIN */
 985# ifdef VTIME
 986	n->c_cc[VTIME]		= s[C_TIME];
 987# endif /* VTIME */
 988    }
 989
 990#else /* GSTTY */
 991
 992# ifdef TIOCGPAGE
 993    {
 994	struct ttypagestat *n = &td->d_pc;
 995
 996	n->tps_length		= 0;
 997	n->tps_lpos		= 0;
 998	n->tps_statc		= s[C_STATUS];
 999	n->tps_pagec		= s[C_PAGE];
1000	n->tps_pgoffc		= s[C_PGOFF];
1001	n->tps_flag		= 0;
1002    }
1003# endif /* TIOCGPAGE */
1004
1005# ifdef TIOCGETC
1006    {
1007	struct tchars *n = &td->d_tc;
1008	n->t_intrc		= s[C_INTR];
1009	n->t_quitc		= s[C_QUIT];
1010	n->t_startc		= s[C_START];
1011	n->t_stopc		= s[C_STOP];
1012	n->t_eofc		= s[C_EOF];
1013	n->t_brkc		= s[C_BRK];
1014    }
1015# endif /* TIOCGETC */
1016
1017# ifdef TIOCGETP
1018    {
1019	struct sgttyb *n = &td->d_t;
1020
1021	n->sg_erase		= s[C_ERASE];
1022	n->sg_kill		= s[C_KILL];
1023    }
1024# endif /* TIOCGETP */
1025#endif /* !POSIX || TERMIO */
1026
1027} /* tty_setchar */
1028
1029speed_t
1030tty_getspeed(ttydata_t *td)
1031{
1032    speed_t spd;
1033
1034#ifdef POSIX
1035    if ((spd = cfgetispeed(&td->d_t)) == 0)
1036	spd = cfgetospeed(&td->d_t);
1037#else /* ! POSIX */
1038# ifdef TERMIO
1039#  ifdef CBAUD
1040    spd = td->d_t.c_cflag & CBAUD;
1041#  else 
1042    spd = 0;
1043#  endif 
1044# else /* SGTTY */
1045    spd = td->d_t.sg_ispeed;
1046# endif /* TERMIO */
1047#endif /* POSIX */
1048
1049    return spd;
1050} /* end tty_getspeed */
1051
1052int
1053tty_gettabs(ttydata_t *td)
1054{
1055#if defined(POSIX) || defined(TERMIO)
1056    return ((td->d_t.c_oflag & TAB3) == TAB3) ? 0 : 1;
1057#else /* SGTTY */
1058    return (td->d_t.sg_flags & XTABS) == XTABS ? 0 : 1;
1059#endif /* POSIX || TERMIO */
1060} /* end tty_gettabs */
1061
1062int
1063tty_geteightbit(ttydata_t *td)
1064{
1065#if defined(POSIX) || defined(TERMIO)
1066    return (td->d_t.c_cflag & CSIZE) == CS8;
1067#else /* SGTTY */
1068    return td->d_lb & (LPASS8 | LLITOUT);
1069#endif /* POSIX || TERMIO */
1070} /* end tty_geteightbit */
1071
1072int
1073tty_cooked_mode(ttydata_t *td)
1074{
1075#if defined(POSIX) || defined(TERMIO)
1076    return (td->d_t.c_lflag & ICANON);
1077#else /* SGTTY */
1078    return !(td->d_t.sg_flags & (RAW | CBREAK));
1079#endif /* POSIX || TERMIO */
1080} /* end tty_cooked_mode */
1081
1082#ifdef _IBMR2
1083void
1084tty_setdisc(int fd, int dis)
1085{
1086    static int edit_discipline = 0;
1087    static union txname tx_disc;
1088    extern char strPOSIX[];
1089
1090    switch (dis) {
1091    case EX_IO:
1092	if (edit_discipline) {
1093	    if (ioctl(fd, TXSETLD, (ioctl_t) & tx_disc) == -1)
1094		return;
1095	    edit_discipline = 0;
1096	}
1097	return;
1098
1099    case ED_IO:
1100	tx_disc.tx_which = 0;
1101	if (ioctl(fd, TXGETLD, (ioctl_t) & tx_disc) == -1)
1102	    return;
1103	if (strcmp(tx_disc.tx_name, strPOSIX) != 0) {
1104	    edit_discipline = 1;
1105	    if (ioctl(fd, TXSETLD, (ioctl_t) strPOSIX) == -1)
1106	    return;
1107	}
1108	return;
1109
1110    default:
1111	return;
1112    }
1113} /* end tty_setdisc */
1114#endif /* _IBMR2 */
1115
1116#ifdef DEBUG_TTY
1117static void
1118tty_printchar(unsigned char *s)
1119{
1120    struct tcshmodes *m;
1121    int i;
1122
1123    for (i = 0; i < C_NCC; i++) {
1124	for (m = modelist; m->m_name; m++) 
1125	    if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
1126		break;
1127	if (m->m_name)
1128	    xprintf("%s ^%c ", m->m_name, s[i] + 'A' - 1);
1129	if (i % 5 == 0)
1130	    xputchar('\n');
1131    }
1132    xputchar('\n');
1133}
1134#endif /* DEBUG_TTY */
1135#else /* WINNT_NATIVE */
1136int
1137tty_cooked_mode(void *td)
1138{
1139    return do_nt_check_cooked_mode();
1140}
1141#endif /* !WINNT_NATIVE */