xref: /aosp_15_r20/external/liburing/test/stdout.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker  * Description: check that STDOUT write works
4*25da2beaSAndroid Build Coastguard Worker  */
5*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
6*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
7*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
8*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
9*25da2beaSAndroid Build Coastguard Worker #include <string.h>
10*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
11*25da2beaSAndroid Build Coastguard Worker 
12*25da2beaSAndroid Build Coastguard Worker #include "helpers.h"
13*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
14*25da2beaSAndroid Build Coastguard Worker 
test_pipe_io_fixed(struct io_uring * ring)15*25da2beaSAndroid Build Coastguard Worker static int test_pipe_io_fixed(struct io_uring *ring)
16*25da2beaSAndroid Build Coastguard Worker {
17*25da2beaSAndroid Build Coastguard Worker 	const char str[] = "This is a fixed pipe test\n";
18*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
19*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
20*25da2beaSAndroid Build Coastguard Worker 	struct iovec vecs[2];
21*25da2beaSAndroid Build Coastguard Worker 	char buffer[128];
22*25da2beaSAndroid Build Coastguard Worker 	int i, ret, fds[2];
23*25da2beaSAndroid Build Coastguard Worker 
24*25da2beaSAndroid Build Coastguard Worker 	t_posix_memalign(&vecs[0].iov_base, 4096, 4096);
25*25da2beaSAndroid Build Coastguard Worker 	memcpy(vecs[0].iov_base, str, strlen(str));
26*25da2beaSAndroid Build Coastguard Worker 	vecs[0].iov_len = strlen(str);
27*25da2beaSAndroid Build Coastguard Worker 
28*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds) < 0) {
29*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
30*25da2beaSAndroid Build Coastguard Worker 		return 1;
31*25da2beaSAndroid Build Coastguard Worker 	}
32*25da2beaSAndroid Build Coastguard Worker 
33*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buffers(ring, vecs, 1);
34*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
35*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Failed to register buffers: %d\n", ret);
36*25da2beaSAndroid Build Coastguard Worker 		return 1;
37*25da2beaSAndroid Build Coastguard Worker 	}
38*25da2beaSAndroid Build Coastguard Worker 
39*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
40*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
41*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
42*25da2beaSAndroid Build Coastguard Worker 		goto err;
43*25da2beaSAndroid Build Coastguard Worker 	}
44*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_write_fixed(sqe, fds[1], vecs[0].iov_base,
45*25da2beaSAndroid Build Coastguard Worker 					vecs[0].iov_len, 0, 0);
46*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
47*25da2beaSAndroid Build Coastguard Worker 
48*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
49*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
50*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
51*25da2beaSAndroid Build Coastguard Worker 		goto err;
52*25da2beaSAndroid Build Coastguard Worker 	}
53*25da2beaSAndroid Build Coastguard Worker 	vecs[1].iov_base = buffer;
54*25da2beaSAndroid Build Coastguard Worker 	vecs[1].iov_len = sizeof(buffer);
55*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_readv(sqe, fds[0], &vecs[1], 1, 0);
56*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
57*25da2beaSAndroid Build Coastguard Worker 
58*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
59*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
60*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
61*25da2beaSAndroid Build Coastguard Worker 		goto err;
62*25da2beaSAndroid Build Coastguard Worker 	} else if (ret != 2) {
63*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Submitted only %d\n", ret);
64*25da2beaSAndroid Build Coastguard Worker 		goto err;
65*25da2beaSAndroid Build Coastguard Worker 	}
66*25da2beaSAndroid Build Coastguard Worker 
67*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
68*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
69*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
70*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait completion %d\n", ret);
71*25da2beaSAndroid Build Coastguard Worker 			goto err;
72*25da2beaSAndroid Build Coastguard Worker 		}
73*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res < 0) {
74*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "I/O write error on %lu: %s\n",
75*25da2beaSAndroid Build Coastguard Worker 					(unsigned long) cqe->user_data,
76*25da2beaSAndroid Build Coastguard Worker 					 strerror(-cqe->res));
77*25da2beaSAndroid Build Coastguard Worker 			goto err;
78*25da2beaSAndroid Build Coastguard Worker 		}
79*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res != strlen(str)) {
80*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "Got %d bytes, wanted %d on %lu\n",
81*25da2beaSAndroid Build Coastguard Worker 					cqe->res, (int)strlen(str),
82*25da2beaSAndroid Build Coastguard Worker 					(unsigned long) cqe->user_data);
83*25da2beaSAndroid Build Coastguard Worker 			goto err;
84*25da2beaSAndroid Build Coastguard Worker 		}
85*25da2beaSAndroid Build Coastguard Worker 		if (cqe->user_data == 2 && memcmp(str, buffer, strlen(str))) {
86*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "read data mismatch\n");
87*25da2beaSAndroid Build Coastguard Worker 			goto err;
88*25da2beaSAndroid Build Coastguard Worker 		}
89*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
90*25da2beaSAndroid Build Coastguard Worker 	}
91*25da2beaSAndroid Build Coastguard Worker 	io_uring_unregister_buffers(ring);
92*25da2beaSAndroid Build Coastguard Worker 	return 0;
93*25da2beaSAndroid Build Coastguard Worker err:
94*25da2beaSAndroid Build Coastguard Worker 	return 1;
95*25da2beaSAndroid Build Coastguard Worker }
96*25da2beaSAndroid Build Coastguard Worker 
test_stdout_io_fixed(struct io_uring * ring)97*25da2beaSAndroid Build Coastguard Worker static int test_stdout_io_fixed(struct io_uring *ring)
98*25da2beaSAndroid Build Coastguard Worker {
99*25da2beaSAndroid Build Coastguard Worker 	const char str[] = "This is a fixed pipe test\n";
100*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
101*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
102*25da2beaSAndroid Build Coastguard Worker 	struct iovec vecs;
103*25da2beaSAndroid Build Coastguard Worker 	int ret;
104*25da2beaSAndroid Build Coastguard Worker 
105*25da2beaSAndroid Build Coastguard Worker 	t_posix_memalign(&vecs.iov_base, 4096, 4096);
106*25da2beaSAndroid Build Coastguard Worker 	memcpy(vecs.iov_base, str, strlen(str));
107*25da2beaSAndroid Build Coastguard Worker 	vecs.iov_len = strlen(str);
108*25da2beaSAndroid Build Coastguard Worker 
109*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buffers(ring, &vecs, 1);
110*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
111*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Failed to register buffers: %d\n", ret);
112*25da2beaSAndroid Build Coastguard Worker 		return 1;
113*25da2beaSAndroid Build Coastguard Worker 	}
114*25da2beaSAndroid Build Coastguard Worker 
115*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
116*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
117*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
118*25da2beaSAndroid Build Coastguard Worker 		goto err;
119*25da2beaSAndroid Build Coastguard Worker 	}
120*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_write_fixed(sqe, STDOUT_FILENO, vecs.iov_base, vecs.iov_len, 0, 0);
121*25da2beaSAndroid Build Coastguard Worker 
122*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
123*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
124*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
125*25da2beaSAndroid Build Coastguard Worker 		goto err;
126*25da2beaSAndroid Build Coastguard Worker 	} else if (ret < 1) {
127*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Submitted only %d\n", ret);
128*25da2beaSAndroid Build Coastguard Worker 		goto err;
129*25da2beaSAndroid Build Coastguard Worker 	}
130*25da2beaSAndroid Build Coastguard Worker 
131*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
132*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
133*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait completion %d\n", ret);
134*25da2beaSAndroid Build Coastguard Worker 		goto err;
135*25da2beaSAndroid Build Coastguard Worker 	}
136*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res < 0) {
137*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "STDOUT write error: %s\n", strerror(-cqe->res));
138*25da2beaSAndroid Build Coastguard Worker 		goto err;
139*25da2beaSAndroid Build Coastguard Worker 	}
140*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res != vecs.iov_len) {
141*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Got %d write, wanted %d\n", cqe->res, (int)vecs.iov_len);
142*25da2beaSAndroid Build Coastguard Worker 		goto err;
143*25da2beaSAndroid Build Coastguard Worker 	}
144*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
145*25da2beaSAndroid Build Coastguard Worker 	io_uring_unregister_buffers(ring);
146*25da2beaSAndroid Build Coastguard Worker 	return 0;
147*25da2beaSAndroid Build Coastguard Worker err:
148*25da2beaSAndroid Build Coastguard Worker 	return 1;
149*25da2beaSAndroid Build Coastguard Worker }
150*25da2beaSAndroid Build Coastguard Worker 
test_stdout_io(struct io_uring * ring)151*25da2beaSAndroid Build Coastguard Worker static int test_stdout_io(struct io_uring *ring)
152*25da2beaSAndroid Build Coastguard Worker {
153*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
154*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
155*25da2beaSAndroid Build Coastguard Worker 	struct iovec vecs;
156*25da2beaSAndroid Build Coastguard Worker 	int ret;
157*25da2beaSAndroid Build Coastguard Worker 
158*25da2beaSAndroid Build Coastguard Worker 	vecs.iov_base = "This is a pipe test\n";
159*25da2beaSAndroid Build Coastguard Worker 	vecs.iov_len = strlen(vecs.iov_base);
160*25da2beaSAndroid Build Coastguard Worker 
161*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
162*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
163*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
164*25da2beaSAndroid Build Coastguard Worker 		goto err;
165*25da2beaSAndroid Build Coastguard Worker 	}
166*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_writev(sqe, STDOUT_FILENO, &vecs, 1, 0);
167*25da2beaSAndroid Build Coastguard Worker 
168*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
169*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
170*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
171*25da2beaSAndroid Build Coastguard Worker 		goto err;
172*25da2beaSAndroid Build Coastguard Worker 	} else if (ret < 1) {
173*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Submitted only %d\n", ret);
174*25da2beaSAndroid Build Coastguard Worker 		goto err;
175*25da2beaSAndroid Build Coastguard Worker 	}
176*25da2beaSAndroid Build Coastguard Worker 
177*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
178*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
179*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait completion %d\n", ret);
180*25da2beaSAndroid Build Coastguard Worker 		goto err;
181*25da2beaSAndroid Build Coastguard Worker 	}
182*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res < 0) {
183*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "STDOUT write error: %s\n",
184*25da2beaSAndroid Build Coastguard Worker 				strerror(-cqe->res));
185*25da2beaSAndroid Build Coastguard Worker 		goto err;
186*25da2beaSAndroid Build Coastguard Worker 	}
187*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res != vecs.iov_len) {
188*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Got %d write, wanted %d\n", cqe->res,
189*25da2beaSAndroid Build Coastguard Worker 				(int)vecs.iov_len);
190*25da2beaSAndroid Build Coastguard Worker 		goto err;
191*25da2beaSAndroid Build Coastguard Worker 	}
192*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
193*25da2beaSAndroid Build Coastguard Worker 
194*25da2beaSAndroid Build Coastguard Worker 	return 0;
195*25da2beaSAndroid Build Coastguard Worker err:
196*25da2beaSAndroid Build Coastguard Worker 	return 1;
197*25da2beaSAndroid Build Coastguard Worker }
198*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])199*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
200*25da2beaSAndroid Build Coastguard Worker {
201*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
202*25da2beaSAndroid Build Coastguard Worker 	int ret;
203*25da2beaSAndroid Build Coastguard Worker 
204*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
205*25da2beaSAndroid Build Coastguard Worker 		return 0;
206*25da2beaSAndroid Build Coastguard Worker 
207*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
208*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
209*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring setup failed\n");
210*25da2beaSAndroid Build Coastguard Worker 		return 1;
211*25da2beaSAndroid Build Coastguard Worker 	}
212*25da2beaSAndroid Build Coastguard Worker 
213*25da2beaSAndroid Build Coastguard Worker 	ret = test_stdout_io(&ring);
214*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
215*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_pipe_io failed\n");
216*25da2beaSAndroid Build Coastguard Worker 		return ret;
217*25da2beaSAndroid Build Coastguard Worker 	}
218*25da2beaSAndroid Build Coastguard Worker 
219*25da2beaSAndroid Build Coastguard Worker 	ret = test_stdout_io_fixed(&ring);
220*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
221*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_pipe_io_fixed failed\n");
222*25da2beaSAndroid Build Coastguard Worker 		return ret;
223*25da2beaSAndroid Build Coastguard Worker 	}
224*25da2beaSAndroid Build Coastguard Worker 
225*25da2beaSAndroid Build Coastguard Worker 	ret = test_pipe_io_fixed(&ring);
226*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
227*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_pipe_io_fixed failed\n");
228*25da2beaSAndroid Build Coastguard Worker 		return ret;
229*25da2beaSAndroid Build Coastguard Worker 	}
230*25da2beaSAndroid Build Coastguard Worker 
231*25da2beaSAndroid Build Coastguard Worker 	return 0;
232*25da2beaSAndroid Build Coastguard Worker }
233