Flutter Engine
file.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/fml/file.h"
6 
7 #include "flutter/fml/logging.h"
8 #include "flutter/fml/unique_fd.h"
9 
10 namespace fml {
11 
12 static fml::UniqueFD CreateDirectory(const fml::UniqueFD& base_directory,
13  const std::vector<std::string>& components,
14  FilePermission permission,
15  size_t index) {
16  FML_DCHECK(index <= components.size());
17 
18  const char* file_path = components[index].c_str();
19 
20  auto directory = OpenDirectory(base_directory, file_path, true, permission);
21 
22  if (!directory.is_valid()) {
23  return {};
24  }
25 
26  if (index == components.size() - 1) {
27  return directory;
28  }
29 
30  return CreateDirectory(directory, components, permission, index + 1);
31 }
32 
34  const std::vector<std::string>& components,
35  FilePermission permission) {
36  if (!IsDirectory(base_directory)) {
37  return {};
38  }
39 
40  if (components.size() == 0) {
41  return {};
42  }
43 
44  return CreateDirectory(base_directory, components, permission, 0);
45 }
46 
48  : path_(CreateTemporaryDirectory()) {
49  if (path_ != "") {
50  dir_fd_ = OpenDirectory(path_.c_str(), false, FilePermission::kRead);
51  }
52 }
53 
55  // POSIX requires the directory to be empty before UnlinkDirectory.
56  if (path_ != "") {
57  if (!RemoveFilesInDirectory(dir_fd_)) {
58  FML_LOG(ERROR) << "Could not clean directory: " << path_;
59  }
60  }
61 
62  // Windows has to close UniqueFD first before UnlinkDirectory
63  dir_fd_.reset();
64  if (path_ != "") {
65  if (!UnlinkDirectory(path_.c_str())) {
66  FML_LOG(ERROR) << "Could not remove directory: " << path_;
67  }
68  }
69 }
70 
71 bool VisitFilesRecursively(const fml::UniqueFD& directory,
72  const FileVisitor& visitor) {
73  FileVisitor recursive_visitor = [&recursive_visitor, &visitor](
74  const UniqueFD& directory,
75  const std::string& filename) {
76  if (!visitor(directory, filename)) {
77  return false;
78  }
79  if (IsDirectory(directory, filename.c_str())) {
80  UniqueFD sub_dir = OpenDirectoryReadOnly(directory, filename.c_str());
81  if (!sub_dir.is_valid()) {
82  FML_LOG(ERROR) << "Can't open sub-directory: " << filename;
83  return true;
84  }
85  return VisitFiles(sub_dir, recursive_visitor);
86  }
87  return true;
88  };
89  return VisitFiles(directory, recursive_visitor);
90 }
91 
93  const char* path) {
94  return OpenFile(base_directory, path, false, FilePermission::kRead);
95 }
96 
98  const char* path) {
99  return OpenDirectory(base_directory, path, false, FilePermission::kRead);
100 }
101 
102 bool RemoveFilesInDirectory(const fml::UniqueFD& directory) {
103  fml::FileVisitor recursive_cleanup = [&recursive_cleanup](
104  const fml::UniqueFD& directory,
105  const std::string& filename) {
106  bool removed;
107  if (fml::IsDirectory(directory, filename.c_str())) {
108  fml::UniqueFD sub_dir =
109  OpenDirectoryReadOnly(directory, filename.c_str());
110  removed = VisitFiles(sub_dir, recursive_cleanup) &&
111  fml::UnlinkDirectory(directory, filename.c_str());
112  } else {
113  removed = fml::UnlinkFile(directory, filename.c_str());
114  }
115  return removed;
116  };
117  return VisitFiles(directory, recursive_cleanup);
118 }
119 
121  const char* directory_name) {
122  auto dir = fml::OpenDirectory(parent, directory_name, false,
124  return RemoveFilesInDirectory(dir) && UnlinkDirectory(parent, directory_name);
125 }
126 
127 } // namespace fml
const std::string & path() const
Definition: file.h:146
bool RemoveFilesInDirectory(const fml::UniqueFD &directory)
Definition: file.cc:102
#define FML_DCHECK(condition)
Definition: logging.h:86
std::string CreateTemporaryDirectory()
Definition: file_posix.cc:23
std::function< bool(const fml::UniqueFD &directory, const std::string &filename)> FileVisitor
Definition: file.h:98
void reset(const T &value=Traits::InvalidValue())
Definition: unique_object.h:62
#define FML_LOG(severity)
Definition: logging.h:65
Definition: ascii_trie.cc:9
bool is_valid() const
Definition: unique_object.h:89
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
Definition: file_posix.cc:94
bool VisitFiles(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file_posix.cc:233
FilePermission
Definition: file.h:24
bool IsDirectory(const fml::UniqueFD &directory)
Definition: file_posix.cc:124
static fml::UniqueFD CreateDirectory(const fml::UniqueFD &base_directory, const std::vector< std::string > &components, FilePermission permission, size_t index)
Definition: file.cc:12
fml::UniqueFD OpenDirectoryReadOnly(const fml::UniqueFD &base_directory, const char *path)
Definition: file.cc:97
bool VisitFilesRecursively(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file.cc:71
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64
bool UnlinkDirectory(const char *path)
Definition: file_posix.cc:160
bool RemoveDirectoryRecursively(const fml::UniqueFD &parent, const char *directory_name)
Definition: file.cc:120
fml::UniqueFD OpenFileReadOnly(const fml::UniqueFD &base_directory, const char *path)
Definition: file.cc:92