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