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

This commit is contained in:
Mike Frysinger 2007-06-13 09:24:50 +00:00
parent a78ef2ccf1
commit b51fd3525e

View File

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