1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <dirent.h>
16 #include <fcntl.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #include <errno.h>
22 #include "test.h"
23 #define BUFFER_SIZE 1024
24 #define RENAME_ZERO 0
25
26 static int g_error = 0;
27 static char g_dirPath[] = "/data/local/tmp";
28 static char g_oldPath[] = "/data/local/tmp/renameat2_test.txt";
29 static char g_oldName[] = "renameat2_test.txt";
30 static char g_oldMsg[] = "renameat2";
31 static char g_newPath[] = "/data/local/tmp/newrenameat2_test.txt";
32 static char g_newName[] = "newrenameat2_test.txt";
33 static char g_newMsg[] = "newrenameat2";
34
WriteFile(char *path, char *msg)35 static void WriteFile(char *path, char *msg)
36 {
37 FILE *file = fopen(path, "w+");
38 if (file == NULL) {
39 g_error++;
40 return;
41 }
42 size_t len = strlen(msg);
43 size_t n = fwrite(msg, sizeof(char), len, file);
44 if (fclose(file)) {
45 g_error++;
46 return;
47 }
48 if (n != len) {
49 g_error++;
50 return;
51 }
52 }
53
ReadFile(char *path, size_t len, char *buf)54 static void ReadFile(char *path, size_t len, char *buf)
55 {
56 FILE *file = fopen(path, "r");
57 if (file == NULL) {
58 g_error++;
59 return;
60 }
61 size_t n = fread(buf, sizeof(char), len, file);
62 if (fclose(file)) {
63 g_error++;
64 return;
65 }
66 if (n != len) {
67 g_error++;
68 return;
69 }
70 }
71
CompareFileString(char *path, size_t readCount, char *compareString)72 static void CompareFileString(char *path, size_t readCount, char *compareString)
73 {
74 char buf[BUFFER_SIZE] = {0};
75 ReadFile(path, readCount, buf);
76 if (strcmp(compareString, buf)) {
77 g_error++;
78 }
79 }
80
RemoveFilenull81 static void RemoveFile()
82 {
83 if (access(g_oldPath, F_OK) == 0) {
84 if (remove(g_oldPath)) {
85 printf("information: file removed fail\n");
86 }
87 }
88 if (access(g_newPath, F_OK) == 0) {
89 if (remove(g_newPath)) {
90 printf("information: file removed fail\n");
91 }
92 }
93 }
94
RenameNoReplaceTest(int oldFolder, int newFolder)95 static void RenameNoReplaceTest(int oldFolder, int newFolder)
96 {
97 WriteFile(g_oldPath, g_oldMsg);
98 if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_NOREPLACE) == -1) {
99 g_error++;
100 return;
101 }
102 if (access(g_oldPath, F_OK) == 0) {
103 g_error++;
104 return;
105 }
106 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
107 RemoveFile();
108
109 WriteFile(g_oldPath, g_oldMsg);
110 WriteFile(g_newPath, g_newMsg);
111 if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_NOREPLACE) == 0) {
112 g_error++;
113 return;
114 }
115 CompareFileString(g_oldPath, strlen(g_oldMsg), g_oldMsg);
116 CompareFileString(g_newPath, strlen(g_newMsg), g_newMsg);
117 RemoveFile();
118
119 WriteFile(g_oldPath, g_oldMsg);
120 if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_NOREPLACE) == -1) {
121 g_error++;
122 return;
123 }
124 if (access(g_oldPath, F_OK) == 0) {
125 g_error++;
126 return;
127 }
128 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
129 RemoveFile();
130
131 WriteFile(g_oldPath, g_oldMsg);
132 WriteFile(g_newPath, g_newMsg);
133 if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_NOREPLACE) == 0) {
134 g_error++;
135 return;
136 }
137 CompareFileString(g_oldPath, strlen(g_oldMsg), g_oldMsg);
138 CompareFileString(g_newPath, strlen(g_newMsg), g_newMsg);
139 RemoveFile();
140 }
141
ZeroTest(int oldFolder, int newFolder)142 static void ZeroTest(int oldFolder, int newFolder)
143 {
144 WriteFile(g_oldPath, g_oldMsg);
145 if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_ZERO) == -1) {
146 g_error++;
147 return;
148 }
149 if (access(g_oldPath, F_OK) == 0) {
150 g_error++;
151 return;
152 }
153 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
154 RemoveFile();
155
156 WriteFile(g_oldPath, g_oldMsg);
157 WriteFile(g_newPath, g_newMsg);
158 if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_ZERO) == -1) {
159 g_error++;
160 return;
161 }
162 if (access(g_oldPath, F_OK) == 0) {
163 g_error++;
164 return;
165 }
166 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
167 RemoveFile();
168
169 WriteFile(g_oldPath, g_oldMsg);
170 if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_ZERO) == -1) {
171 g_error++;
172 return;
173 }
174 if (access(g_oldPath, F_OK) == 0) {
175 g_error++;
176 return;
177 }
178 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
179 RemoveFile();
180
181 WriteFile(g_oldPath, g_oldMsg);
182 WriteFile(g_newPath, g_newMsg);
183 if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_ZERO) == -1) {
184 g_error++;
185 return;
186 }
187 if (access(g_oldPath, F_OK) == 0) {
188 g_error++;
189 return;
190 }
191 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
192 RemoveFile();
193 }
194
RenameExchangeTest(int oldFolder, int newFolder)195 static void RenameExchangeTest(int oldFolder, int newFolder)
196 {
197 WriteFile(g_oldPath, g_oldMsg);
198 WriteFile(g_newPath, g_newMsg);
199 if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_EXCHANGE) == -1) {
200 g_error++;
201 return;
202 }
203 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
204 CompareFileString(g_oldPath, strlen(g_newMsg), g_newMsg);
205 RemoveFile();
206
207 WriteFile(g_oldPath, g_oldMsg);
208 WriteFile(g_newPath, g_newMsg);
209 if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_EXCHANGE) == -1) {
210 g_error++;
211 return;
212 }
213 CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
214 CompareFileString(g_oldPath, strlen(g_newMsg), g_newMsg);
215 RemoveFile();
216 }
217
CloseFolder(DIR *dir)218 static void CloseFolder(DIR *dir)
219 {
220 if (closedir(dir)) {
221 printf("information: close folder fail\n");
222 }
223 }
224
main(void)225 int main(void)
226 {
227 DIR *dir = opendir(g_dirPath);
228 if (dir == NULL) {
229 t_error("%s open dir failed, errno: %d\n", __func__, errno);
230 return 1;
231 }
232 int dirFD = dirfd(dir);
233 if (dirFD == -1) {
234 t_error("%s open dirfd failed, errno: %d\n", __func__, errno);
235 return 1;
236 }
237
238 g_error = 0;
239 RenameNoReplaceTest(dirFD, dirFD);
240 if (g_error) {
241 t_error("%s renameat2 failed,flags: RENAME_NOREPLACE\n", __func__);
242 RemoveFile();
243 CloseFolder(dir);
244 return 1;
245 }
246
247 g_error = 0;
248 ZeroTest(dirFD, dirFD);
249 if (g_error) {
250 t_error("%s renameat2 failed,flags: zero\n", __func__);
251 RemoveFile();
252 CloseFolder(dir);
253 return 1;
254 }
255
256 g_error = 0;
257 RenameExchangeTest(dirFD, dirFD);
258 if (g_error) {
259 t_error("%s renameat2 failed,flags: RENAME_EXCHANGE\n", __func__);
260 RemoveFile();
261 CloseFolder(dir);
262 return 1;
263 }
264 CloseFolder(dir);
265 return 0;
266 }