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) |
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 { #define root_major (G.root_major) #define root_minor (G.root_minor) +#define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */ + /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ static void make_device(char *path, int delete) { @@ -191,39 +193,28 @@ static void make_device(char *path, int delete) if (delete) unlink(device_name); } -/* Recursive search of /sys/block or /sys/class. path must be a writeable - * buffer of size PATH_MAX containing the directory string to start at. */ - -static void find_dev(char *path) +/* File callback for /sys/ traversal */ +static int fileAction(const char *fileName, struct stat *statbuf, + void *userData, int depth) { - DIR *dir; - size_t len = strlen(path); - struct dirent *entry; - - dir = opendir(path); - if (dir == NULL) - return; - - while ((entry = readdir(dir)) != NULL) { - struct stat st; - - /* Skip "." and ".." (also skips hidden files, which is ok) */ - - if (entry->d_name[0] == '.') - continue; + size_t len = strlen(fileName) - 4; + char *scratch = userData; - // uClibc doesn't fill out entry->d_type reliably. so we use lstat(). + if (strcmp(fileName + len, "/dev")) + return FALSE; - snprintf(path+len, PATH_MAX-len, "/%s", entry->d_name); - if (!lstat(path, &st) && S_ISDIR(st.st_mode)) find_dev(path); - path[len] = 0; + strcpy(scratch, fileName); + scratch[len] = 0; + make_device(scratch, 0); - /* If there's a dev entry, mknod it */ - - if (!strcmp(entry->d_name, "dev")) make_device(path, 0); - } + return TRUE; +} - closedir(dir); +/* Directory callback for /sys/ traversal */ +static int dirAction(const char *fileName, struct stat *statbuf, + void *userData, int depth) +{ + return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); } /* For the full gory details, see linux/Documentation/firmware_class/README @@ -308,10 +299,14 @@ int mdev_main(int argc, char **argv) xstat("/", &st); root_major = major(st.st_dev); root_minor = minor(st.st_dev); - strcpy(temp,"/sys/block"); - find_dev(temp); - strcpy(temp,"/sys/class"); - find_dev(temp); + + recursive_action("/sys/block", + ACTION_RECURSE | ACTION_FOLLOWLINKS, + fileAction, dirAction, temp, 0); + + recursive_action("/sys/class", + ACTION_RECURSE | ACTION_FOLLOWLINKS, + fileAction, dirAction, temp, 0); /* Hotplug */ |