tty.c revision 1.3 1 /* $NetBSD: tty.c,v 1.3 1998/04/07 10:29:50 fair 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 const char *devtty = _PATH_TTY;
108
109 if (tty_fd >= 0) {
110 close(tty_fd);
111 tty_fd = -1;
112 }
113 tty_devtty = 1;
114
115 /* SCO can't job control on /dev/tty, so don't try... */
116 #if !defined(__SCO__)
117 if ((tfd = open(devtty, O_RDWR, 0)) < 0) {
118 #ifdef __NeXT
119 /* rlogin on NeXT boxes does not set up the controlling tty,
120 * so force it to be done here...
121 */
122 {
123 extern char *ttyname ARGS((int));
124 char *s = ttyname(isatty(2) ? 2 : 0);
125 int fd;
126
127 if (s && (fd = open(s, O_RDWR, 0)) >= 0) {
128 close(fd);
129 tfd = open(devtty, O_RDWR, 0);
130 }
131 }
132 #endif /* __NeXT */
133
134 /* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */
135 # if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
136 if (tfd < 0) {
137 tty_devtty = 0;
138 warningf(FALSE,
139 "No controlling tty (open %s: %s)",
140 devtty, strerror(errno));
141 }
142 # endif /* __mips */
143 }
144 #else /* !__SCO__ */
145 tfd = -1;
146 #endif /* __SCO__ */
147
148 if (tfd < 0) {
149 do_close = 0;
150 if (isatty(0))
151 tfd = 0;
152 else if (isatty(2))
153 tfd = 2;
154 else {
155 warningf(FALSE, "Can't find tty file descriptor");
156 return;
157 }
158 }
159 if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
160 warningf(FALSE, "j_ttyinit: dup of tty fd failed: %s",
161 strerror(errno));
162 } else if (fd_clexec(tty_fd) < 0) {
163 warningf(FALSE, "j_ttyinit: can't set close-on-exec flag: %s",
164 strerror(errno));
165 close(tty_fd);
166 tty_fd = -1;
167 } else if (init_ttystate)
168 get_tty(tty_fd, &tty_state);
169 if (do_close)
170 close(tfd);
171 }
172
173 void
174 tty_close()
175 {
176 if (tty_fd >= 0) {
177 close(tty_fd);
178 tty_fd = -1;
179 }
180 }
181