1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Description: test io_uring mkdirat handling
4 */
5 #include <fcntl.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11
12 #include "liburing.h"
13
do_mkdirat(struct io_uring * ring,const char * fn)14 static int do_mkdirat(struct io_uring *ring, const char *fn)
15 {
16 int ret;
17 struct io_uring_sqe *sqe;
18 struct io_uring_cqe *cqe;
19
20 sqe = io_uring_get_sqe(ring);
21 if (!sqe) {
22 fprintf(stderr, "sqe get failed\n");
23 goto err;
24 }
25 io_uring_prep_mkdirat(sqe, AT_FDCWD, fn, 0700);
26
27 ret = io_uring_submit(ring);
28 if (ret != 1) {
29 fprintf(stderr, "submit failed: %d\n", ret);
30 goto err;
31 }
32
33 ret = io_uring_wait_cqes(ring, &cqe, 1, 0, 0);
34 if (ret) {
35 fprintf(stderr, "wait_cqe failed: %d\n", ret);
36 goto err;
37 }
38 ret = cqe->res;
39 io_uring_cqe_seen(ring, cqe);
40 return ret;
41 err:
42 return 1;
43 }
44
stat_file(const char * fn)45 static int stat_file(const char *fn)
46 {
47 struct stat sb;
48
49 if (!stat(fn, &sb))
50 return 0;
51
52 return errno;
53 }
54
main(int argc,char * argv[])55 int main(int argc, char *argv[])
56 {
57 static const char fn[] = "io_uring-mkdirat-test";
58 int ret;
59 struct io_uring ring;
60
61 ret = io_uring_queue_init(8, &ring, 0);
62 if (ret) {
63 fprintf(stderr, "queue init failed: %d\n", ret);
64 return ret;
65 }
66
67 ret = do_mkdirat(&ring, fn);
68 if (ret < 0) {
69 if (ret == -EBADF || ret == -EINVAL) {
70 fprintf(stdout, "mkdirat not supported, skipping\n");
71 goto out;
72 }
73 fprintf(stderr, "mkdirat: %s\n", strerror(-ret));
74 goto err;
75 } else if (ret) {
76 goto err;
77 }
78
79 if (stat_file(fn)) {
80 perror("stat");
81 goto err;
82 }
83
84 ret = do_mkdirat(&ring, fn);
85 if (ret != -EEXIST) {
86 fprintf(stderr, "do_mkdirat already exists failed: %d\n", ret);
87 goto err1;
88 }
89
90 ret = do_mkdirat(&ring, "surely/this/wont/exist");
91 if (ret != -ENOENT) {
92 fprintf(stderr, "do_mkdirat no parent failed: %d\n", ret);
93 goto err1;
94 }
95
96 out:
97 unlinkat(AT_FDCWD, fn, AT_REMOVEDIR);
98 io_uring_queue_exit(&ring);
99 return 0;
100 err1:
101 unlinkat(AT_FDCWD, fn, AT_REMOVEDIR);
102 err:
103 io_uring_queue_exit(&ring);
104 return 1;
105 }
106