• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Description: run various rename tests
4  *
5  */
6 #include <errno.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <sys/stat.h>
13 
14 #include "liburing.h"
15 
16 /* test using a bad address for either old or new path */
test_rename_badaddr(struct io_uring * ring,bool bad_old)17 static int test_rename_badaddr(struct io_uring *ring, bool bad_old)
18 {
19 	struct io_uring_cqe *cqe;
20 	struct io_uring_sqe *sqe;
21 	const char *path = ".foo.bar";
22 	const char *old, *new;
23 	int ret;
24 
25 	if (bad_old) {
26 		old = (void *) (uintptr_t) 0x1234;
27 		new = path;
28 	} else {
29 		old = path;
30 		new = (void *) (uintptr_t) 0x1234;
31 	}
32 
33 	sqe = io_uring_get_sqe(ring);
34 	if (!sqe) {
35 		fprintf(stderr, "get sqe failed\n");
36 		goto err;
37 	}
38 
39 	memset(sqe, 0, sizeof(*sqe));
40 
41 	io_uring_prep_rename(sqe, old, new);
42 
43 	ret = io_uring_submit(ring);
44 	if (ret <= 0) {
45 		fprintf(stderr, "sqe submit failed: %d\n", ret);
46 		goto err;
47 	}
48 
49 	ret = io_uring_wait_cqe(ring, &cqe);
50 	if (ret < 0) {
51 		fprintf(stderr, "wait completion %d\n", ret);
52 		goto err;
53 	}
54 	ret = cqe->res;
55 	io_uring_cqe_seen(ring, cqe);
56 	return ret;
57 err:
58 	return 1;
59 }
60 
test_rename(struct io_uring * ring,const char * old,const char * new)61 static int test_rename(struct io_uring *ring, const char *old, const char *new)
62 {
63 	struct io_uring_cqe *cqe;
64 	struct io_uring_sqe *sqe;
65 	int ret;
66 
67 	sqe = io_uring_get_sqe(ring);
68 	if (!sqe) {
69 		fprintf(stderr, "get sqe failed\n");
70 		goto err;
71 	}
72 
73 	memset(sqe, 0, sizeof(*sqe));
74 
75 	io_uring_prep_rename(sqe, old, new);
76 
77 	ret = io_uring_submit(ring);
78 	if (ret <= 0) {
79 		fprintf(stderr, "sqe submit failed: %d\n", ret);
80 		goto err;
81 	}
82 
83 	ret = io_uring_wait_cqe(ring, &cqe);
84 	if (ret < 0) {
85 		fprintf(stderr, "wait completion %d\n", ret);
86 		goto err;
87 	}
88 	ret = cqe->res;
89 	io_uring_cqe_seen(ring, cqe);
90 	return ret;
91 err:
92 	return 1;
93 }
94 
stat_file(const char * buf)95 static int stat_file(const char *buf)
96 {
97 	struct stat sb;
98 
99 	if (!stat(buf, &sb))
100 		return 0;
101 
102 	return errno;
103 }
104 
main(int argc,char * argv[])105 int main(int argc, char *argv[])
106 {
107 	struct io_uring ring;
108 	char src[32] = "./XXXXXX";
109 	char dst[32] = "./XXXXXX";
110 	int ret;
111 
112 	if (argc > 1)
113 		return 0;
114 
115 	ret = io_uring_queue_init(1, &ring, 0);
116 	if (ret) {
117 		fprintf(stderr, "ring setup failed: %d\n", ret);
118 		return 1;
119 	}
120 
121 	ret = mkstemp(src);
122 	if (ret < 0) {
123 		perror("mkstemp");
124 		return 1;
125 	}
126 	close(ret);
127 
128 	ret = mkstemp(dst);
129 	if (ret < 0) {
130 		perror("mkstemp");
131 		return 1;
132 	}
133 	close(ret);
134 
135 	if (stat_file(src) != 0) {
136 		perror("stat");
137 		return 1;
138 	}
139 	if (stat_file(dst) != 0) {
140 		perror("stat");
141 		return 1;
142 	}
143 
144 	ret = test_rename(&ring, src, dst);
145 	if (ret < 0) {
146 		if (ret == -EBADF || ret == -EINVAL) {
147 			fprintf(stdout, "Rename not supported, skipping\n");
148 			goto out;
149 		}
150 		fprintf(stderr, "rename: %s\n", strerror(-ret));
151 		goto err;
152 	} else if (ret)
153 		goto err;
154 
155 	if (stat_file(src) != ENOENT) {
156 		fprintf(stderr, "stat got %s\n", strerror(ret));
157 		return 1;
158 	}
159 
160 	if (stat_file(dst) != 0) {
161 		perror("stat");
162 		return 1;
163 	}
164 
165 	ret = test_rename(&ring, "/x/y/1/2", "/2/1/y/x");
166 	if (ret != -ENOENT) {
167 		fprintf(stderr, "test_rename invalid failed: %d\n", ret);
168 		return ret;
169 	}
170 
171 	ret = test_rename_badaddr(&ring, 0);
172 	if (ret != -EFAULT) {
173 		fprintf(stderr, "test_badaddr 0 failed: %d\n", ret);
174 		return ret;
175 	}
176 
177 	ret = test_rename_badaddr(&ring, 1);
178 	if (ret != -EFAULT) {
179 		fprintf(stderr, "test_badaddr 1 failed: %d\n", ret);
180 		return ret;
181 	}
182 
183 out:
184 	unlink(dst);
185 	return 0;
186 err:
187 	unlink(src);
188 	unlink(dst);
189 	return 1;
190 }
191