1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/* $OpenBSD: kqueue-pty.c,v 1.2 2003/06/12 05:08:51 mickey Exp $ */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/event.h>
#include <stdio.h>
#include <unistd.h>
#include <util.h>
#include <termios.h>
#include <fcntl.h>
#include <err.h>
int
pty_check(int kq, struct kevent *ev, int n, int rm, int rs, int wm, int ws)
{
struct timespec ts;
int i;
ts.tv_sec = 0;
ts.tv_nsec = 0;
if ((n = kevent(kq, NULL, 0, ev, n, &ts)) < 0)
err(1, "slave: kevent");
if (n == 0)
return (1);
for (i = 0; i < n; i++, ev++) {
if (ev->filter == EVFILT_READ) {
if (rm < 0 && ev->ident == -rm)
return (1);
if (rs < 0 && ev->ident == -rs)
return (1);
} else if (ev->filter == EVFILT_WRITE) {
if (wm < 0 && ev->ident == -wm)
return (1);
if (ws < 0 && ev->ident == -ws)
return (1);
} else
errx(1, "unknown event");
}
return (0);
}
int
do_pty(void)
{
struct kevent ev[4];
struct termios tt;
int kq, massa, slave;
char buf[1024];
tcgetattr(STDIN_FILENO, &tt);
cfmakeraw(&tt);
tt.c_lflag &= ~ECHO;
if (openpty(&massa, &slave, NULL, &tt, NULL) < 0)
err(1, "openpty");
if (fcntl(massa, F_SETFL, O_NONBLOCK) < 0)
err(1, "massa: fcntl");
if (fcntl(slave, F_SETFL, O_NONBLOCK) < 0)
err(1, "massa: fcntl");
if ((kq = kqueue()) == -1)
err(1, "kqueue");
/* test the read from the slave works */
EV_SET(&ev[0], massa, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, NULL);
EV_SET(&ev[1], massa, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, NULL);
EV_SET(&ev[2], slave, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, NULL);
EV_SET(&ev[3], slave, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, NULL);
if (kevent(kq, ev, 4, NULL, 0, NULL) < 0)
err(1, "slave: kevent add");
if (write(massa, " ", 1) != 1)
err(1, "massa: write");
if (pty_check(kq, ev, 4, -massa, slave, massa, slave))
return (1);
read(slave, buf, sizeof(buf));
if (pty_check(kq, ev, 4, -massa, -slave, massa, slave))
return (1);
while (write(massa, buf, sizeof(buf)) > 0);
if (pty_check(kq, ev, 4, -massa, slave, -massa, slave))
return (1);
read(slave, buf, 1);
if (pty_check(kq, ev, 4, -massa, slave, massa, slave))
return (1);
while (read(slave, buf, sizeof(buf)) > 0);
if (pty_check(kq, ev, 4, -massa, -slave, massa, slave))
return (1);
return (0);
}
|