From mboxrd@z Thu Jan 1 00:00:00 1970 From: Arun Bhanu Date: Wed, 15 Sep 2004 22:00:56 +0000 Subject: [RFC][PATCH] use libsysfs for udevstart directory walking Message-Id: <20040915220056.GA9906@spock.enterprise> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linux-hotplug@vger.kernel.org Hi Following up on Kay's idea about using libsysfs for directory walking. Attached patch(against udev-032) is a first cut attempt at replacing udev_scan_class directory walking code with libsysfs calls. If we agree on this approach, I'll do the same for udev_scan_block. Currently, libsysfs does not provide an API for getting all the classes. So, I've introduced two new functions in libsysfs: struct dlist *sysfs_open_classes(void) void sysfs_close_classes(struct dlist *clslist) Comments/flames? --Arun Signed-off-by: Arun Bhanu diff -Nru a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h --- a/libsysfs/sysfs/libsysfs.h 2004-09-14 13:55:34.000000000 +0800 +++ b/libsysfs/sysfs/libsysfs.h 2004-09-16 04:42:56.528667024 +0800 @@ -288,6 +288,9 @@ extern struct sysfs_attribute *sysfs_open_classdev_attr (const char *classname, const char *dev, const char *attrib); +extern struct dlist *sysfs_open_classes(void); +extern void sysfs_close_classes(struct dlist *clslist); + /** * sort_list: sorter function to keep list elements sorted in alphabetical diff -Nru a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c --- a/libsysfs/sysfs_class.c 2004-09-14 13:55:37.000000000 +0800 +++ b/libsysfs/sysfs_class.c 2004-09-16 04:32:08.080246168 +0800 @@ -703,3 +703,48 @@ return attribute; } +static inline void sysfs_close_class_classes(void *cls) +{ + sysfs_close_class((struct sysfs_class *)cls); +} + +struct dlist *sysfs_open_classes(void) +{ + struct sysfs_directory *dir; + struct sysfs_directory *sdir; + struct dlist *dirlist; + + char classpath[SYSFS_PATH_MAX]; + memset(classpath, 0, SYSFS_PATH_MAX); + if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { + dprintf("Sysfs not supported on this system\n"); + return NULL; + } + safestrcat(classpath, "/"SYSFS_CLASS_NAME); + + dir = sysfs_open_directory(classpath); + if (dir = NULL) + return NULL; + + struct dlist *clslist = NULL; + struct sysfs_class *class = NULL; + + clslist = dlist_new_with_delete(sizeof(struct sysfs_class), + sysfs_close_class_classes); + + if (sysfs_read_dir_subdirs(dir) = 0) { + dirlist = dir->subdirs; + dlist_for_each_data(dirlist, sdir, struct sysfs_directory) { + class = sysfs_open_class(sdir->name); + dlist_unshift(clslist, class); + } + } + sysfs_close_directory(dir); + return clslist; +} + +void sysfs_close_classes(struct dlist *clslist) +{ + if (clslist != NULL) + dlist_destroy(clslist); +} diff -Nru a/udevstart.c b/udevstart.c --- a/udevstart.c 2004-09-14 13:55:36.000000000 +0800 +++ b/udevstart.c 2004-09-16 04:43:52.697128120 +0800 @@ -37,6 +37,8 @@ #include "udev_lib.h" #include "list.h" #include "udev.h" +#include "libsysfs/sysfs/libsysfs.h" +#include "libsysfs/dlist.h" #define MAX_PATHLEN 1024 @@ -191,66 +193,30 @@ static void udev_scan_class(void) { - DIR *dir; - struct dirent *dent; LIST_HEAD(device_list); - - dir = opendir(SYSCLASS); - if (dir != NULL) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[MAX_PATHLEN]; - DIR *dir2; - struct dirent *dent2; - - if ((strcmp(dent->d_name, ".") = 0) || - (strcmp(dent->d_name, "..") = 0)) - continue; - - snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); - dirname[MAX_PATHLEN-1] = '\0'; - dir2 = opendir(dirname); - if (dir2 != NULL) { - for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN-1]; - DIR *dir3; - struct dirent *dent3; - - if ((strcmp(dent2->d_name, ".") = 0) || - (strcmp(dent2->d_name, "..") = 0)) - continue; - - /* pass the net class as it is */ - if (strcmp(dent->d_name, "net") = 0) { - snprintf(dirname2, MAX_PATHLEN, "/class/net/%s", dent2->d_name); - device_list_insert(dirname2, "net", &device_list); - continue; - } - - snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); - dirname2[MAX_PATHLEN-1] = '\0'; - dir3 = opendir(dirname2); - if (dir3 != NULL) { - for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { - char filename[MAX_PATHLEN]; - - /* pass devices with a "dev" file */ - if (strcmp(dent3->d_name, "dev") = 0) { - snprintf(filename, MAX_PATHLEN, "/class/%s/%s", - dent->d_name, dent2->d_name); - filename[MAX_PATHLEN-1] = '\0'; - device_list_insert(filename, dent->d_name, &device_list); - break; - } - } - closedir(dir3); + char filename[MAX_PATHLEN]; + struct dlist *clslist = NULL; + struct sysfs_class *class = NULL; + struct sysfs_class_device *device = NULL; + struct dlist *devlist = NULL; + clslist = sysfs_open_classes(); + dlist_for_each_data(clslist, class, struct sysfs_class) { + if (class != NULL) { + devlist = sysfs_get_class_devices(class); + if (devlist != NULL) { + dlist_for_each_data(devlist, device, + struct sysfs_class_device) { + if (sysfs_get_classdev_attr(device, "dev") != NULL || + strcmp(class->name, "net") = 0) { + snprintf(filename, MAX_PATHLEN, "/class/%s/%s", + class->name, device->name); + device_list_insert(filename, class->name, &device_list); } } - closedir(dir2); } } - closedir(dir); } - + sysfs_close_classes(clslist); exec_list(&device_list); } ------------------------------------------------------- This SF.Net email is sponsored by: thawte's Crypto Challenge Vl Crack the code and win a Sony DCRHC40 MiniDV Digital Handycam Camcorder. More prizes in the weekly Lunch Hour Challenge. Sign up NOW http://ad.doubleclick.net/clk;10740251;10262165;m _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel