72 lines
2.4 KiB
Diff
72 lines
2.4 KiB
Diff
From a4619a5138ce581c6cee79dbf0b47c85ac5467cf Mon Sep 17 00:00:00 2001
|
|
From: classabbyamp <dev@placeviolette.net>
|
|
Date: Sun, 24 Mar 2024 16:45:52 -0400
|
|
Subject: [PATCH] fix(file_util::pick): ensure files are readable before
|
|
picking them
|
|
|
|
the firmware of the Lenovo X13s does not expose charge_now or
|
|
charge_full, but the files still exist, so file_util::pick() will still
|
|
choose that over energy_now/energy_full. This leads to the battery
|
|
module erroneously outputting "0%" at all times. If charge_now or
|
|
charge_full is read, it will return ENODATA, so simply reading 1 char
|
|
and checking the status should determine if the file should actually be
|
|
picked.
|
|
---
|
|
include/utils/file.hpp | 1 +
|
|
src/utils/file.cpp | 20 ++++++++++++++++++--
|
|
2 files changed, 19 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/include/utils/file.hpp b/include/utils/file.hpp
|
|
index 8a34c6450..65ff10a53 100644
|
|
--- a/include/utils/file.hpp
|
|
+++ b/include/utils/file.hpp
|
|
@@ -82,6 +82,7 @@ class fd_stream : public StreamType {
|
|
|
|
namespace file_util {
|
|
bool exists(const string& filename);
|
|
+ bool readable(const string& filename);
|
|
bool is_file(const string& filename);
|
|
bool is_dir(const string& filename);
|
|
string pick(const vector<string>& filenames);
|
|
diff --git a/src/utils/file.cpp b/src/utils/file.cpp
|
|
index 9511ad613..b9dce41a6 100644
|
|
--- a/src/utils/file.cpp
|
|
+++ b/src/utils/file.cpp
|
|
@@ -152,6 +152,22 @@ namespace file_util {
|
|
return stat(filename.c_str(), &buffer) == 0;
|
|
}
|
|
|
|
+ /**
|
|
+ * Checks if the given file is actually readable
|
|
+ *
|
|
+ * Doing an actual read is necessary to confirm that reading
|
|
+ * will actually succeed. For example, some battery firmware
|
|
+ * will return ENODATA when charge_now is read, as it is not
|
|
+ * implemented in the firmware, despite the file existing
|
|
+ * and having a+r permissions.
|
|
+ */
|
|
+ bool readable(const string& filename) {
|
|
+ char c;
|
|
+ std::ifstream in(filename, std::ifstream::in);
|
|
+ in.get(c);
|
|
+ return in.good();
|
|
+ }
|
|
+
|
|
/**
|
|
* Checks if the given path exists and is a file
|
|
*/
|
|
@@ -179,11 +195,11 @@ namespace file_util {
|
|
}
|
|
|
|
/**
|
|
- * Picks the first existing file out of given entries
|
|
+ * Picks the first existing and readable file out of given entries
|
|
*/
|
|
string pick(const vector<string>& filenames) {
|
|
for (auto&& f : filenames) {
|
|
- if (exists(f)) {
|
|
+ if (exists(f) && readable(f)) {
|
|
return f;
|
|
}
|
|
}
|