diff options
author | Jooyung Han <jooyung@google.com> | 2019-05-03 00:42:31 +0900 |
---|---|---|
committer | Jooyung Han <jooyung@google.com> | 2019-05-07 14:41:40 +0000 |
commit | aed3a0330159bda1a1baf8cde6ebb5aa0f142129 (patch) | |
tree | e2b81c1a59910855617227bf1e9b3e0717c6463f | |
parent | 37751319ee24278bda70e0031cf55f5b733a5b6f (diff) | |
download | apex-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.cpp | 16 | ||||
-rw-r--r-- | apexd/apexd_utils.h | 37 |
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; }); |