From b51fd3525e48c79ef9e854dd357a9cdfdfeef72b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 13 Jun 2007 09:24:50 +0000 Subject: 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 --- util-linux/mdev.c | 59 +++++++++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 32 deletions(-) (limited to 'util-linux') diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 8e5b8a9..fca4fd0 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 */ -- cgit v1.1