t_pr.c revision 1.6 1 1.6 martin /* $NetBSD: t_pr.c,v 1.6 2011/04/26 18:50:53 martin Exp $ */
2 1.1 pooka
3 1.1 pooka #include <sys/types.h>
4 1.1 pooka #include <sys/ioctl.h>
5 1.1 pooka #include <sys/tty.h>
6 1.1 pooka
7 1.1 pooka #include <atf-c.h>
8 1.1 pooka #include <fcntl.h>
9 1.1 pooka
10 1.5 martin #include <stdio.h>
11 1.5 martin #include <string.h>
12 1.5 martin #include <errno.h>
13 1.1 pooka #include <rump/rump.h>
14 1.1 pooka #include <rump/rump_syscalls.h>
15 1.1 pooka
16 1.5 martin static int
17 1.5 martin sendsome(int from, int to)
18 1.5 martin {
19 1.5 martin size_t i;
20 1.5 martin ssize_t cnt;
21 1.5 martin static const char msg[] = "hello world\n";
22 1.5 martin char buf[sizeof(msg)+10];
23 1.5 martin
24 1.5 martin memset(buf, 0, sizeof(buf));
25 1.5 martin rump_sys_write(from, msg, strlen(msg));
26 1.5 martin cnt = rump_sys_read(to, buf, sizeof(buf));
27 1.5 martin if (cnt < (ssize_t)strlen(msg)) {
28 1.5 martin printf("short message read: %zd chars: \"%s\"\n", cnt, buf);
29 1.5 martin return 1;
30 1.5 martin }
31 1.5 martin for (i = 0; i < sizeof(buf); i++) {
32 1.5 martin if (buf[i] == '\r' || buf[i] == '\n') {
33 1.5 martin buf[i] = '\n';
34 1.5 martin buf[i+1] = '\0';
35 1.5 martin break;
36 1.5 martin }
37 1.5 martin }
38 1.5 martin
39 1.5 martin return strcmp(buf, msg) != 0;
40 1.5 martin }
41 1.5 martin
42 1.5 martin static int
43 1.5 martin exercise_ptytty(int master, int slave)
44 1.5 martin {
45 1.5 martin int error, flags;
46 1.5 martin
47 1.5 martin /*
48 1.5 martin * send a few bytes from master to slave and read them back
49 1.5 martin */
50 1.5 martin error = sendsome(master, slave);
51 1.5 martin if (error)
52 1.5 martin return error;
53 1.5 martin
54 1.5 martin flags = FREAD|FWRITE;
55 1.5 martin rump_sys_ioctl(master, TIOCFLUSH, &flags);
56 1.5 martin
57 1.5 martin /*
58 1.5 martin * and the same in the other direction
59 1.5 martin */
60 1.5 martin error = sendsome(slave, master);
61 1.5 martin if (error)
62 1.5 martin return error;
63 1.5 martin
64 1.5 martin flags = FREAD|FWRITE;
65 1.5 martin rump_sys_ioctl(master, TIOCFLUSH, &flags);
66 1.5 martin return 0;
67 1.5 martin }
68 1.5 martin
69 1.5 martin ATF_TC(client_first);
70 1.5 martin ATF_TC_HEAD(client_first, tc)
71 1.5 martin {
72 1.5 martin
73 1.5 martin atf_tc_set_md_var(tc, "descr",
74 1.5 martin "test basic tty/pty operation when opening client side first");
75 1.5 martin }
76 1.5 martin
77 1.5 martin ATF_TC_BODY(client_first, tc)
78 1.5 martin {
79 1.5 martin int master, slave, error, v;
80 1.5 martin
81 1.6 martin rump_init();
82 1.5 martin slave = rump_sys_open("/dev/ttyp1", O_RDWR|O_NONBLOCK);
83 1.5 martin ATF_CHECK(slave != -1);
84 1.5 martin
85 1.5 martin master = rump_sys_open("/dev/ptyp1", O_RDWR);
86 1.5 martin ATF_CHECK(master != -1);
87 1.5 martin
88 1.5 martin v = 0;
89 1.5 martin rump_sys_ioctl(slave, FIOASYNC, &v);
90 1.5 martin error = exercise_ptytty(master, slave);
91 1.5 martin ATF_CHECK(error == 0);
92 1.5 martin
93 1.5 martin rump_sys_close(master);
94 1.5 martin rump_sys_close(slave);
95 1.5 martin }
96 1.5 martin
97 1.5 martin ATF_TC(master_first);
98 1.5 martin ATF_TC_HEAD(master_first, tc)
99 1.5 martin {
100 1.5 martin
101 1.5 martin atf_tc_set_md_var(tc, "descr",
102 1.5 martin "test basic tty/pty operation when opening master side first");
103 1.5 martin }
104 1.5 martin
105 1.5 martin ATF_TC_BODY(master_first, tc)
106 1.5 martin {
107 1.5 martin int master, slave, error;
108 1.5 martin
109 1.6 martin rump_init();
110 1.5 martin master = rump_sys_open("/dev/ptyp1", O_RDWR);
111 1.5 martin ATF_CHECK(master != -1);
112 1.5 martin
113 1.5 martin slave = rump_sys_open("/dev/ttyp1", O_RDWR);
114 1.5 martin ATF_CHECK(slave != -1);
115 1.5 martin
116 1.5 martin error = exercise_ptytty(master, slave);
117 1.5 martin ATF_CHECK(error == 0);
118 1.5 martin
119 1.5 martin rump_sys_close(master);
120 1.5 martin rump_sys_close(slave);
121 1.5 martin }
122 1.5 martin
123 1.1 pooka ATF_TC(ptyioctl);
124 1.1 pooka ATF_TC_HEAD(ptyioctl, tc)
125 1.1 pooka {
126 1.1 pooka
127 1.5 martin atf_tc_set_md_var(tc, "descr",
128 1.5 martin "ioctl on pty with client side not open");
129 1.1 pooka }
130 1.1 pooka
131 1.1 pooka ATF_TC_BODY(ptyioctl, tc)
132 1.1 pooka {
133 1.1 pooka struct termios tio;
134 1.1 pooka int fd;
135 1.1 pooka
136 1.6 martin rump_init();
137 1.1 pooka fd = rump_sys_open("/dev/ptyp1", O_RDWR);
138 1.3 christos ATF_CHECK(fd != -1);
139 1.1 pooka
140 1.4 martin /*
141 1.4 martin * This used to die with null deref under ptcwakeup()
142 1.4 martin * atf_tc_expect_signal(-1, "PR kern/40688");
143 1.4 martin */
144 1.1 pooka rump_sys_ioctl(fd, TIOCGETA, &tio);
145 1.5 martin
146 1.5 martin rump_sys_close(fd);
147 1.1 pooka }
148 1.1 pooka
149 1.1 pooka ATF_TP_ADD_TCS(tp)
150 1.1 pooka {
151 1.1 pooka
152 1.1 pooka ATF_TP_ADD_TC(tp, ptyioctl);
153 1.5 martin ATF_TP_ADD_TC(tp, client_first);
154 1.5 martin ATF_TP_ADD_TC(tp, master_first);
155 1.1 pooka
156 1.1 pooka return atf_no_error();
157 1.1 pooka }
158