xref: /openbsd/bin/ksh/tty.c (revision 891a519f)
1 /*	$OpenBSD: tty.c,v 1.12 2015/09/25 11:58:14 nicm Exp $	*/
2 
3 #include "sh.h"
4 #include <sys/stat.h>
5 #include "tty.h"
6 
7 int		tty_fd = -1;	/* dup'd tty file descriptor */
8 int		tty_devtty;	/* true if tty_fd is from /dev/tty */
9 struct termios	tty_state;	/* saved tty state */
10 
11 void
12 tty_close(void)
13 {
14 	if (tty_fd >= 0) {
15 		close(tty_fd);
16 		tty_fd = -1;
17 	}
18 }
19 
20 /* Initialize tty_fd.  Used for saving/reseting tty modes upon
21  * foreground job completion and for setting up tty process group.
22  */
23 void
24 tty_init(int init_ttystate)
25 {
26 	int	do_close = 1;
27 	int	tfd;
28 
29 	tty_close();
30 	tty_devtty = 1;
31 
32 	tfd = open("/dev/tty", O_RDWR, 0);
33 	if (tfd < 0) {
34 		tty_devtty = 0;
35 		warningf(false, "No controlling tty (open /dev/tty: %s)",
36 		    strerror(errno));
37 
38 		do_close = 0;
39 		if (isatty(0))
40 			tfd = 0;
41 		else if (isatty(2))
42 			tfd = 2;
43 		else {
44 			warningf(false, "Can't find tty file descriptor");
45 			return;
46 		}
47 	}
48 	if ((tty_fd = fcntl(tfd, F_DUPFD_CLOEXEC, FDBASE)) < 0) {
49 		warningf(false, "j_ttyinit: dup of tty fd failed: %s",
50 		    strerror(errno));
51 	} else if (init_ttystate)
52 		tcgetattr(tty_fd, &tty_state);
53 	if (do_close)
54 		close(tfd);
55 }
56