xref: /openbsd-src/bin/ksh/tty.c (revision b7041c0781c8668129da8084451ded41b0c43954)
1*b7041c07Sderaadt /*	$OpenBSD: tty.c,v 1.19 2021/10/24 21:24:21 deraadt Exp $	*/
256018212Smmcc 
34a010e0cStb #include <errno.h>
44a010e0cStb #include <fcntl.h>
556018212Smmcc #include <string.h>
64a010e0cStb #include <unistd.h>
77cb960a2Sdownsj 
87cb960a2Sdownsj #include "sh.h"
97cb960a2Sdownsj #include "tty.h"
10891a519fSnicm 
11891a519fSnicm int		tty_fd = -1;	/* dup'd tty file descriptor */
12891a519fSnicm int		tty_devtty;	/* true if tty_fd is from /dev/tty */
13891a519fSnicm struct termios	tty_state;	/* saved tty state */
147cb960a2Sdownsj 
15259612a2Stedu void
tty_close(void)16259612a2Stedu tty_close(void)
17259612a2Stedu {
18259612a2Stedu 	if (tty_fd >= 0) {
19259612a2Stedu 		close(tty_fd);
20259612a2Stedu 		tty_fd = -1;
21259612a2Stedu 	}
22259612a2Stedu }
23259612a2Stedu 
240ddc292aSmmcc /* Initialize tty_fd.  Used for saving/resetting tty modes upon
257cb960a2Sdownsj  * foreground job completion and for setting up tty process group.
267cb960a2Sdownsj  */
277cb960a2Sdownsj void
tty_init(int init_ttystate)28c5d5393cSotto tty_init(int init_ttystate)
297cb960a2Sdownsj {
307cb960a2Sdownsj 	int	do_close = 1;
317cb960a2Sdownsj 	int	tfd;
327cb960a2Sdownsj 
33259612a2Stedu 	tty_close();
347cb960a2Sdownsj 	tty_devtty = 1;
357cb960a2Sdownsj 
36*b7041c07Sderaadt 	tfd = open("/dev/tty", O_RDWR);
373aaa63ebSderaadt 	if (tfd == -1) {
387cb960a2Sdownsj 		tty_devtty = 0;
39c3a8e039Sderaadt 		warningf(false, "No controlling tty (open /dev/tty: %s)",
407cb960a2Sdownsj 		    strerror(errno));
417cb960a2Sdownsj 
427cb960a2Sdownsj 		do_close = 0;
437cb960a2Sdownsj 		if (isatty(0))
447cb960a2Sdownsj 			tfd = 0;
457cb960a2Sdownsj 		else if (isatty(2))
467cb960a2Sdownsj 			tfd = 2;
477cb960a2Sdownsj 		else {
480e7d3a01Smillert 			warningf(false, "Can't find tty file descriptor");
497cb960a2Sdownsj 			return;
507cb960a2Sdownsj 		}
517cb960a2Sdownsj 	}
523aaa63ebSderaadt 	if ((tty_fd = fcntl(tfd, F_DUPFD_CLOEXEC, FDBASE)) == -1) {
5397445c82Santon 		warningf(false, "%s: dup of tty fd failed: %s",
5497445c82Santon 		    __func__, strerror(errno));
557cb960a2Sdownsj 	} else if (init_ttystate)
5669dc5d70Smillert 		tcgetattr(tty_fd, &tty_state);
577cb960a2Sdownsj 	if (do_close)
587cb960a2Sdownsj 		close(tfd);
597cb960a2Sdownsj }
60