1/* 2 * Copyright (c) 2024 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 16#include "ecmascript/platform/filesystem.h" 17 18#include <dirent.h> 19#include <sys/stat.h> 20#include <sys/types.h> 21#include <unistd.h> 22 23#include "ecmascript/platform/file.h" 24 25#include "os/filesystem.h" 26 27namespace panda::ecmascript::filesystem { 28bool CreateDirectory(const std::string& path) 29{ 30 if (path.empty()) { 31 return true; 32 } 33 auto pos = path.find_last_of('/'); 34 if (pos != std::string::npos) { 35 if (!CreateDirectory(path.substr(0, pos))) { 36 return false; 37 } 38 } 39 panda::os::CreateDirectories(path); 40 if (!Exists(path)) { 41 return false; 42 } 43 return true; 44} 45 46bool Exists(const std::string& path) 47{ 48 return panda::ecmascript::FileExist(path.c_str()); 49} 50 51std::string TempDirectoryPath() 52{ 53 const char* temp = getenv("TMPDIR"); 54 if (temp) { 55 return std::string(temp); 56 } 57 return "/tmp"; 58} 59 60std::size_t FileSize(const std::string& path) 61{ 62 struct stat info; 63 stat(path.c_str(), &info); 64 return info.st_size; 65} 66 67bool RemoveAll(const std::string& path) 68{ 69 struct stat info; 70 if (stat(path.c_str(), &info) != 0) { 71 return false; 72 } 73 74 if (S_ISDIR(info.st_mode)) { 75 DIR* dir = opendir(path.c_str()); 76 if (!dir) { 77 return false; 78 } 79 80 struct dirent* entry; 81 while ((entry = readdir(dir)) != nullptr) { 82 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { 83 continue; 84 } 85 std::string entryPath = path + "/" + entry->d_name; 86 if (!RemoveAll(entryPath)) { 87 closedir(dir); 88 return false; 89 } 90 } 91 closedir(dir); 92 return rmdir(path.c_str()) == 0; 93 } else { 94 return unlink(path.c_str()) == 0; 95 } 96} 97 98void CreateEmptyFile(const std::string& fileName) 99{ 100 std::string realPath; 101 if (!panda::ecmascript::RealPath(fileName, realPath, false)) { 102 LOG_FULL(ERROR) << "failed to create empty file: " << fileName << ", error: " << std::strerror(errno); 103 return; 104 } 105 if (Exists(realPath)) { 106 LOG_FULL(INFO) << realPath << " exists, skip creation"; 107 return; 108 } 109 110 auto index = realPath.find_last_of('/'); 111 if (index != std::string::npos) { 112 std::string dir = realPath.substr(0, index); 113 if (Exists(dir)) { 114 LOG_FULL(INFO) << dir << " exists, skip creation"; 115 } else { 116 LOG_FULL(INFO) << "creating folder " << dir; 117 if (!CreateDirectory(dir)) { 118 LOG_FULL(ERROR) << "failed to create folder " << dir << ", error: " << std::strerror(errno); 119 return; 120 } 121 } 122 } 123 124 std::ofstream file(realPath); 125 if (!file.good()) { 126 LOG_FULL(ERROR) << "failed to create empty file: " << realPath << ", error: " << std::strerror(errno); 127 } else { 128 LOG_FULL(INFO) << "created empty file: " << realPath; 129 } 130 file.close(); 131} 132} // namespace panda::ecmascript::kungfu::filesystem