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