xref: /openbsd-src/regress/sys/kern/pledge/generic/pty.c (revision 7a7077c028cf38d6f086fdf15b487a0ad276c621)
1 /*	$OpenBSD: pty.c,v 1.1 2024/06/03 08:02:22 anton Exp $	*/
2 
3 #include <sys/ioctl.h>
4 
5 #include <err.h>
6 #include <fcntl.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 
10 #include "pty.h"
11 
12 int
pty_open(struct pty * pty)13 pty_open(struct pty *pty)
14 {
15 	int master, slave;
16 
17 	master = posix_openpt(O_RDWR);
18 	if (master == -1) {
19 		warn("posix_openpt");
20 		return 1;
21 	}
22 	if (grantpt(master) == -1) {
23 		warn("grantpt");
24 		return 1;
25 	}
26 	if (unlockpt(master) == -1) {
27 		warn("unlockpt");
28 		return 1;
29 	}
30 
31 	slave = open(ptsname(master), O_RDWR);
32 	if (slave == -1) {
33 		warn("%s", ptsname(master));
34 		return 1;
35 	}
36 
37 	pty->master = master;
38 	pty->slave = slave;
39 	return 0;
40 }
41 
42 void
pty_close(struct pty * pty)43 pty_close(struct pty *pty)
44 {
45 	close(pty->slave);
46 	close(pty->master);
47 }
48 
49 /*
50  * Disconnect the controlling tty, if present.
51  */
52 int
pty_detach(struct pty * pty)53 pty_detach(struct pty *pty)
54 {
55 	int fd;
56 
57 	fd = open("/dev/tty", O_RDWR | O_NOCTTY);
58 	if (fd >= 0) {
59 		(void)ioctl(fd, TIOCNOTTY, NULL);
60 		close(fd);
61 	}
62 	return 0;
63 }
64 
65 /*
66  * Connect the slave as the controlling tty.
67  */
68 int
pty_attach(struct pty * pty)69 pty_attach(struct pty *pty)
70 {
71 	if (ioctl(pty->slave, TIOCSCTTY, NULL) == -1) {
72 		warn("TIOCSCTTY");
73 		return 1;
74 	}
75 	return 0;
76 }
77 
78 int
pty_drain(struct pty * pty)79 pty_drain(struct pty *pty)
80 {
81 	for (;;) {
82 		char *buf = &pty->buf.storage[pty->buf.len];
83 		size_t bufsize = sizeof(pty->buf.storage) - pty->buf.len;
84 		ssize_t n;
85 
86 		n = read(pty->master, buf, bufsize);
87 		if (n == -1) {
88 			warn("read");
89 			return 1;
90 		}
91 		if (n == 0)
92 			break;
93 
94 		/* Ensure space for NUL-terminator. */
95 		if ((size_t)n >= bufsize) {
96 			warnx("pty buffer too small");
97 			return 1;
98 		}
99 		pty->buf.len += n;
100 	}
101 
102 	return 0;
103 }
104