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