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