source: trunk/third/tcsh/ed.term.c @ 22036

Revision 22036, 26.7 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22035, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/ed.term.c,v 1.1.1.3 2005-06-03 14:35:03 ghudson 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("$Id: ed.term.c,v 1.1.1.3 2005-06-03 14:35:03 ghudson Exp $")
37
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 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 */
571static int count;
572#define RETRY(x) \
573   for (count = 0;; count++) \
574        if ((x) == -1) { \
575            if (OKERROR(errno) || KLUDGE) \
576                continue; \
577            else \
578                return -1; \
579        } \
580        else \
581           break \
582
583/*ARGSUSED*/
584void
585dosetty(v, t)
586    Char **v;
587    struct command *t;
588{
589    struct tcshmodes *m;
590    char x, *d;
591    int aflag = 0;
592    Char *s;
593    int z = EX_IO;
594    char cmdname[BUFSIZE];
595
596    USE(t);
597    setname(strcpy(cmdname, short2str(*v++)));
598
599    while (v && *v && v[0][0] == '-' && v[0][2] == '\0')
600        switch (v[0][1]) {
601        case 'a':
602            aflag++;
603            v++;
604            break;
605        case 'd':
606            v++;
607            z = ED_IO;
608            break;
609        case 'x':
610            v++;
611            z = EX_IO;
612            break;
613        case 'q':
614            v++;
615            z = QU_IO;
616            break;
617        default:
618            stderror(ERR_NAME | ERR_SYSTEM, short2str(v[0]),
619                     CGETS(8, 1, "Unknown switch"));
620            break;
621        }
622
623    didsetty = 1;
624    if (!v || !*v) {
625        int i = -1;
626        int len = 0, st = 0, cu;
627        for (m = modelist; m->m_name; m++) {
628            if (m->m_type != i) {
629                xprintf("%s%s", i != -1 ? "\n" : "",
630                        ttylist[z][m->m_type].t_name);
631                i = m->m_type;
632                st = len = strlen(ttylist[z][m->m_type].t_name);
633            }
634
635            x = (ttylist[z][i].t_setmask & m->m_value) ? '+' : '\0';
636            x = (ttylist[z][i].t_clrmask & m->m_value) ? '-' : x;
637
638            if (x != '\0' || aflag) {
639                cu = strlen(m->m_name) + (x != '\0') + 1;
640                if (len + cu >= T_Cols) {
641                    xprintf("\n%*s", st, "");
642                    len = st + cu;
643                }
644                else
645                    len += cu;
646                if (x != '\0')
647                    xprintf("%c%s ", x, m->m_name);
648                else
649                    xprintf("%s ", m->m_name);
650            }
651        }
652        xputchar('\n');
653        return;
654    }
655    while (v && (s = *v++)) {
656        switch (*s) {
657        case '+':
658        case '-':
659            x = *s++;
660            break;
661        default:
662            x = '\0';
663            break;
664        }
665        d = short2str(s);
666        for (m = modelist; m->m_name; m++)
667            if (strcmp(m->m_name, d) == 0)
668                break;
669        if (!m->m_name)
670            stderror(ERR_NAME | ERR_SYSTEM, d, CGETS(8, 2, "Invalid argument"));
671
672        switch (x) {
673        case '+':
674            ttylist[z][m->m_type].t_setmask |= m->m_value;
675            ttylist[z][m->m_type].t_clrmask &= ~m->m_value;
676            break;
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        default:
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        }
686    }
687} /* end dosetty */
688
689int
690tty_getty(fd, td)
691   int fd;
692   ttydata_t *td;
693{
694#ifdef POSIX
695    RETRY(tcgetattr(fd, &td->d_t));
696#else /* TERMIO || GSTTY */
697# ifdef TERMIO
698    RETRY(ioctl(fd, TCGETA,    (ioctl_t) &td->d_t));
699# else /* GSTTY */
700#  ifdef TIOCGETP
701    RETRY(ioctl(fd, TIOCGETP,  (ioctl_t) &td->d_t));
702#  endif /* TIOCGETP */
703#  ifdef TIOCGETC
704    RETRY(ioctl(fd, TIOCGETC,  (ioctl_t) &td->d_tc));
705#  endif /* TIOCGETC */
706#  ifdef TIOCGPAGE
707    RETRY(ioctl(fd, TIOCGPAGE, (ioctl_t) &td->d_pc));
708#  endif /* TIOCGPAGE */
709#  ifdef TIOCLGET
710    RETRY(ioctl(fd, TIOCLGET,  (ioctl_t) &td->d_lb));
711#  endif /* TIOCLGET */
712# endif /* TERMIO */
713#endif /* POSIX */
714
715#ifdef TIOCGLTC
716    RETRY(ioctl(fd, TIOCGLTC,  (ioctl_t) &td->d_ltc));
717#endif /* TIOCGLTC */
718
719    return 0;
720}
721
722int
723tty_setty(fd, td)
724   int fd;
725   ttydata_t *td;
726{
727#ifdef POSIX
728    RETRY(tcsetattr(fd, TCSADRAIN, &td->d_t));
729#else
730# ifdef TERMIO
731    RETRY(ioctl(fd, TCSETAW,    (ioctl_t) &td->d_t));
732# else
733#  ifdef TIOCSETN
734    RETRY(ioctl(fd, TIOCSETN,  (ioctl_t) &td->d_t));
735#  endif /* TIOCSETN */
736#  ifdef TIOCGETC
737    RETRY(ioctl(fd, TIOCSETC,  (ioctl_t) &td->d_tc));
738#  endif /* TIOCGETC */
739#  ifdef TIOCGPAGE
740    RETRY(ioctl(fd, TIOCSPAGE, (ioctl_t) &td->d_pc));
741#  endif /* TIOCGPAGE */
742#  ifdef TIOCLGET
743    RETRY(ioctl(fd, TIOCLSET,  (ioctl_t) &td->d_lb));
744#  endif /* TIOCLGET */
745# endif /* TERMIO */
746#endif /* POSIX */
747
748#ifdef TIOCGLTC
749    RETRY(ioctl(fd, TIOCSLTC,  (ioctl_t) &td->d_ltc));
750#endif /* TIOCGLTC */
751
752    return 0;
753}
754
755void
756tty_getchar(td, s)
757    ttydata_t *td;
758    unsigned char *s;
759{   
760#ifdef TIOCGLTC
761    {
762        struct ltchars *n = &td->d_ltc;
763
764        s[C_SUSP]       = n->t_suspc;
765        s[C_DSUSP]      = n->t_dsuspc;
766        s[C_REPRINT]    = n->t_rprntc;
767        s[C_DISCARD]    = n->t_flushc;
768        s[C_WERASE]     = n->t_werasc;
769        s[C_LNEXT]      = n->t_lnextc;
770    }
771#endif /* TIOCGLTC */
772
773#if defined(POSIX) || defined(TERMIO)
774    {
775# ifdef POSIX
776        struct termios *n = &td->d_t;
777# else
778        struct termio *n = &td->d_t;
779# endif /* POSIX */
780
781# ifdef VINTR
782        s[C_INTR]       = n->c_cc[VINTR];
783# endif /* VINTR */
784# ifdef VQUIT
785        s[C_QUIT]       = n->c_cc[VQUIT];
786# endif /* VQUIT */
787# ifdef VERASE
788        s[C_ERASE]      = n->c_cc[VERASE];
789# endif /* VERASE */
790# ifdef VKILL
791        s[C_KILL]       = n->c_cc[VKILL];
792# endif /* VKILL */
793# ifdef VEOF
794        s[C_EOF]        = n->c_cc[VEOF];
795# endif /* VEOF */
796# ifdef VEOL
797        s[C_EOL]        = n->c_cc[VEOL];
798# endif /* VEOL */
799# ifdef VEOL2
800        s[C_EOL2]       = n->c_cc[VEOL2];
801# endif  /* VEOL2 */
802# ifdef VSWTCH
803        s[C_SWTCH]      = n->c_cc[VSWTCH];
804# endif /* VSWTCH */
805# ifdef VDSWTCH
806        s[C_DSWTCH]     = n->c_cc[VDSWTCH];
807# endif /* VDSWTCH */
808# ifdef VERASE2
809        s[C_ERASE2]     = n->c_cc[VERASE2];
810# endif /* VERASE2 */
811# ifdef VSTART
812        s[C_START]      = n->c_cc[VSTART];
813# endif /* VSTART */
814# ifdef VSTOP
815        s[C_STOP]       = n->c_cc[VSTOP];
816# endif /* VSTOP */
817# ifdef VWERASE
818        s[C_WERASE]     = n->c_cc[VWERASE];
819# endif /* VWERASE */
820# ifdef VSUSP
821        s[C_SUSP]       = n->c_cc[VSUSP];
822# endif /* VSUSP */
823# ifdef VDSUSP
824        s[C_DSUSP]      = n->c_cc[VDSUSP];
825# endif /* VDSUSP */
826# ifdef VREPRINT
827        s[C_REPRINT]    = n->c_cc[VREPRINT];
828# endif /* WREPRINT */
829# ifdef VDISCARD
830        s[C_DISCARD]    = n->c_cc[VDISCARD];
831# endif /* VDISCARD */
832# ifdef VLNEXT
833        s[C_LNEXT]      = n->c_cc[VLNEXT];
834# endif /* VLNEXT */
835# ifdef VSTATUS
836        s[C_STATUS]     = n->c_cc[VSTATUS];
837# endif /* VSTATUS */
838# ifdef VPAGE
839        s[C_PAGE]       = n->c_cc[VPAGE];
840# endif /* VPAGE */
841# ifdef VPGOFF
842        s[C_PGOFF]      = n->c_cc[VPGOFF];
843# endif /* VPGOFF */
844# ifdef VKILL2
845        s[C_KILL2]      = n->c_cc[VKILL2];
846# endif /* KILL2 */
847# ifdef VMIN
848        s[C_MIN]        = n->c_cc[VMIN];
849# endif /* VMIN */
850# ifdef VTIME
851        s[C_TIME]       = n->c_cc[VTIME];
852# endif /* VTIME */
853    }
854
855#else /* SGTTY */
856
857# ifdef TIOCGPAGE
858    {
859        struct ttypagestat *n = &td->d_pc;
860
861        s[C_STATUS]     = n->tps_statc;
862        s[C_PAGE]       = n->tps_pagec;
863        s[C_PGOFF]      = n->tps_pgoffc;
864    }
865# endif /* TIOCGPAGE */
866
867# ifdef TIOCGETC
868    {
869        struct tchars *n = &td->d_tc;
870
871        s[C_INTR]       = n->t_intrc;
872        s[C_QUIT]       = n->t_quitc;
873        s[C_START]      = n->t_startc;
874        s[C_STOP]       = n->t_stopc;
875        s[C_EOF]        = n->t_eofc;
876        s[C_BRK]        = n->t_brkc;
877    }
878# endif /* TIOCGETC */
879
880# ifdef TIOCGETP
881    {
882        struct sgttyb *n = &td->d_t;
883
884        s[C_ERASE]      = n->sg_erase;
885        s[C_KILL]       = n->sg_kill;
886    }
887# endif /* TIOCGETP */
888#endif /* !POSIX || TERMIO */
889
890} /* tty_getchar */
891
892
893void
894tty_setchar(td, s)
895    ttydata_t *td;
896    unsigned char *s;
897{   
898#ifdef TIOCGLTC
899    {
900        struct ltchars *n = &td->d_ltc;
901
902        n->t_suspc              = s[C_SUSP];
903        n->t_dsuspc             = s[C_DSUSP];
904        n->t_rprntc             = s[C_REPRINT];
905        n->t_flushc             = s[C_DISCARD];
906        n->t_werasc             = s[C_WERASE];
907        n->t_lnextc             = s[C_LNEXT];
908    }
909#endif /* TIOCGLTC */
910
911#if defined(POSIX) || defined(TERMIO)
912    {
913# ifdef POSIX
914        struct termios *n = &td->d_t;
915# else
916        struct termio *n = &td->d_t;
917# endif /* POSIX */
918
919# ifdef VINTR
920        n->c_cc[VINTR]          = s[C_INTR];
921# endif /* VINTR */
922# ifdef VQUIT
923        n->c_cc[VQUIT]          = s[C_QUIT];
924# endif /* VQUIT */
925# ifdef VERASE
926        n->c_cc[VERASE]         = s[C_ERASE];
927# endif /* VERASE */
928# ifdef VKILL
929        n->c_cc[VKILL]          = s[C_KILL];
930# endif /* VKILL */
931# ifdef VEOF
932        n->c_cc[VEOF]           = s[C_EOF];
933# endif /* VEOF */
934# ifdef VEOL
935        n->c_cc[VEOL]           = s[C_EOL];
936# endif /* VEOL */
937# ifdef VEOL2
938        n->c_cc[VEOL2]          = s[C_EOL2];
939# endif  /* VEOL2 */
940# ifdef VSWTCH
941        n->c_cc[VSWTCH]         = s[C_SWTCH];
942# endif /* VSWTCH */
943# ifdef VDSWTCH
944        n->c_cc[VDSWTCH]        = s[C_DSWTCH];
945# endif /* VDSWTCH */
946# ifdef VERASE2
947        n->c_cc[VERASE2]        = s[C_ERASE2];
948# endif /* VERASE2 */
949# ifdef VSTART
950        n->c_cc[VSTART]         = s[C_START];
951# endif /* VSTART */
952# ifdef VSTOP
953        n->c_cc[VSTOP]          = s[C_STOP];
954# endif /* VSTOP */
955# ifdef VWERASE
956        n->c_cc[VWERASE]        = s[C_WERASE];
957# endif /* VWERASE */
958# ifdef VSUSP
959        n->c_cc[VSUSP]          = s[C_SUSP];
960# endif /* VSUSP */
961# ifdef VDSUSP
962        n->c_cc[VDSUSP]         = s[C_DSUSP];
963# endif /* VDSUSP */
964# ifdef VREPRINT
965        n->c_cc[VREPRINT]       = s[C_REPRINT];
966# endif /* WREPRINT */
967# ifdef VDISCARD
968        n->c_cc[VDISCARD]       = s[C_DISCARD];
969# endif /* VDISCARD */
970# ifdef VLNEXT
971        n->c_cc[VLNEXT]         = s[C_LNEXT];
972# endif /* VLNEXT */
973# ifdef VSTATUS
974        n->c_cc[VSTATUS]        = s[C_STATUS];
975# endif /* VSTATUS */
976# ifdef VPAGE
977        n->c_cc[VPAGE]          = s[C_PAGE];
978# endif /* VPAGE */
979# ifdef VPGOFF
980        n->c_cc[VPGOFF]         = s[C_PGOFF];
981# endif /* VPGOFF */
982# ifdef VKILL2
983        n->c_cc[VKILL2]         = s[C_KILL2];
984# endif /* VKILL2 */
985# ifdef VMIN
986        n->c_cc[VMIN]           = s[C_MIN];
987# endif /* VMIN */
988# ifdef VTIME
989        n->c_cc[VTIME]          = s[C_TIME];
990# endif /* VTIME */
991    }
992
993#else /* GSTTY */
994
995# ifdef TIOCGPAGE
996    {
997        struct ttypagestat *n = &td->d_pc;
998
999        n->tps_length           = 0;
1000        n->tps_lpos             = 0;
1001        n->tps_statc            = s[C_STATUS];
1002        n->tps_pagec            = s[C_PAGE];
1003        n->tps_pgoffc           = s[C_PGOFF];
1004        n->tps_flag             = 0;
1005    }
1006# endif /* TIOCGPAGE */
1007
1008# ifdef TIOCGETC
1009    {
1010        struct tchars *n = &td->d_tc;
1011        n->t_intrc              = s[C_INTR];
1012        n->t_quitc              = s[C_QUIT];
1013        n->t_startc             = s[C_START];
1014        n->t_stopc              = s[C_STOP];
1015        n->t_eofc               = s[C_EOF];
1016        n->t_brkc               = s[C_BRK];
1017    }
1018# endif /* TIOCGETC */
1019
1020# ifdef TIOCGETP
1021    {
1022        struct sgttyb *n = &td->d_t;
1023
1024        n->sg_erase             = s[C_ERASE];
1025        n->sg_kill              = s[C_KILL];
1026    }
1027# endif /* TIOCGETP */
1028#endif /* !POSIX || TERMIO */
1029
1030} /* tty_setchar */
1031
1032speed_t
1033tty_getspeed(td)
1034    ttydata_t *td;
1035{
1036    speed_t spd;
1037
1038#ifdef POSIX
1039    if ((spd = cfgetispeed(&td->d_t)) == 0)
1040        spd = cfgetospeed(&td->d_t);
1041#else /* ! POSIX */
1042# ifdef TERMIO
1043#  ifdef CBAUD
1044    spd = td->d_t.c_cflag & CBAUD;
1045#  else
1046    spd = 0;
1047#  endif
1048# else /* SGTTY */
1049    spd = td->d_t.sg_ispeed;
1050# endif /* TERMIO */
1051#endif /* POSIX */
1052
1053    return spd;
1054} /* end tty_getspeed */
1055
1056int
1057tty_gettabs(td)
1058    ttydata_t *td;
1059{
1060#if defined(POSIX) || defined(TERMIO)
1061    return ((td->d_t.c_oflag & TAB3) == TAB3) ? 0 : 1;
1062#else /* SGTTY */
1063    return (td->d_t.sg_flags & XTABS) == XTABS ? 0 : 1;
1064#endif /* POSIX || TERMIO */
1065} /* end tty_gettabs */
1066
1067int
1068tty_geteightbit(td)
1069    ttydata_t *td;
1070{
1071#if defined(POSIX) || defined(TERMIO)
1072    return (td->d_t.c_cflag & CSIZE) == CS8;
1073#else /* SGTTY */
1074    return td->d_lb & (LPASS8 | LLITOUT);
1075#endif /* POSIX || TERMIO */
1076} /* end tty_geteightbit */
1077
1078int
1079tty_cooked_mode(td)
1080    ttydata_t *td;
1081{
1082#if defined(POSIX) || defined(TERMIO)
1083    return (td->d_t.c_lflag & ICANON);
1084#else /* SGTTY */
1085    return !(td->d_t.sg_flags & (RAW | CBREAK));
1086#endif /* POSIX || TERMIO */
1087} /* end tty_cooked_mode */
1088
1089#ifdef _IBMR2
1090void
1091tty_setdisc(fd, dis)
1092    int fd;
1093    int dis;
1094{
1095    static int edit_discipline = 0;
1096    static union txname tx_disc;
1097    extern char strPOSIX[];
1098
1099    switch (dis) {
1100    case EX_IO:
1101        if (edit_discipline) {
1102            if (ioctl(fd, TXSETLD, (ioctl_t) & tx_disc) == -1)
1103                return;
1104            edit_discipline = 0;
1105        }
1106        return;
1107
1108    case ED_IO:
1109        tx_disc.tx_which = 0;
1110        if (ioctl(fd, TXGETLD, (ioctl_t) & tx_disc) == -1)
1111            return;
1112        if (strcmp(tx_disc.tx_name, strPOSIX) != 0) {
1113            edit_discipline = 1;
1114            if (ioctl(fd, TXSETLD, (ioctl_t) strPOSIX) == -1)
1115            return;
1116        }
1117        return;
1118
1119    default:
1120        return;
1121    }
1122} /* end tty_setdisc */
1123#endif /* _IBMR2 */
1124
1125#ifdef DEBUG_TTY
1126static void
1127tty_printchar(s)
1128    unsigned char *s;
1129{
1130    struct tcshmodes *m;
1131    int i;
1132
1133    for (i = 0; i < C_NCC; i++) {
1134        for (m = modelist; m->m_name; m++)
1135            if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
1136                break;
1137        if (m->m_name)
1138            xprintf("%s ^%c ", m->m_name, s[i] + 'A' - 1);
1139        if (i % 5 == 0)
1140            xputchar('\n');
1141    }
1142    xputchar('\n');
1143}
1144#endif /* DEBUG_TTY */
1145#else /* WINNT_NATIVE */
1146int
1147tty_cooked_mode(td)
1148    void *td;
1149{
1150    return do_nt_check_cooked_mode();
1151}
1152#endif /* !WINNT_NATIVE */
Note: See TracBrowser for help on using the repository browser.