1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci#include <dirent.h>
16570af302Sopenharmony_ci#include <fcntl.h>
17570af302Sopenharmony_ci#include <stdio.h>
18570af302Sopenharmony_ci#include <string.h>
19570af302Sopenharmony_ci#include <sys/stat.h>
20570af302Sopenharmony_ci#include <unistd.h>
21570af302Sopenharmony_ci#include <errno.h>
22570af302Sopenharmony_ci#include "test.h"
23570af302Sopenharmony_ci#define BUFFER_SIZE 1024
24570af302Sopenharmony_ci#define RENAME_ZERO 0
25570af302Sopenharmony_ci
26570af302Sopenharmony_cistatic int g_error = 0;
27570af302Sopenharmony_cistatic char g_dirPath[] = "/data/local/tmp";
28570af302Sopenharmony_cistatic char g_oldPath[] = "/data/local/tmp/renameat2_test.txt";
29570af302Sopenharmony_cistatic char g_oldName[] = "renameat2_test.txt";
30570af302Sopenharmony_cistatic char g_oldMsg[] = "renameat2";
31570af302Sopenharmony_cistatic char g_newPath[] = "/data/local/tmp/newrenameat2_test.txt";
32570af302Sopenharmony_cistatic char g_newName[] = "newrenameat2_test.txt";
33570af302Sopenharmony_cistatic char g_newMsg[] = "newrenameat2";
34570af302Sopenharmony_ci
35570af302Sopenharmony_cistatic void WriteFile(char *path, char *msg)
36570af302Sopenharmony_ci{
37570af302Sopenharmony_ci    FILE *file = fopen(path, "w+");
38570af302Sopenharmony_ci    if (file == NULL) {
39570af302Sopenharmony_ci        g_error++;
40570af302Sopenharmony_ci        return;
41570af302Sopenharmony_ci    }
42570af302Sopenharmony_ci    size_t len = strlen(msg);
43570af302Sopenharmony_ci    size_t n = fwrite(msg, sizeof(char), len, file);
44570af302Sopenharmony_ci    if (fclose(file)) {
45570af302Sopenharmony_ci        g_error++;
46570af302Sopenharmony_ci        return;
47570af302Sopenharmony_ci    }
48570af302Sopenharmony_ci    if (n != len) {
49570af302Sopenharmony_ci        g_error++;
50570af302Sopenharmony_ci        return;
51570af302Sopenharmony_ci    }
52570af302Sopenharmony_ci}
53570af302Sopenharmony_ci
54570af302Sopenharmony_cistatic void ReadFile(char *path, size_t len, char *buf)
55570af302Sopenharmony_ci{
56570af302Sopenharmony_ci    FILE *file = fopen(path, "r");
57570af302Sopenharmony_ci    if (file == NULL) {
58570af302Sopenharmony_ci        g_error++;
59570af302Sopenharmony_ci        return;
60570af302Sopenharmony_ci    }
61570af302Sopenharmony_ci    size_t n = fread(buf, sizeof(char), len, file);
62570af302Sopenharmony_ci    if (fclose(file)) {
63570af302Sopenharmony_ci        g_error++;
64570af302Sopenharmony_ci        return;
65570af302Sopenharmony_ci    }
66570af302Sopenharmony_ci    if (n != len) {
67570af302Sopenharmony_ci        g_error++;
68570af302Sopenharmony_ci        return;
69570af302Sopenharmony_ci    }
70570af302Sopenharmony_ci}
71570af302Sopenharmony_ci
72570af302Sopenharmony_cistatic void CompareFileString(char *path, size_t readCount, char *compareString)
73570af302Sopenharmony_ci{
74570af302Sopenharmony_ci    char buf[BUFFER_SIZE] = {0};
75570af302Sopenharmony_ci    ReadFile(path, readCount, buf);
76570af302Sopenharmony_ci    if (strcmp(compareString, buf)) {
77570af302Sopenharmony_ci        g_error++;
78570af302Sopenharmony_ci    }
79570af302Sopenharmony_ci}
80570af302Sopenharmony_ci
81570af302Sopenharmony_cistatic void RemoveFile()
82570af302Sopenharmony_ci{
83570af302Sopenharmony_ci    if (access(g_oldPath, F_OK) == 0) {
84570af302Sopenharmony_ci        if (remove(g_oldPath)) {
85570af302Sopenharmony_ci            printf("information: file removed fail\n");
86570af302Sopenharmony_ci        }
87570af302Sopenharmony_ci    }
88570af302Sopenharmony_ci    if (access(g_newPath, F_OK) == 0) {
89570af302Sopenharmony_ci        if (remove(g_newPath)) {
90570af302Sopenharmony_ci            printf("information: file removed fail\n");
91570af302Sopenharmony_ci        }
92570af302Sopenharmony_ci    }
93570af302Sopenharmony_ci}
94570af302Sopenharmony_ci
95570af302Sopenharmony_cistatic void RenameNoReplaceTest(int oldFolder, int newFolder)
96570af302Sopenharmony_ci{
97570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
98570af302Sopenharmony_ci    if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_NOREPLACE) == -1) {
99570af302Sopenharmony_ci        g_error++;
100570af302Sopenharmony_ci        return;
101570af302Sopenharmony_ci    }
102570af302Sopenharmony_ci    if (access(g_oldPath, F_OK) == 0) {
103570af302Sopenharmony_ci        g_error++;
104570af302Sopenharmony_ci        return;
105570af302Sopenharmony_ci    }
106570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
107570af302Sopenharmony_ci    RemoveFile();
108570af302Sopenharmony_ci
109570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
110570af302Sopenharmony_ci    WriteFile(g_newPath, g_newMsg);
111570af302Sopenharmony_ci    if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_NOREPLACE) == 0) {
112570af302Sopenharmony_ci        g_error++;
113570af302Sopenharmony_ci        return;
114570af302Sopenharmony_ci    }
115570af302Sopenharmony_ci    CompareFileString(g_oldPath, strlen(g_oldMsg), g_oldMsg);
116570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_newMsg), g_newMsg);
117570af302Sopenharmony_ci    RemoveFile();
118570af302Sopenharmony_ci
119570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
120570af302Sopenharmony_ci    if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_NOREPLACE) == -1) {
121570af302Sopenharmony_ci        g_error++;
122570af302Sopenharmony_ci        return;
123570af302Sopenharmony_ci    }
124570af302Sopenharmony_ci    if (access(g_oldPath, F_OK) == 0) {
125570af302Sopenharmony_ci        g_error++;
126570af302Sopenharmony_ci        return;
127570af302Sopenharmony_ci    }
128570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
129570af302Sopenharmony_ci    RemoveFile();
130570af302Sopenharmony_ci
131570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
132570af302Sopenharmony_ci    WriteFile(g_newPath, g_newMsg);
133570af302Sopenharmony_ci    if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_NOREPLACE) == 0) {
134570af302Sopenharmony_ci        g_error++;
135570af302Sopenharmony_ci        return;
136570af302Sopenharmony_ci    }
137570af302Sopenharmony_ci    CompareFileString(g_oldPath, strlen(g_oldMsg), g_oldMsg);
138570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_newMsg), g_newMsg);
139570af302Sopenharmony_ci    RemoveFile();
140570af302Sopenharmony_ci}
141570af302Sopenharmony_ci
142570af302Sopenharmony_cistatic void ZeroTest(int oldFolder, int newFolder)
143570af302Sopenharmony_ci{
144570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
145570af302Sopenharmony_ci    if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_ZERO) == -1) {
146570af302Sopenharmony_ci        g_error++;
147570af302Sopenharmony_ci        return;
148570af302Sopenharmony_ci    }
149570af302Sopenharmony_ci    if (access(g_oldPath, F_OK) == 0) {
150570af302Sopenharmony_ci        g_error++;
151570af302Sopenharmony_ci        return;
152570af302Sopenharmony_ci    }
153570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
154570af302Sopenharmony_ci    RemoveFile();
155570af302Sopenharmony_ci
156570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
157570af302Sopenharmony_ci    WriteFile(g_newPath, g_newMsg);
158570af302Sopenharmony_ci    if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_ZERO) == -1) {
159570af302Sopenharmony_ci        g_error++;
160570af302Sopenharmony_ci        return;
161570af302Sopenharmony_ci    }
162570af302Sopenharmony_ci    if (access(g_oldPath, F_OK) == 0) {
163570af302Sopenharmony_ci        g_error++;
164570af302Sopenharmony_ci        return;
165570af302Sopenharmony_ci    }
166570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
167570af302Sopenharmony_ci    RemoveFile();
168570af302Sopenharmony_ci
169570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
170570af302Sopenharmony_ci    if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_ZERO) == -1) {
171570af302Sopenharmony_ci        g_error++;
172570af302Sopenharmony_ci        return;
173570af302Sopenharmony_ci    }
174570af302Sopenharmony_ci    if (access(g_oldPath, F_OK) == 0) {
175570af302Sopenharmony_ci        g_error++;
176570af302Sopenharmony_ci        return;
177570af302Sopenharmony_ci    }
178570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
179570af302Sopenharmony_ci    RemoveFile();
180570af302Sopenharmony_ci
181570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
182570af302Sopenharmony_ci    WriteFile(g_newPath, g_newMsg);
183570af302Sopenharmony_ci    if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_ZERO) == -1) {
184570af302Sopenharmony_ci        g_error++;
185570af302Sopenharmony_ci        return;
186570af302Sopenharmony_ci    }
187570af302Sopenharmony_ci    if (access(g_oldPath, F_OK) == 0) {
188570af302Sopenharmony_ci        g_error++;
189570af302Sopenharmony_ci        return;
190570af302Sopenharmony_ci    }
191570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
192570af302Sopenharmony_ci    RemoveFile();
193570af302Sopenharmony_ci}
194570af302Sopenharmony_ci
195570af302Sopenharmony_cistatic void RenameExchangeTest(int oldFolder, int newFolder)
196570af302Sopenharmony_ci{
197570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
198570af302Sopenharmony_ci    WriteFile(g_newPath, g_newMsg);
199570af302Sopenharmony_ci    if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_EXCHANGE) == -1) {
200570af302Sopenharmony_ci        g_error++;
201570af302Sopenharmony_ci        return;
202570af302Sopenharmony_ci    }
203570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
204570af302Sopenharmony_ci    CompareFileString(g_oldPath, strlen(g_newMsg), g_newMsg);
205570af302Sopenharmony_ci    RemoveFile();
206570af302Sopenharmony_ci
207570af302Sopenharmony_ci    WriteFile(g_oldPath, g_oldMsg);
208570af302Sopenharmony_ci    WriteFile(g_newPath, g_newMsg);
209570af302Sopenharmony_ci    if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_EXCHANGE) == -1) {
210570af302Sopenharmony_ci        g_error++;
211570af302Sopenharmony_ci        return;
212570af302Sopenharmony_ci    }
213570af302Sopenharmony_ci    CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
214570af302Sopenharmony_ci    CompareFileString(g_oldPath, strlen(g_newMsg), g_newMsg);
215570af302Sopenharmony_ci    RemoveFile();
216570af302Sopenharmony_ci}
217570af302Sopenharmony_ci
218570af302Sopenharmony_cistatic void CloseFolder(DIR *dir)
219570af302Sopenharmony_ci{
220570af302Sopenharmony_ci    if (closedir(dir)) {
221570af302Sopenharmony_ci        printf("information: close folder fail\n");
222570af302Sopenharmony_ci    }
223570af302Sopenharmony_ci}
224570af302Sopenharmony_ci
225570af302Sopenharmony_ciint main(void)
226570af302Sopenharmony_ci{
227570af302Sopenharmony_ci    DIR *dir = opendir(g_dirPath);
228570af302Sopenharmony_ci    if (dir == NULL) {
229570af302Sopenharmony_ci        t_error("%s open dir failed, errno: %d\n", __func__, errno);
230570af302Sopenharmony_ci        return 1;
231570af302Sopenharmony_ci    }
232570af302Sopenharmony_ci    int dirFD = dirfd(dir);
233570af302Sopenharmony_ci    if (dirFD == -1) {
234570af302Sopenharmony_ci        t_error("%s open dirfd failed, errno: %d\n", __func__, errno);
235570af302Sopenharmony_ci        return 1;
236570af302Sopenharmony_ci    }
237570af302Sopenharmony_ci
238570af302Sopenharmony_ci    g_error = 0;
239570af302Sopenharmony_ci    RenameNoReplaceTest(dirFD, dirFD);
240570af302Sopenharmony_ci    if (g_error) {
241570af302Sopenharmony_ci        t_error("%s renameat2 failed,flags: RENAME_NOREPLACE\n", __func__);
242570af302Sopenharmony_ci        RemoveFile();
243570af302Sopenharmony_ci        CloseFolder(dir);
244570af302Sopenharmony_ci        return 1;
245570af302Sopenharmony_ci    }
246570af302Sopenharmony_ci
247570af302Sopenharmony_ci    g_error = 0;
248570af302Sopenharmony_ci    ZeroTest(dirFD, dirFD);
249570af302Sopenharmony_ci    if (g_error) {
250570af302Sopenharmony_ci        t_error("%s renameat2 failed,flags: zero\n", __func__);
251570af302Sopenharmony_ci        RemoveFile();
252570af302Sopenharmony_ci        CloseFolder(dir);
253570af302Sopenharmony_ci        return 1;
254570af302Sopenharmony_ci    }
255570af302Sopenharmony_ci
256570af302Sopenharmony_ci    g_error = 0;
257570af302Sopenharmony_ci    RenameExchangeTest(dirFD, dirFD);
258570af302Sopenharmony_ci    if (g_error) {
259570af302Sopenharmony_ci        t_error("%s renameat2 failed,flags: RENAME_EXCHANGE\n", __func__);
260570af302Sopenharmony_ci        RemoveFile();
261570af302Sopenharmony_ci        CloseFolder(dir);
262570af302Sopenharmony_ci        return 1;
263570af302Sopenharmony_ci    }
264570af302Sopenharmony_ci    CloseFolder(dir);
265570af302Sopenharmony_ci    return 0;
266570af302Sopenharmony_ci}