* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "test.h"
#define BUFFER_SIZE 1024
#define RENAME_ZERO 0
static int g_error = 0;
static char g_dirPath[] = "/data/local/tmp";
static char g_oldPath[] = "/data/local/tmp/renameat2_test.txt";
static char g_oldName[] = "renameat2_test.txt";
static char g_oldMsg[] = "renameat2";
static char g_newPath[] = "/data/local/tmp/newrenameat2_test.txt";
static char g_newName[] = "newrenameat2_test.txt";
static char g_newMsg[] = "newrenameat2";
static void WriteFile(char *path, char *msg)
{
FILE *file = fopen(path, "w+");
if (file == NULL) {
g_error++;
return;
}
size_t len = strlen(msg);
size_t n = fwrite(msg, sizeof(char), len, file);
if (fclose(file)) {
g_error++;
return;
}
if (n != len) {
g_error++;
return;
}
}
static void ReadFile(char *path, size_t len, char *buf)
{
FILE *file = fopen(path, "r");
if (file == NULL) {
g_error++;
return;
}
size_t n = fread(buf, sizeof(char), len, file);
if (fclose(file)) {
g_error++;
return;
}
if (n != len) {
g_error++;
return;
}
}
static void CompareFileString(char *path, size_t readCount, char *compareString)
{
char buf[BUFFER_SIZE] = {0};
ReadFile(path, readCount, buf);
if (strcmp(compareString, buf)) {
g_error++;
}
}
static void RemoveFile()
{
if (access(g_oldPath, F_OK) == 0) {
if (remove(g_oldPath)) {
printf("information: file removed fail\n");
}
}
if (access(g_newPath, F_OK) == 0) {
if (remove(g_newPath)) {
printf("information: file removed fail\n");
}
}
}
static void RenameNoReplaceTest(int oldFolder, int newFolder)
{
WriteFile(g_oldPath, g_oldMsg);
if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_NOREPLACE) == -1) {
g_error++;
return;
}
if (access(g_oldPath, F_OK) == 0) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
RemoveFile();
WriteFile(g_oldPath, g_oldMsg);
WriteFile(g_newPath, g_newMsg);
if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_NOREPLACE) == 0) {
g_error++;
return;
}
CompareFileString(g_oldPath, strlen(g_oldMsg), g_oldMsg);
CompareFileString(g_newPath, strlen(g_newMsg), g_newMsg);
RemoveFile();
WriteFile(g_oldPath, g_oldMsg);
if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_NOREPLACE) == -1) {
g_error++;
return;
}
if (access(g_oldPath, F_OK) == 0) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
RemoveFile();
WriteFile(g_oldPath, g_oldMsg);
WriteFile(g_newPath, g_newMsg);
if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_NOREPLACE) == 0) {
g_error++;
return;
}
CompareFileString(g_oldPath, strlen(g_oldMsg), g_oldMsg);
CompareFileString(g_newPath, strlen(g_newMsg), g_newMsg);
RemoveFile();
}
static void ZeroTest(int oldFolder, int newFolder)
{
WriteFile(g_oldPath, g_oldMsg);
if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_ZERO) == -1) {
g_error++;
return;
}
if (access(g_oldPath, F_OK) == 0) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
RemoveFile();
WriteFile(g_oldPath, g_oldMsg);
WriteFile(g_newPath, g_newMsg);
if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_ZERO) == -1) {
g_error++;
return;
}
if (access(g_oldPath, F_OK) == 0) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
RemoveFile();
WriteFile(g_oldPath, g_oldMsg);
if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_ZERO) == -1) {
g_error++;
return;
}
if (access(g_oldPath, F_OK) == 0) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
RemoveFile();
WriteFile(g_oldPath, g_oldMsg);
WriteFile(g_newPath, g_newMsg);
if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_ZERO) == -1) {
g_error++;
return;
}
if (access(g_oldPath, F_OK) == 0) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
RemoveFile();
}
static void RenameExchangeTest(int oldFolder, int newFolder)
{
WriteFile(g_oldPath, g_oldMsg);
WriteFile(g_newPath, g_newMsg);
if (renameat2(oldFolder, g_oldName, newFolder, g_newName, RENAME_EXCHANGE) == -1) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
CompareFileString(g_oldPath, strlen(g_newMsg), g_newMsg);
RemoveFile();
WriteFile(g_oldPath, g_oldMsg);
WriteFile(g_newPath, g_newMsg);
if (renameat2(AT_FDCWD, g_oldPath, AT_FDCWD, g_newPath, RENAME_EXCHANGE) == -1) {
g_error++;
return;
}
CompareFileString(g_newPath, strlen(g_oldMsg), g_oldMsg);
CompareFileString(g_oldPath, strlen(g_newMsg), g_newMsg);
RemoveFile();
}
static void CloseFolder(DIR *dir)
{
if (closedir(dir)) {
printf("information: close folder fail\n");
}
}
int main(void)
{
DIR *dir = opendir(g_dirPath);
if (dir == NULL) {
t_error("%s open dir failed, errno: %d\n", __func__, errno);
return 1;
}
int dirFD = dirfd(dir);
if (dirFD == -1) {
t_error("%s open dirfd failed, errno: %d\n", __func__, errno);
return 1;
}
g_error = 0;
RenameNoReplaceTest(dirFD, dirFD);
if (g_error) {
t_error("%s renameat2 failed,flags: RENAME_NOREPLACE\n", __func__);
RemoveFile();
CloseFolder(dir);
return 1;
}
g_error = 0;
ZeroTest(dirFD, dirFD);
if (g_error) {
t_error("%s renameat2 failed,flags: zero\n", __func__);
RemoveFile();
CloseFolder(dir);
return 1;
}
g_error = 0;
RenameExchangeTest(dirFD, dirFD);
if (g_error) {
t_error("%s renameat2 failed,flags: RENAME_EXCHANGE\n", __func__);
RemoveFile();
CloseFolder(dir);
return 1;
}
CloseFolder(dir);
return 0;
}