tty.c revision 1.4 1 1.4 agc /* $NetBSD: tty.c,v 1.4 2003/06/23 11:39:06 agc Exp $ */
2 1.4 agc
3 1.4 agc #include <sys/cdefs.h>
4 1.4 agc
5 1.4 agc #ifndef lint
6 1.4 agc __RCSID("$NetBSD: tty.c,v 1.4 2003/06/23 11:39:06 agc Exp $");
7 1.4 agc #endif
8 1.4 agc
9 1.2 tls
10 1.1 jtc #include "sh.h"
11 1.1 jtc #include "ksh_stat.h"
12 1.1 jtc #define EXTERN
13 1.1 jtc #include "tty.h"
14 1.1 jtc #undef EXTERN
15 1.1 jtc
16 1.1 jtc int
17 1.1 jtc get_tty(fd, ts)
18 1.1 jtc int fd;
19 1.1 jtc TTY_state *ts;
20 1.1 jtc {
21 1.1 jtc int ret;
22 1.1 jtc
23 1.1 jtc # ifdef HAVE_TERMIOS_H
24 1.1 jtc ret = tcgetattr(fd, ts);
25 1.1 jtc # else /* HAVE_TERIOS_H */
26 1.1 jtc # ifdef HAVE_TERMIO_H
27 1.1 jtc ret = ioctl(fd, TCGETA, ts);
28 1.1 jtc # else /* HAVE_TERMIO_H */
29 1.1 jtc ret = ioctl(fd, TIOCGETP, &ts->sgttyb);
30 1.1 jtc # ifdef TIOCGATC
31 1.1 jtc if (ioctl(fd, TIOCGATC, &ts->lchars) < 0)
32 1.1 jtc ret = -1;
33 1.1 jtc # else
34 1.1 jtc if (ioctl(fd, TIOCGETC, &ts->tchars) < 0)
35 1.1 jtc ret = -1;
36 1.1 jtc # ifdef TIOCGLTC
37 1.1 jtc if (ioctl(fd, TIOCGLTC, &ts->ltchars) < 0)
38 1.1 jtc ret = -1;
39 1.1 jtc # endif /* TIOCGLTC */
40 1.1 jtc # endif /* TIOCGATC */
41 1.1 jtc # endif /* HAVE_TERMIO_H */
42 1.1 jtc # endif /* HAVE_TERIOS_H */
43 1.1 jtc return ret;
44 1.1 jtc }
45 1.1 jtc
46 1.1 jtc int
47 1.1 jtc set_tty(fd, ts, flags)
48 1.1 jtc int fd;
49 1.1 jtc TTY_state *ts;
50 1.1 jtc int flags;
51 1.1 jtc {
52 1.1 jtc int ret = 0;
53 1.1 jtc
54 1.1 jtc # ifdef HAVE_TERMIOS_H
55 1.1 jtc ret = tcsetattr(fd, TCSADRAIN, ts);
56 1.1 jtc # else /* HAVE_TERIOS_H */
57 1.1 jtc # ifdef HAVE_TERMIO_H
58 1.1 jtc # ifndef TCSETAW /* e.g. Cray-2 */
59 1.1 jtc /* first wait for output to drain */
60 1.1 jtc # ifdef TCSBRK
61 1.1 jtc if (ioctl(tty_fd, TCSBRK, 1) < 0)
62 1.1 jtc ret = -1;
63 1.1 jtc # else /* the following kludge is minimally intrusive, but sometimes fails */
64 1.1 jtc if (flags & TF_WAIT)
65 1.1 jtc sleep((unsigned)1); /* fake it */
66 1.1 jtc # endif
67 1.1 jtc # endif /* !TCSETAW */
68 1.1 jtc # if defined(_BSD_SYSV) || !defined(TCSETAW)
69 1.1 jtc /* _BSD_SYSV must force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
70 1.1 jtc if (ioctl(tty_fd, TCSETA, ts) < 0)
71 1.1 jtc ret = -1;
72 1.1 jtc # else
73 1.1 jtc if (ioctl(tty_fd, TCSETAW, ts) < 0)
74 1.1 jtc ret = -1;
75 1.1 jtc # endif
76 1.1 jtc # else /* HAVE_TERMIO_H */
77 1.1 jtc # if defined(__mips) && (defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
78 1.1 jtc /* Under RISC/os 5.00, bsd43 environment, after a tty driver
79 1.1 jtc * generated interrupt (eg, INTR, TSTP), all output to tty is
80 1.1 jtc * lost until a SETP is done (there must be a better way of
81 1.1 jtc * doing this...).
82 1.1 jtc */
83 1.1 jtc if (flags & TF_MIPSKLUDGE)
84 1.1 jtc ret = ioctl(fd, TIOCSETP, &ts->sgttyb);
85 1.1 jtc else
86 1.1 jtc # endif /* _SYSTYPE_BSD43 */
87 1.1 jtc ret = ioctl(fd, TIOCSETN, &ts->sgttyb);
88 1.1 jtc # ifdef TIOCGATC
89 1.1 jtc if (ioctl(fd, TIOCSATC, &ts->lchars) < 0)
90 1.1 jtc ret = -1;
91 1.1 jtc # else
92 1.1 jtc if (ioctl(fd, TIOCSETC, &ts->tchars) < 0)
93 1.1 jtc ret = -1;
94 1.1 jtc # ifdef TIOCGLTC
95 1.1 jtc if (ioctl(fd, TIOCSLTC, &ts->ltchars) < 0)
96 1.1 jtc ret = -1;
97 1.1 jtc # endif /* TIOCGLTC */
98 1.1 jtc # endif /* TIOCGATC */
99 1.1 jtc # endif /* HAVE_TERMIO_H */
100 1.1 jtc # endif /* HAVE_TERIOS_H */
101 1.1 jtc return ret;
102 1.1 jtc }
103 1.1 jtc
104 1.1 jtc
105 1.1 jtc /* Initialize tty_fd. Used for saving/reseting tty modes upon
106 1.1 jtc * foreground job completion and for setting up tty process group.
107 1.1 jtc */
108 1.1 jtc void
109 1.1 jtc tty_init(init_ttystate)
110 1.1 jtc int init_ttystate;
111 1.1 jtc {
112 1.1 jtc int do_close = 1;
113 1.1 jtc int tfd;
114 1.3 fair const char *devtty = _PATH_TTY;
115 1.1 jtc
116 1.1 jtc if (tty_fd >= 0) {
117 1.1 jtc close(tty_fd);
118 1.1 jtc tty_fd = -1;
119 1.1 jtc }
120 1.1 jtc tty_devtty = 1;
121 1.1 jtc
122 1.1 jtc /* SCO can't job control on /dev/tty, so don't try... */
123 1.1 jtc #if !defined(__SCO__)
124 1.3 fair if ((tfd = open(devtty, O_RDWR, 0)) < 0) {
125 1.2 tls #ifdef __NeXT
126 1.2 tls /* rlogin on NeXT boxes does not set up the controlling tty,
127 1.2 tls * so force it to be done here...
128 1.2 tls */
129 1.2 tls {
130 1.2 tls extern char *ttyname ARGS((int));
131 1.2 tls char *s = ttyname(isatty(2) ? 2 : 0);
132 1.2 tls int fd;
133 1.2 tls
134 1.2 tls if (s && (fd = open(s, O_RDWR, 0)) >= 0) {
135 1.2 tls close(fd);
136 1.3 fair tfd = open(devtty, O_RDWR, 0);
137 1.2 tls }
138 1.2 tls }
139 1.2 tls #endif /* __NeXT */
140 1.2 tls
141 1.1 jtc /* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */
142 1.1 jtc # if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
143 1.2 tls if (tfd < 0) {
144 1.2 tls tty_devtty = 0;
145 1.2 tls warningf(FALSE,
146 1.3 fair "No controlling tty (open %s: %s)",
147 1.3 fair devtty, strerror(errno));
148 1.2 tls }
149 1.1 jtc # endif /* __mips */
150 1.1 jtc }
151 1.1 jtc #else /* !__SCO__ */
152 1.1 jtc tfd = -1;
153 1.1 jtc #endif /* __SCO__ */
154 1.1 jtc
155 1.1 jtc if (tfd < 0) {
156 1.1 jtc do_close = 0;
157 1.1 jtc if (isatty(0))
158 1.1 jtc tfd = 0;
159 1.1 jtc else if (isatty(2))
160 1.1 jtc tfd = 2;
161 1.1 jtc else {
162 1.1 jtc warningf(FALSE, "Can't find tty file descriptor");
163 1.1 jtc return;
164 1.1 jtc }
165 1.1 jtc }
166 1.1 jtc if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
167 1.1 jtc warningf(FALSE, "j_ttyinit: dup of tty fd failed: %s",
168 1.1 jtc strerror(errno));
169 1.1 jtc } else if (fd_clexec(tty_fd) < 0) {
170 1.1 jtc warningf(FALSE, "j_ttyinit: can't set close-on-exec flag: %s",
171 1.1 jtc strerror(errno));
172 1.1 jtc close(tty_fd);
173 1.1 jtc tty_fd = -1;
174 1.1 jtc } else if (init_ttystate)
175 1.1 jtc get_tty(tty_fd, &tty_state);
176 1.1 jtc if (do_close)
177 1.1 jtc close(tfd);
178 1.1 jtc }
179 1.1 jtc
180 1.1 jtc void
181 1.1 jtc tty_close()
182 1.1 jtc {
183 1.1 jtc if (tty_fd >= 0) {
184 1.1 jtc close(tty_fd);
185 1.1 jtc tty_fd = -1;
186 1.1 jtc }
187 1.1 jtc }
188