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