oksh-noxz

[fork] Portable OpenBSD ksh, based on the Public Domain Korn Shell (pdksh).
git clone https://noxz.tech/git/oksh-noxz.git
Log | Files | Tags

tty.c
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
11int		tty_fd = -1;	/* dup'd tty file descriptor */
12int		tty_devtty;	/* true if tty_fd is from /dev/tty */
13struct termios	tty_state;	/* saved tty state */
14
15void
16tty_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 */
27void
28tty_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#ifdef F_DUPFD_CLOEXEC
53	if ((tty_fd = fcntl(tfd, F_DUPFD_CLOEXEC, FDBASE)) == -1) {
54		warningf(false, "%s: dup of tty fd failed: %s",
55		    __func__, strerror(errno));
56#else
57	if ((tty_fd = fcntl(tfd, F_DUPFD, FDBASE)) == -1) {
58		warningf(false, "%s: dup of tty fd failed: %s",
59		    __func__, strerror(errno));
60	} else if (fcntl(tty_fd, F_SETFD, FD_CLOEXEC) == -1) {
61		warningf(false, "%s: set tty fd close-on-exec flag failed: %s",
62		    __func__, strerror(errno));
63		close(tty_fd);
64		tty_fd = -1;
65#endif
66	} else if (init_ttystate)
67		tcgetattr(tty_fd, &tty_state);
68	if (do_close)
69		close(tfd);
70}