1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Test fixed buffers with non-iterators.
4 *
5 * Taken from: https://github.com/axboe/liburing/issues/549
6 */
7 #include <stdio.h>
8 #include <string.h>
9 #include <fcntl.h>
10 #include <stdlib.h>
11
12 #include "liburing.h"
13 #include "helpers.h"
14
15 #define BUF_SIZE 4096
16 #define BUFFERS 1
17 #define IN_FD "/dev/urandom"
18 #define OUT_FD "/dev/zero"
19
test(struct io_uring * ring)20 static int test(struct io_uring *ring)
21 {
22 struct iovec iov[BUFFERS];
23 struct io_uring_sqe *sqe;
24 struct io_uring_cqe *cqe;
25 int ret, fd_in, fd_out, i;
26
27 fd_in = open(IN_FD, O_RDONLY, 0644);
28 if (fd_in < 0) {
29 perror("open in");
30 return 1;
31 }
32
33 fd_out = open(OUT_FD, O_RDWR, 0644);
34 if (fd_out < 0) {
35 perror("open out");
36 return 1;
37 }
38
39 for (i = 0; i < BUFFERS; i++) {
40 iov[i].iov_base = malloc(BUF_SIZE);
41 iov[i].iov_len = BUF_SIZE;
42 memset(iov[i].iov_base, 0, BUF_SIZE);
43 }
44
45 ret = io_uring_register_buffers(ring, iov, BUFFERS);
46 if (ret) {
47 fprintf(stderr, "Error registering buffers: %s", strerror(-ret));
48 return 1;
49 }
50
51 sqe = io_uring_get_sqe(ring);
52 if (!sqe) {
53 fprintf(stderr, "Could not get SQE.\n");
54 return 1;
55 }
56
57 io_uring_prep_read_fixed(sqe, fd_in, iov[0].iov_base, BUF_SIZE, 0, 0);
58 io_uring_submit(ring);
59
60 ret = io_uring_wait_cqe(ring, &cqe);
61 if (ret < 0) {
62 fprintf(stderr, "Error waiting for completion: %s\n", strerror(-ret));
63 return 1;
64 }
65
66 if (cqe->res < 0) {
67 fprintf(stderr, "Error in async operation: %s\n", strerror(-cqe->res));
68 return 1;
69 }
70 io_uring_cqe_seen(ring, cqe);
71
72 sqe = io_uring_get_sqe(ring);
73 if (!sqe) {
74 fprintf(stderr, "Could not get SQE.\n");
75 return 1;
76 }
77 io_uring_prep_write_fixed(sqe, fd_out, iov[0].iov_base, BUF_SIZE, 0, 0);
78 io_uring_submit(ring);
79
80 ret = io_uring_wait_cqe(ring, &cqe);
81 if (ret < 0) {
82 fprintf(stderr, "Error waiting for completion: %s\n", strerror(-ret));
83 return 1;
84 }
85 if (cqe->res < 0) {
86 fprintf(stderr, "Error in async operation: %s\n", strerror(-cqe->res));
87 return 1;
88 }
89 io_uring_cqe_seen(ring, cqe);
90 return 0;
91 }
92
main(int argc,char * argv[])93 int main(int argc, char *argv[])
94 {
95 struct io_uring ring;
96 int ret;
97
98 if (argc > 1)
99 return 0;
100
101 ret = t_create_ring(8, &ring, 0);
102 if (ret == T_SETUP_SKIP)
103 return 0;
104 else if (ret < 0)
105 return 1;
106
107 ret = test(&ring);
108 if (ret) {
109 fprintf(stderr, "Test failed\n");
110 return 1;
111 }
112
113 io_uring_queue_exit(&ring);
114 return 0;
115 }
116