diff options
author | Mike Frysinger <vapier@gentoo.org> | 2007-06-13 09:24:50 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2007-06-13 09:24:50 +0000 |
commit | b51fd3525e48c79ef9e854dd357a9cdfdfeef72b (patch) | |
tree | 9c26f4fa46961b3cca2a0eda7d0c6e1e4cd28dd5 /util-linux/mdev.c | |
parent | a78ef2ccf14a0b3bc50b8fd8fd3239ca1385ee2b (diff) | |
download | busybox-w32-b51fd3525e48c79ef9e854dd357a9cdfdfeef72b.tar.gz busybox-w32-b51fd3525e48c79ef9e854dd357a9cdfdfeef72b.tar.bz2 busybox-w32-b51fd3525e48c79ef9e854dd357a9cdfdfeef72b.zip |
as suggested by Renaud Cerrato and Souf, switch over to recursive_action() for some nice shrinkage and so we work even when CONFIG_SYSFS_DEPRECATED is off
Diffstat (limited to 'util-linux/mdev.c')
-rw-r--r-- | util-linux/mdev.c | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 8e5b8a94b..fca4fd052 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -19,6 +19,8 @@ struct globals { | |||
19 | #define root_major (G.root_major) | 19 | #define root_major (G.root_major) |
20 | #define root_minor (G.root_minor) | 20 | #define root_minor (G.root_minor) |
21 | 21 | ||
22 | #define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */ | ||
23 | |||
22 | /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ | 24 | /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ |
23 | static void make_device(char *path, int delete) | 25 | static void make_device(char *path, int delete) |
24 | { | 26 | { |
@@ -191,39 +193,28 @@ static void make_device(char *path, int delete) | |||
191 | if (delete) unlink(device_name); | 193 | if (delete) unlink(device_name); |
192 | } | 194 | } |
193 | 195 | ||
194 | /* Recursive search of /sys/block or /sys/class. path must be a writeable | 196 | /* File callback for /sys/ traversal */ |
195 | * buffer of size PATH_MAX containing the directory string to start at. */ | 197 | static int fileAction(const char *fileName, struct stat *statbuf, |
196 | 198 | void *userData, int depth) | |
197 | static void find_dev(char *path) | ||
198 | { | 199 | { |
199 | DIR *dir; | 200 | size_t len = strlen(fileName) - 4; |
200 | size_t len = strlen(path); | 201 | char *scratch = userData; |
201 | struct dirent *entry; | ||
202 | |||
203 | dir = opendir(path); | ||
204 | if (dir == NULL) | ||
205 | return; | ||
206 | |||
207 | while ((entry = readdir(dir)) != NULL) { | ||
208 | struct stat st; | ||
209 | |||
210 | /* Skip "." and ".." (also skips hidden files, which is ok) */ | ||
211 | |||
212 | if (entry->d_name[0] == '.') | ||
213 | continue; | ||
214 | 202 | ||
215 | // uClibc doesn't fill out entry->d_type reliably. so we use lstat(). | 203 | if (strcmp(fileName + len, "/dev")) |
204 | return FALSE; | ||
216 | 205 | ||
217 | snprintf(path+len, PATH_MAX-len, "/%s", entry->d_name); | 206 | strcpy(scratch, fileName); |
218 | if (!lstat(path, &st) && S_ISDIR(st.st_mode)) find_dev(path); | 207 | scratch[len] = 0; |
219 | path[len] = 0; | 208 | make_device(scratch, 0); |
220 | 209 | ||
221 | /* If there's a dev entry, mknod it */ | 210 | return TRUE; |
222 | 211 | } | |
223 | if (!strcmp(entry->d_name, "dev")) make_device(path, 0); | ||
224 | } | ||
225 | 212 | ||
226 | closedir(dir); | 213 | /* Directory callback for /sys/ traversal */ |
214 | static int dirAction(const char *fileName, struct stat *statbuf, | ||
215 | void *userData, int depth) | ||
216 | { | ||
217 | return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); | ||
227 | } | 218 | } |
228 | 219 | ||
229 | /* For the full gory details, see linux/Documentation/firmware_class/README | 220 | /* For the full gory details, see linux/Documentation/firmware_class/README |
@@ -308,10 +299,14 @@ int mdev_main(int argc, char **argv) | |||
308 | xstat("/", &st); | 299 | xstat("/", &st); |
309 | root_major = major(st.st_dev); | 300 | root_major = major(st.st_dev); |
310 | root_minor = minor(st.st_dev); | 301 | root_minor = minor(st.st_dev); |
311 | strcpy(temp,"/sys/block"); | 302 | |
312 | find_dev(temp); | 303 | recursive_action("/sys/block", |
313 | strcpy(temp,"/sys/class"); | 304 | ACTION_RECURSE | ACTION_FOLLOWLINKS, |
314 | find_dev(temp); | 305 | fileAction, dirAction, temp, 0); |
306 | |||
307 | recursive_action("/sys/class", | ||
308 | ACTION_RECURSE | ACTION_FOLLOWLINKS, | ||
309 | fileAction, dirAction, temp, 0); | ||
315 | 310 | ||
316 | /* Hotplug */ | 311 | /* Hotplug */ |
317 | 312 | ||