• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/common/file_utils.h"
18 #ifdef _WIN32
19 #include <direct.h>
20 #include <io.h>
21 #else
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25 #include <dirent.h>
26 #endif
27 
28 #include <cstdlib>
29 #include "securec/include/securec.h"
30 
31 #if defined(_WIN32) && defined(SUPPORT_MSVC)
32 #define PATH_MAX 1024
33 #define F_OK 0
34 #endif
35 
36 namespace mindspore {
37 namespace lite {
38 namespace {
39 const int MAXIMUM_NUMBERS_OF_FOLDER = 1000;
40 
AccessFile(const std::string & file_path,int access_mode)41 inline int AccessFile(const std::string &file_path, int access_mode) {
42 #ifdef _WIN32
43   return _access(file_path.c_str(), access_mode);
44 #else
45   // android access interface always return true
46   struct stat st;
47   if (stat(file_path.c_str(), &st) == 0) {
48     mode_t perm = st.st_mode;
49     auto can_read = perm & S_IRUSR;
50     return (can_read && access(file_path.c_str(), access_mode) == 0) ? 0 : -1;
51   }
52   return -1;
53 #endif
54 }
55 
Mkdir(const std::string & file_path)56 inline int Mkdir(const std::string &file_path) {
57 #ifdef _WIN32
58   return _mkdir(file_path.c_str());
59 #else
60   return mkdir(file_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
61 #endif
62 }
63 }  // namespace
64 
ReadFile(const char * file,size_t * size)65 char *ReadFile(const char *file, size_t *size) {
66   if (file == nullptr) {
67     MS_LOG(ERROR) << "file is nullptr";
68     return nullptr;
69   }
70   MS_ASSERT(size != nullptr);
71   std::string real_path = RealPath(file);
72   if (AccessFile(real_path, R_OK) != 0) {
73     MS_LOG(ERROR) << "cannot access file:" << real_path << ".please check file if exists and file mod";
74     return nullptr;
75   }
76   std::ifstream ifs(real_path, std::ifstream::in | std::ifstream::binary);
77   if (!ifs.good()) {
78     MS_LOG(ERROR) << "file: " << real_path << " is not exist";
79     return nullptr;
80   }
81 
82   if (!ifs.is_open()) {
83     MS_LOG(ERROR) << "file: " << real_path << " open failed";
84     return nullptr;
85   }
86 
87   ifs.seekg(0, std::ios::end);
88   *size = ifs.tellg();
89   auto buf = std::make_unique<char[]>(*size);
90   if (buf == nullptr) {
91     MS_LOG(ERROR) << "malloc buf failed, file: " << real_path;
92     ifs.close();
93     return nullptr;
94   }
95 
96   ifs.seekg(0, std::ios::beg);
97   ifs.read(buf.get(), *size);
98   ifs.close();
99 
100   return buf.release();
101 }
102 
RealPath(const char * path)103 std::string RealPath(const char *path) {
104   if (path == nullptr) {
105     MS_LOG(ERROR) << "path is nullptr";
106     return "";
107   }
108   if ((strlen(path)) >= PATH_MAX) {
109     MS_LOG(ERROR) << "path is too long";
110     return "";
111   }
112   auto resolved_path = std::make_unique<char[]>(PATH_MAX);
113   if (resolved_path == nullptr) {
114     MS_LOG(ERROR) << "new resolved_path failed";
115     return "";
116   }
117 #ifdef _WIN32
118   char *real_path = _fullpath(resolved_path.get(), path, PATH_MAX);
119 #else
120   char *real_path = realpath(path, resolved_path.get());
121 #endif
122   if (real_path == nullptr || strlen(real_path) == 0) {
123     MS_LOG(ERROR) << "file path is not valid : " << path;
124     return "";
125   }
126   std::string res = resolved_path.get();
127   return res;
128 }
129 
CreateOutputDir(std::string * file_path)130 int CreateOutputDir(std::string *file_path) {
131   if (file_path->empty()) {
132     MS_LOG(ERROR) << "input file path is empty.";
133     return RET_ERROR;
134   } else if (file_path->size() >= PATH_MAX) {
135     MS_LOG(ERROR) << "input file path is too long";
136     return RET_ERROR;
137   }
138 
139   for (size_t i = 0; i < file_path->size(); i++) {
140     if ((*file_path).at(i) == '\\' || (*file_path).at(i) == '/') {
141       if (AccessFile(file_path->substr(0, i + 1), F_OK) != 0) {
142         int ret = Mkdir(file_path->substr(0, i + 1));
143         if (ret != RET_OK) {
144           MS_LOG(ERROR) << "mkdir failed. " << file_path->substr(0, i + 1);
145           return RET_ERROR;
146         }
147       }
148     }
149   }
150 
151   if (file_path->back() != '\\' && file_path->back() != '/') {
152     if (AccessFile(*file_path, F_OK) != 0) {
153       int ret = Mkdir(*file_path);
154       if (ret != RET_OK) {
155         MS_LOG(ERROR) << "mkdir failed. " << file_path;
156         return RET_ERROR;
157       }
158     }
159   }
160 
161   int count = 0;
162   while (AccessFile((*file_path + "/" + std::to_string(count)), F_OK) == 0) {
163     MS_LOG(INFO) << "current file_path has existed, file_path cnt plus 1.";  // such as: /xxx/0 ==> /xxx/1
164     count++;
165     if (count >= MAXIMUM_NUMBERS_OF_FOLDER) {
166       MS_LOG(ERROR) << "the number of file folders exceeds the upper limit.";
167       return RET_ERROR;
168     }
169   }
170 #ifdef _WIN32
171   *file_path += "\\" + std::to_string(count);
172 #else
173   *file_path += "/" + std::to_string(count);
174 #endif
175   int ret = Mkdir(*file_path);
176   if (ret != RET_OK) {
177     MS_LOG(ERROR) << "mkdir failed. " << file_path->c_str();
178     return RET_ERROR;
179   }
180   return RET_OK;
181 }
182 }  // namespace lite
183 }  // namespace mindspore
184