2929#include < cstring>
3030#include < sys/types.h>
3131#include < sys/stat.h>
32+ #include < filesystem>
3233
3334namespace thinkfan {
3435
36+ namespace filesystem = std::filesystem;
37+
3538
3639static int filter_hwmon_dirs (const struct dirent *entry)
3740{
3841 return (entry->d_type == DT_DIR || entry->d_type == DT_LNK)
39- && (! strncmp ( " hwmon " , entry->d_name , 5 ) || ! strcmp ( " device " , entry->d_name ));
42+ && (string ( entry->d_name ) == " hwmon " || string ( entry->d_name ) == " device " );
4043}
4144
4245
@@ -48,6 +51,43 @@ static int filter_subdirs(const struct dirent *entry)
4851}
4952
5053
54+ template <>
55+ int HwmonInterface<SensorDriver>::filter_driver_file(const struct dirent *entry)
56+ {
57+ int idx;
58+ return (entry->d_type == DT_REG || entry->d_type == DT_LNK)
59+ && !::sscanf (entry->d_name , " temp%d_input" , &idx)
60+ ;
61+ }
62+
63+ template <>
64+ int HwmonInterface<FanDriver>::filter_driver_file(const struct dirent *entry)
65+ {
66+ int idx;
67+ return (entry->d_type == DT_REG || entry->d_type == DT_LNK)
68+ && !::sscanf (entry->d_name , " pwm%d" , &idx)
69+ ;
70+ }
71+
72+
73+ template <int (* filter_fn)(const struct dirent *)>
74+ vector<filesystem::path> dir_entries (const filesystem::path &dir)
75+ {
76+ struct dirent **entries;
77+ int nentries = ::scandir (dir.c_str (), &entries, filter_fn, nullptr );
78+ if (nentries == -1 )
79+ return {};
80+
81+ vector<filesystem::path> rv;
82+ for (int i = 0 ; i < nentries; ++i) {
83+ rv.emplace_back (dir / entries[i]->d_name );
84+ ::free (entries[i]);
85+ }
86+ ::free (entries);
87+ return rv;
88+ }
89+
90+
5191template <class HwmonT >
5292vector<string> HwmonInterface<HwmonT>::find_files(const string &path, const vector<unsigned int > &indices)
5393{
@@ -85,6 +125,7 @@ HwmonInterface<HwmonT>::HwmonInterface(const string &base_path, opt<const string
85125, indices_(indices)
86126{}
87127
128+
88129template <class HwmonT >
89130vector<string> HwmonInterface<HwmonT>::find_hwmons_by_name(
90131 const string &path,
@@ -106,15 +147,7 @@ vector<string> HwmonInterface<HwmonT>::find_hwmons_by_name(
106147 return result; // don't recurse to subdirs
107148 }
108149
109- struct dirent **entries;
110- int nentries = ::scandir (path.c_str (), &entries, filter_subdirs, nullptr );
111- if (nentries == -1 ) {
112- return result;
113- }
114- for (int i = 0 ; i < nentries; i++) {
115- auto subdir = path + " /" + entries[i]->d_name ;
116- free (entries[i]);
117-
150+ for (const filesystem::path &subdir : dir_entries<filter_subdirs>(path)) {
118151 struct stat statbuf;
119152 int err = stat (path.c_str (), &statbuf);
120153 if (err || (statbuf.st_mode & S_IFMT) != S_IFDIR)
@@ -123,11 +156,11 @@ vector<string> HwmonInterface<HwmonT>::find_hwmons_by_name(
123156 auto found = find_hwmons_by_name (subdir, name, depth + 1 );
124157 result.insert (result.end (), found.begin (), found.end ());
125158 }
126- free (entries);
127159
128160 return result;
129161}
130162
163+
131164template <class HwmonT >
132165vector<string> HwmonInterface<HwmonT>::find_hwmons_by_model(
133166 const string &path,
@@ -152,15 +185,7 @@ vector<string> HwmonInterface<HwmonT>::find_hwmons_by_model(
152185 return result; // don't recurse to subdirs
153186 }
154187
155- struct dirent **entries;
156- int nentries = ::scandir (path.c_str (), &entries, filter_subdirs, nullptr );
157- if (nentries == -1 ) {
158- return result;
159- }
160- for (int i = 0 ; i < nentries; i++) {
161- auto subdir = path + " /" + entries[i]->d_name ;
162- free (entries[i]);
163-
188+ for (const filesystem::path &subdir : dir_entries<filter_subdirs>(path)) {
164189 struct stat statbuf;
165190 int err = stat (path.c_str (), &statbuf);
166191 if (err || (statbuf.st_mode & S_IFMT) != S_IFDIR)
@@ -169,11 +194,11 @@ vector<string> HwmonInterface<HwmonT>::find_hwmons_by_model(
169194 auto found = find_hwmons_by_model (subdir, model, depth + 1 );
170195 result.insert (result.end (), found.begin (), found.end ());
171196 }
172- free (entries);
173197
174198 return result;
175199}
176200
201+
177202template <class HwmonT >
178203vector<string> HwmonInterface<HwmonT>::find_hwmons_by_indices(
179204 const string &path,
@@ -187,24 +212,20 @@ vector<string> HwmonInterface<HwmonT>::find_hwmons_by_indices(
187212 }
188213 catch (IOerror &) {
189214 if (depth <= max_depth) {
190- struct dirent **entries;
191- int nentries = ::scandir (path.c_str (), &entries, filter_hwmon_dirs, alphasort);
192- if (nentries < 0 )
215+ vector<filesystem::path> hwmon_dirs = dir_entries<filter_hwmon_dirs>(path);
216+ if (hwmon_dirs.empty ())
193217 throw IOerror (" Error scanning " + path + " : " , errno);
194218
195219 vector<string> rv;
196- for (int i = 0 ; i < nentries; i++ ) {
220+ for (const filesystem::path &hwmon_dir : hwmon_dirs ) {
197221 rv = HwmonInterface<HwmonT>::find_hwmons_by_indices (
198- path + " / " + entries[i]-> d_name ,
222+ hwmon_dir ,
199223 indices,
200224 depth + 1
201225 );
202226 if (rv.size ())
203227 break ;
204228 }
205- for (int i = 0 ; i < nentries; i++)
206- free (entries[i]);
207- free (entries);
208229
209230 return rv;
210231 }
@@ -214,7 +235,6 @@ vector<string> HwmonInterface<HwmonT>::find_hwmons_by_indices(
214235}
215236
216237
217-
218238template <class HwmonT >
219239string HwmonInterface<HwmonT>::lookup()
220240{
@@ -229,7 +249,7 @@ string HwmonInterface<HwmonT>::lookup()
229249 if (paths.size () != 1 ) {
230250 string msg (path + " : " );
231251 if (paths.size () == 0 ) {
232- msg += " Could not find a hwmon with this name: " + name_.value ();
252+ msg += " Could not find an hwmon with this name: " + name_.value ();
233253 } else {
234254 msg += MSG_MULTIPLE_HWMONS_FOUND;
235255 for (string hwmon_path : paths)
@@ -259,8 +279,10 @@ string HwmonInterface<HwmonT>::lookup()
259279 if (found_paths_.size () == 0 )
260280 throw DriverInitError (path + " : " + " Could not find any hwmons in " + path);
261281 }
262- else
263- found_paths_.push_back (path);
282+ else {
283+ vector<filesystem::path> paths = dir_entries<filter_driver_file>(path);
284+ found_paths_.assign (paths.begin (), paths.end ());
285+ }
264286
265287 paths_it_.emplace (found_paths_.begin ());
266288 }
0 commit comments