Deleted Added
sdiff udiff text old ( 69408 ) new ( 83098 )
full compact
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
40RCSID("$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
45int didsetty = 0;
46ttyperm_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
92static 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*/
582void
583dosetty(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
687int
688tty_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
720int
721tty_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
753void
754tty_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
891void
892tty_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
1030speed_t
1031tty_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
1054int
1055tty_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
1065int
1066tty_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
1076int
1077tty_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
1088void
1089tty_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
1124static void
1125tty_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 */
1144int
1145tty_cooked_mode(td)
1146 void *td;
1147{
1148 return do_nt_check_cooked_mode();
1149}
1150#endif /* !WINNT_NATIVE */