* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "common/path_utils.h"
#include <fstream>
#include "ge_common/string_util.h"
#include "mmpa/mmpa_api.h"
#include "framework/common/debug/ge_log.h"
#include "base/err_msg.h"
#ifdef __GNUC__
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#endif
namespace ge {
std::string ge::PathUtils::Join(const std::vector<std::string> &names) {
return StringUtils::Join(names.begin(), names.end(), "/");
}
bool PathUtils::CopyFile(const std::string &src, const std::string &dst) {
std::ifstream src_file(src, std::ios::binary);
std::ofstream dst_file(dst, std::ios::binary);
dst_file << src_file.rdbuf();
}
std::string RealPath(const char_t *path) {
std::string res;
char_t resolved_path[MMPA_MAX_PATH] = {};
if (mmRealPath(path, &(resolved_path[0U]), MMPA_MAX_PATH) == EN_OK) {
res = &(resolved_path[0]);
}
return res;
}
int32_t CheckAndMkdir(const char_t *tmp_dir_path, mmMode_t mode) {
if (mmAccess2(tmp_dir_path, M_F_OK) != EN_OK) {
const int32_t ret = mmMkdir(tmp_dir_path, mode);
if (ret != 0 && errno != EEXIST) {
REPORT_INNER_ERR_MSG("E18888",
"Cannot create directory %s. Make sure the directory "
"exists and writable. errmsg:%s",
tmp_dir_path, strerror(errno));
GELOGW("[Util][mkdir] Create directory %s failed, reason:%s. Make sure the "
"directory exists and writable.",
tmp_dir_path, strerror(errno));
return ret;
}
}
return 0;
}
int32_t CreateDir(const std::string &directory_path, uint32_t mode) {
GE_CHK_BOOL_EXEC(!directory_path.empty(), REPORT_INNER_ERR_MSG("E18888", "directory path is empty, check invalid");
return -1, "[Check][Param] directory path is empty.");
const auto dir_path_len = directory_path.length();
if (dir_path_len >= static_cast<size_t>(MMPA_MAX_PATH)) {
REPORT_PREDEFINED_ERR_MSG(
"E13002", std::vector<const char *>({"filepath", "size"}),
std::vector<const char *>({directory_path.c_str(), std::to_string(MMPA_MAX_PATH).c_str()}));
GELOGW("[Util][mkdir] Path %s len is too long, it must be less than %d", directory_path.c_str(), MMPA_MAX_PATH);
return -1;
}
char_t tmp_dir_path[MMPA_MAX_PATH] = {};
const auto mkdir_mode = static_cast<mmMode_t>(mode);
for (size_t i = 0U; i < dir_path_len; i++) {
tmp_dir_path[i] = directory_path[i];
if ((tmp_dir_path[i] == '\\') || (tmp_dir_path[i] == '/')) {
const int32_t ret = CheckAndMkdir(&(tmp_dir_path[0U]), mkdir_mode);
if (ret != 0) {
return ret;
}
}
}
return CheckAndMkdir(directory_path.c_str(), mkdir_mode);
}
int32_t CreateDir(const std::string &directory_path) {
constexpr auto mkdir_mode = static_cast<uint32_t>(M_IRUSR | M_IWUSR | M_IXUSR);
return CreateDir(directory_path, mkdir_mode);
}
#ifdef __GNUC__
bool IsFile(const std::string &filename) {
struct stat buffer;
return (stat(filename.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode));
}
bool IsDirectory(const std::string &file_folder) {
struct stat buffer;
return (stat(file_folder.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode));
}
int64_t PathUtils::RemoveDirectories(const std::string &path) {
int result = 0;
DIR *p_dir;
struct dirent *p_dirent;
if (IsDirectory(path)) {
if ((p_dir = opendir(path.c_str())) == nullptr) {
return -1;
}
while ((p_dirent = readdir(p_dir)) != nullptr) {
std::string file_name = path + "/" + p_dirent->d_name;
if (IsDirectory(file_name) && (0 != strcmp(p_dirent->d_name, ".")) && (0 != strcmp(p_dirent->d_name, ".."))) {
result = RemoveDirectories(file_name);
if (result < 0) {
return result;
}
}
else if ((0 != strcmp(p_dirent->d_name, ".")) && (0 != strcmp(p_dirent->d_name, ".."))) {
result = remove(file_name.c_str());
if (result < 0) {
return result;
}
}
}
closedir(p_dir);
result = rmdir(path.c_str());
} else if (IsFile(path)) {
result = remove(path.c_str());
}
return result;
}
#else
#error "not support yet"
#endif
}