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 26static int g_error = 0; 27static char g_dirPath[] = "/data/local/tmp"; 28static char g_oldPath[] = "/data/local/tmp/renameat2_test.txt"; 29static char g_oldName[] = "renameat2_test.txt"; 30static char g_oldMsg[] = "renameat2"; 31static char g_newPath[] = "/data/local/tmp/newrenameat2_test.txt"; 32static char g_newName[] = "newrenameat2_test.txt"; 33static char g_newMsg[] = "newrenameat2"; 34 35static 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 54static 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 72static 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 81static 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 95static 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 142static 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 195static 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 218static void CloseFolder(DIR *dir) 219{ 220 if (closedir(dir)) { 221 printf("information: close folder fail\n"); 222 } 223} 224 225int 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}