summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJooyung Han <jooyung@google.com>2019-05-03 00:42:31 +0900
committerJooyung Han <jooyung@google.com>2019-05-07 14:41:40 +0000
commitaed3a0330159bda1a1baf8cde6ebb5aa0f142129 (patch)
treee2b81c1a59910855617227bf1e9b3e0717c6463f
parent37751319ee24278bda70e0031cf55f5b733a5b6f (diff)
downloadapex-aed3a0330159bda1a1baf8cde6ebb5aa0f142129.tar.gz
apexd: make exception-free
Do not use APIs which can throw exceptions. - add and use WalkDir() helper instead of directory_iterator - use noexcept version of is_block_file() Bug: 124662897 Test: atest apexservice_test Test: adb shell pm list packages --apex-only (after restart) Change-Id: Ie42ba763903521c43e21381e3ae9871cd71120fd
-rw-r--r--apexd/apex_database.cpp16
-rw-r--r--apexd/apexd_utils.h37
2 files changed, 32 insertions, 21 deletions
diff --git a/apexd/apex_database.cpp b/apexd/apex_database.cpp
index d386adbd..53793659 100644
--- a/apexd/apex_database.cpp
+++ b/apexd/apex_database.cpp
@@ -100,10 +100,15 @@ class BlockDevice {
std::vector<BlockDevice> GetSlaves() const {
std::vector<BlockDevice> slaves;
- for (auto& p : fs::directory_iterator(SysPath() / "slaves")) {
- if (fs::is_block_file(kDevBlock / p.path().filename())) {
- slaves.emplace_back(p.path());
+ std::error_code ec;
+ auto status = WalkDir(SysPath() / "slaves", [&](const auto& entry) {
+ BlockDevice dev(entry);
+ if (fs::is_block_file(dev.DevPath(), ec)) {
+ slaves.push_back(dev);
}
+ });
+ if (!status.Ok()) {
+ LOG(WARNING) << status.ErrorMessage();
}
return slaves;
}
@@ -142,12 +147,12 @@ StatusOr<inode_t> inodeFor(const std::string& path) {
return StatusOr<inode_t>(buf.st_dev, buf.st_ino);
}
-// Flattened packages from builtin APEX dirs(/system/apex, /product/apex)
+// Flattened packages from builtin APEX dirs(/system/apex, /product/apex, ...)
inode_map scanFlattendedPackages() {
inode_map map;
for (const auto& dir : kApexPackageBuiltinDirs) {
- ReadDir(dir, [&](const fs::directory_entry& entry) {
+ WalkDir(dir, [&](const fs::directory_entry& entry) {
const auto& path = entry.path();
if (isFlattenedApex(path)) {
auto inode = inodeFor(path);
@@ -155,7 +160,6 @@ inode_map scanFlattendedPackages() {
map[*inode] = path;
}
}
- return true;
});
}
diff --git a/apexd/apexd_utils.h b/apexd/apexd_utils.h
index 3ce80541..e97c0ba6 100644
--- a/apexd/apexd_utils.h
+++ b/apexd/apexd_utils.h
@@ -82,33 +82,40 @@ inline int ForkAndRun(const std::vector<std::string>& args,
return rc;
}
-template <typename FilterFn>
-StatusOr<std::vector<std::string>> ReadDir(const std::string& path,
- FilterFn fn) {
+template <typename Fn>
+Status WalkDir(const std::string& path, Fn fn) {
namespace fs = std::filesystem;
- using Status = StatusOr<std::vector<std::string>>;
-
std::error_code ec;
- if (!fs::is_directory(path, ec) || ec) {
- return Status::Fail(StringLog() << "Can't open " << path
- << " for reading : " << ec.message());
- }
-
- std::vector<std::string> ret;
auto it = fs::directory_iterator(path, ec);
auto end = fs::directory_iterator();
while (!ec && it != end) {
- if (fn(*it)) {
- ret.push_back(it->path());
- }
+ fn(*it);
it.increment(ec);
}
if (ec) {
return Status::Fail(StringLog() << "Can't open " << path
<< " for reading : " << ec.message());
}
+ return Status::Success();
+}
+
+template <typename FilterFn>
+StatusOr<std::vector<std::string>> ReadDir(const std::string& path,
+ FilterFn fn) {
+ namespace fs = std::filesystem;
+ using Status = StatusOr<std::vector<std::string>>;
+
+ std::vector<std::string> ret;
+ auto status = WalkDir(path, [&](const fs::directory_entry& entry) {
+ if (fn(entry)) {
+ ret.push_back(entry.path());
+ }
+ });
+ if (!status.Ok()) {
+ return Status::Fail(status.ErrorMessage());
+ }
return Status(std::move(ret));
-} // namespace apex
+}
inline bool IsEmptyDirectory(const std::string& path) {
auto res = ReadDir(path, [](auto _) { return true; });