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
27 namespace panda::ecmascript::filesystem {
CreateDirectory(const std::string & path)28 bool CreateDirectory(const std::string& path)
29 {
30 if (path.empty() || Exists(path)) {
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
Exists(const std::string & path)46 bool Exists(const std::string& path)
47 {
48 return panda::ecmascript::FileExist(path.c_str());
49 }
50
TempDirectoryPath()51 std::string TempDirectoryPath()
52 {
53 const char* temp = getenv("TMPDIR");
54 if (temp) {
55 return std::string(temp);
56 }
57 return "/tmp";
58 }
59
FileSize(const std::string & path)60 std::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
RemoveAll(const std::string & path)67 bool 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
CreateEmptyFile(const std::string & fileName)98 void 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