* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
* ubs-engine is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* 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 FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "ubse_file_util.h"
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <filesystem>
#include <fstream>
#include <memory>
#include <regex>
#include "ubse_error.h"
#include "ubse_logger_module.h"
namespace ubse::utils {
using namespace ubse::common::def;
UBSE_DEFINE_THIS_MODULE("ubse");
using std::ifstream;
using namespace ubse::log;
* 读取文件内容
* @param path const string &: 文件路径
* @param info vector<string> &: 文件内容, 按行输出
* @return UbseResult
*/
UbseResult UbseFileUtil::GetFileInfo(const string& path, vector<string>& info)
{
auto realFileName = std::make_unique<char[]>(PATH_MAX);
if (!realFileName) {
return UBSE_ERROR;
}
if ((realpath(path.c_str(), realFileName.get()) == nullptr) && (errno == ENOENT)) {
return UBSE_ERROR;
}
ifstream file((string(realFileName.get())));
if (!file.is_open()) {
return UBSE_ERROR;
}
try {
string line;
while (getline(file, line)) {
info.push_back(line);
}
} catch (const std::exception& e) {
file.close();
return UBSE_ERROR;
}
file.close();
return UBSE_OK;
}
* @brief 检查给定路径是否为 Unix/Linux 系统的绝对路径。
*
* 该函数使用filesystem的is_absolute函数判断是否为绝对路径。
*
* @param path 要检查的路径。
* @return UbseResult 如果路径是绝对路径,则返回 UBSE_OK,
* 否则返回 UBSE_ERROR。
*/
UbseResult UbseFileUtil::IsAbsolutePath(const std::string& path)
{
if (path.empty() || path[NO_0] != '/') {
return UBSE_ERROR;
}
std::filesystem::path p(path);
try {
if (p.is_absolute()) {
return UBSE_OK;
}
return UBSE_ERROR;
} catch (const std::exception& e) {
return UBSE_ERROR;
}
}
std::vector<std::string> UbseFileUtil::ListFiles(const std::string& directory, const std::regex& pattern)
{
std::vector<std::string> files;
const auto dir = opendir(directory.c_str());
if (dir == nullptr) {
return files;
}
dirent* entry;
while ((entry = readdir(dir)) != nullptr) {
const std::string fileName = entry->d_name;
if (fileName != "." && fileName != "..") {
if (std::regex_match(fileName, pattern)) {
files.push_back(fileName);
}
}
}
closedir(dir);
return files;
}
bool UbseFileUtil::IsDirectory(const string& dir)
{
struct stat info {
};
if (stat(dir.data(), &info) != 0) {
return false;
}
return S_ISDIR(info.st_mode);
}
UbseResult UbseFileUtil::CreateAndChmodDirectory(const string& dir, mode_t permission)
{
if (IsAbsolutePath(dir) != UBSE_OK) {
UBSE_LOG_ERROR << "The directory must be an absolute path, current path=" << dir;
return UBSE_ERROR;
}
if (!IsDirectory(dir)) {
if (mkdir(dir.c_str(), permission) == 0) {
UBSE_LOG_INFO << "Success to create directory=" << dir;
} else {
UBSE_LOG_ERROR << "Failed to create directory=" << dir;
return UBSE_ERROR;
}
}
auto ret = chmod(dir.c_str(), permission);
if (ret != 0) {
UBSE_LOG_ERROR << "Failed to chmod to directory=" << dir << ", ret=" << strerror(errno);
return UBSE_ERROR_ACCES;
}
return UBSE_OK;
}
bool UbseFileUtil::CheckFileExists(const string& path)
{
struct stat buffer {
};
return (stat(path.c_str(), &buffer) == 0);
}
* @brief 设置文件的所有者和属组
* @param path 文件路径
* @param uid 用户ID,如果为0则保持不变
* @param gid 组ID,如果为0则保持不变
* @return bool 成功返回true,失败返回false
*/
bool UbseFileUtil::SetFileOwnership(const std::string& path, uid_t uid, gid_t gid)
{
if (access(path.c_str(), F_OK) != 0) {
return false;
}
if (uid == 0 && gid == 0) {
return true;
}
struct stat fileStat {
};
if (stat(path.c_str(), &fileStat) != 0) {
return false;
}
uid_t targetUid = (uid == 0) ? fileStat.st_uid : uid;
gid_t targetGid = (gid == 0) ? fileStat.st_gid : gid;
if (chown(path.c_str(), targetUid, targetGid) != 0) {
return false;
}
return true;
}
* @brief 设置文件权限
* @param path 文件路径
* @param mode 权限模式,如0644、0755等
* @return bool 成功返回true,失败返回false
*/
bool UbseFileUtil::SetFilePermissions(const std::string& path, mode_t mode)
{
if (access(path.c_str(), F_OK) != 0) {
return false;
}
if (chmod(path.c_str(), mode) != 0) {
return false;
}
return true;
}
* @brief 同时设置文件所有权和权限
* @param path 文件路径
* @param uid 用户ID
* @param gid 组ID
* @param mode 权限模式
* @return bool 成功返回true,失败返回false
*/
bool UbseFileUtil::SetFileAttributes(const std::string& path, uid_t uid, gid_t gid, mode_t mode)
{
bool success = true;
if (mode != 0) {
success = SetFilePermissions(path, mode);
}
if (uid != 0 || gid != 0) {
success = success && SetFileOwnership(path, uid, gid);
}
return success;
}
* @brief 规范化路径
* @param path 文件路径
* @return bool 成功返回true,失败返回false
*/
bool UbseFileUtil::CanonicalPath(std::string& path)
{
if (path.empty() || path.size() > PATH_MAX) {
return false;
}
char* realPath = realpath(path.c_str(), nullptr);
if (realPath == nullptr) {
return false;
}
path = realPath;
free(realPath);
return true;
}
}