106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci * 1506f6ba60Sopenharmony_ci * Description: FileUtils implements 1606f6ba60Sopenharmony_ci */ 1706f6ba60Sopenharmony_ci#include "file_utils.h" 1806f6ba60Sopenharmony_ci 1906f6ba60Sopenharmony_ci#include <cerrno> 2006f6ba60Sopenharmony_ci#include <cstring> 2106f6ba60Sopenharmony_ci#include <dirent.h> 2206f6ba60Sopenharmony_ci#include <fcntl.h> 2306f6ba60Sopenharmony_ci#include <unistd.h> 2406f6ba60Sopenharmony_ci#include <regex> 2506f6ba60Sopenharmony_ci#include "logging.h" 2606f6ba60Sopenharmony_ci 2706f6ba60Sopenharmony_cinamespace { 2806f6ba60Sopenharmony_ciconstexpr size_t DEFAULT_READ_SIZE = 4096; 2906f6ba60Sopenharmony_ci} 3006f6ba60Sopenharmony_ci 3106f6ba60Sopenharmony_cistd::string FileUtils::ReadFile(int fd) 3206f6ba60Sopenharmony_ci{ 3306f6ba60Sopenharmony_ci std::string content; 3406f6ba60Sopenharmony_ci size_t count = 0; 3506f6ba60Sopenharmony_ci while (true) { 3606f6ba60Sopenharmony_ci if (content.size() - count < DEFAULT_READ_SIZE) { 3706f6ba60Sopenharmony_ci content.resize(content.size() + DEFAULT_READ_SIZE); 3806f6ba60Sopenharmony_ci } 3906f6ba60Sopenharmony_ci ssize_t nBytes = TEMP_FAILURE_RETRY(read(fd, &content[count], content.size() - count)); 4006f6ba60Sopenharmony_ci if (nBytes == -1 && errno == EAGAIN) { 4106f6ba60Sopenharmony_ci continue; 4206f6ba60Sopenharmony_ci } 4306f6ba60Sopenharmony_ci if (nBytes <= 0) { 4406f6ba60Sopenharmony_ci break; 4506f6ba60Sopenharmony_ci } 4606f6ba60Sopenharmony_ci count += nBytes; 4706f6ba60Sopenharmony_ci } 4806f6ba60Sopenharmony_ci content.resize(count); 4906f6ba60Sopenharmony_ci return content; 5006f6ba60Sopenharmony_ci} 5106f6ba60Sopenharmony_ci 5206f6ba60Sopenharmony_cistd::string FileUtils::ReadFile(const std::string& path) 5306f6ba60Sopenharmony_ci{ 5406f6ba60Sopenharmony_ci char realPath[PATH_MAX + 1] = {0}; 5506f6ba60Sopenharmony_ci CHECK_TRUE((path.length() < PATH_MAX) && (realpath(path.c_str(), realPath) != nullptr), "", 5606f6ba60Sopenharmony_ci "%s:path is invalid: %s, errno=%d", __func__, path.c_str(), errno); 5706f6ba60Sopenharmony_ci int fd = open(realPath, O_RDONLY); 5806f6ba60Sopenharmony_ci if (fd == -1) { 5906f6ba60Sopenharmony_ci const int bufSize = 256; 6006f6ba60Sopenharmony_ci char buf[bufSize] = { 0 }; 6106f6ba60Sopenharmony_ci strerror_r(errno, buf, bufSize); 6206f6ba60Sopenharmony_ci PROFILER_LOG_WARN(LOG_CORE, "open file %s FAILED: %s!", path.c_str(), buf); 6306f6ba60Sopenharmony_ci return ""; 6406f6ba60Sopenharmony_ci } 6506f6ba60Sopenharmony_ci std::string content = ReadFile(fd); 6606f6ba60Sopenharmony_ci CHECK_TRUE(close(fd) != -1, content, "close %s failed, %d", path.c_str(), errno); 6706f6ba60Sopenharmony_ci return content; 6806f6ba60Sopenharmony_ci} 6906f6ba60Sopenharmony_ci 7006f6ba60Sopenharmony_ciint FileUtils::WriteFile(const std::string& path, const std::string& content) 7106f6ba60Sopenharmony_ci{ 7206f6ba60Sopenharmony_ci return WriteFile(path, content, O_WRONLY); 7306f6ba60Sopenharmony_ci} 7406f6ba60Sopenharmony_ci 7506f6ba60Sopenharmony_ciint FileUtils::WriteFile(const std::string& path, const std::string& content, int flags) 7606f6ba60Sopenharmony_ci{ 7706f6ba60Sopenharmony_ci return WriteFile(path, content, flags, 0); 7806f6ba60Sopenharmony_ci} 7906f6ba60Sopenharmony_ci 8006f6ba60Sopenharmony_ciint FileUtils::WriteFile(const std::string& path, const std::string& content, int flags, int mode) 8106f6ba60Sopenharmony_ci{ 8206f6ba60Sopenharmony_ci CHECK_TRUE(!path.empty() && (path.length() < PATH_MAX), -1, 8306f6ba60Sopenharmony_ci "%s:path is invalid: %s, errno=%d", __func__, path.c_str(), errno); 8406f6ba60Sopenharmony_ci 8506f6ba60Sopenharmony_ci std::regex dirNameRegex("[.~-]"); 8606f6ba60Sopenharmony_ci std::regex fileNameRegex("[\\/:*?\"<>|]"); 8706f6ba60Sopenharmony_ci size_t pos = path.rfind("/"); 8806f6ba60Sopenharmony_ci if (pos != std::string::npos) { 8906f6ba60Sopenharmony_ci std::string dirName = path.substr(0, pos+1); 9006f6ba60Sopenharmony_ci size_t index = path.length() > (pos + 1) ? path.length() - pos - 1 : 0; 9106f6ba60Sopenharmony_ci std::string fileName = path.substr(pos+1, index); 9206f6ba60Sopenharmony_ci CHECK_TRUE(!(std::regex_search(dirName, dirNameRegex) || std::regex_search(fileName, fileNameRegex)), -1, 9306f6ba60Sopenharmony_ci "%s:path is invalid: %s, errno=%d", __func__, path.c_str(), errno); 9406f6ba60Sopenharmony_ci } else { 9506f6ba60Sopenharmony_ci CHECK_TRUE(!std::regex_search(path, fileNameRegex), -1, 9606f6ba60Sopenharmony_ci "%s:path is invalid: %s, errno=%d", __func__, path.c_str(), errno); 9706f6ba60Sopenharmony_ci } 9806f6ba60Sopenharmony_ci 9906f6ba60Sopenharmony_ci int fd = open(path.c_str(), flags, mode); 10006f6ba60Sopenharmony_ci CHECK_TRUE(fd >= 0, -1, "open %s failed, %d", path.c_str(), errno); 10106f6ba60Sopenharmony_ci 10206f6ba60Sopenharmony_ci int retval = write(fd, content.data(), content.size()); 10306f6ba60Sopenharmony_ci CHECK_TRUE(close(fd) != -1, -1, "close %s failed, %d", path.c_str(), errno); 10406f6ba60Sopenharmony_ci return retval; 10506f6ba60Sopenharmony_ci} 10606f6ba60Sopenharmony_ci 10706f6ba60Sopenharmony_cistd::vector<std::string> FileUtils::ListDir(const std::string& dirPath) 10806f6ba60Sopenharmony_ci{ 10906f6ba60Sopenharmony_ci std::vector<std::string> result; 11006f6ba60Sopenharmony_ci DIR* dir = opendir(dirPath.c_str()); 11106f6ba60Sopenharmony_ci if (dir == nullptr) { 11206f6ba60Sopenharmony_ci return result; 11306f6ba60Sopenharmony_ci } 11406f6ba60Sopenharmony_ci 11506f6ba60Sopenharmony_ci struct dirent* ent = nullptr; 11606f6ba60Sopenharmony_ci while ((ent = readdir(dir)) != nullptr) { 11706f6ba60Sopenharmony_ci std::string name = ent->d_name; 11806f6ba60Sopenharmony_ci if (name == "." || name == "..") { 11906f6ba60Sopenharmony_ci continue; 12006f6ba60Sopenharmony_ci } 12106f6ba60Sopenharmony_ci result.push_back(name); 12206f6ba60Sopenharmony_ci } 12306f6ba60Sopenharmony_ci closedir(dir); 12406f6ba60Sopenharmony_ci return result; 12506f6ba60Sopenharmony_ci} 126