From 6cbd7ae67a04b1f0c3269ab3aae2d8ee0efa5a89 Mon Sep 17 00:00:00 2001 From: mananth Date: Wed, 4 Feb 2004 10:51:50 +0000 Subject: Sorting support, removed unneeded functions and other cosmetic changes --- ChangeLog | 14 ++++++++++---- cmd/systool.c | 4 ++++ include/dlist.h | 1 + include/libsysfs.h | 31 +++++++++++++++++++++++++++---- lib/dlist.c | 10 ++++++++++ lib/sysfs_bus.c | 47 ++--------------------------------------------- lib/sysfs_class.c | 2 +- lib/sysfs_device.c | 15 ++++++++------- lib/sysfs_dir.c | 10 +++++----- lib/sysfs_driver.c | 5 +++-- lib/sysfs_utils.c | 44 +++++++++++++++++++++++++++----------------- 11 files changed, 98 insertions(+), 85 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ee8752..5d5d8f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,17 +1,23 @@ -01/07/2003 - Ananth Mavinakayanahalli +02/04/2004 - Ananth Mavinakayanahalli + * Added list sorting support + * Exported get_device_bus() + * Removed sysfs_open_bus_device() + * Other cosmetic changes + +01/07/2004 - Ananth Mavinakayanahalli * Modified parameter order for "open" functions to make them consistent -01/07/2003 - Ananth Mavinakayanahalli +01/07/2004 - Ananth Mavinakayanahalli * Added additional CFLAGS for building lib and apps -01/07/2003 - Ananth Mavinakayanahalli +01/07/2004 - Ananth Mavinakayanahalli * Added numerous "refresh" functions * Added funtion to remove trailing slash from paths * Fixed sysfs_get_link() to handle different possibilities -01/07/2003 - Martin Hicks +01/07/2004 - Martin Hicks * Fixed sysfs_get_class_device() 12/26/2003 - Daniel Stekloff diff --git a/cmd/systool.c b/cmd/systool.c index 89d6feb..6ecfb15 100644 --- a/cmd/systool.c +++ b/cmd/systool.c @@ -365,6 +365,8 @@ static void show_device_tree(struct sysfs_device *root, int level) if (root->children != NULL) { dlist_for_each_data(root->children, cur, struct sysfs_device) { + if (strncmp(cur->name, "power", 5) == 0) + continue; show_device_tree(cur, (level+6)); } } @@ -520,6 +522,8 @@ static int show_sysfs_root(unsigned char *rootname) if (devlist != NULL) { dlist_for_each_data(devlist, device, struct sysfs_device) { + if (strncmp(device->name, "power", 5) == 0) + continue; show_device_tree(device, 2); } } diff --git a/include/dlist.h b/include/dlist.h index 5da79f9..1616a1b 100644 --- a/include/dlist.h +++ b/include/dlist.h @@ -84,6 +84,7 @@ void dlist_delete(Dlist *,int); void dlist_push(Dlist *,void *); void dlist_unshift(Dlist *,void *); +void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *)); void *dlist_pop(Dlist *); diff --git a/include/libsysfs.h b/include/libsysfs.h index 451830f..10cad36 100644 --- a/include/libsysfs.h +++ b/include/libsysfs.h @@ -24,6 +24,7 @@ #define _LIBSYSFS_H_ #include +#include #include "dlist.h" /* @@ -47,12 +48,17 @@ #define SYSFS_METHOD_SHOW 0x01 /* attr can be read by user */ #define SYSFS_METHOD_STORE 0x02 /* attr can be changed by user */ +/* + * NOTE: We have the statically allocated "name" as the first element of all + * the structures. This feature is used in the "sorter" function for dlists + */ + struct sysfs_attribute { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; unsigned char *value; unsigned short len; /* value length */ unsigned short method; /* show and store */ - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; }; struct sysfs_link { @@ -215,6 +221,7 @@ extern struct sysfs_device *sysfs_open_device (const unsigned char *bus, const unsigned char *bus_id); extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev); extern struct sysfs_device *sysfs_open_device_path(const unsigned char *path); +extern int sysfs_get_device_bus(struct sysfs_device *dev); extern struct sysfs_attribute *sysfs_get_device_attr (struct sysfs_device *dev, const unsigned char *name); extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); @@ -236,8 +243,6 @@ extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus); extern struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus); extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, unsigned char *attrname); -extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, - unsigned char *dev_id); extern int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, size_t bsize); @@ -268,6 +273,24 @@ extern struct sysfs_attribute *sysfs_open_classdev_attr (const unsigned char *classname, const unsigned char *dev, const unsigned char *attrib); +/** + * sort_list: sorter function to keep list elements sorted in alphabetical + * order. Just does a strncmp as you can see :) + * + * Returns 1 if less than 0 otherwise + * + * NOTE: We take care to have a statically allocated "name" as the first + * lement of all libsysfs structures. Hence, this function will work + * AS IS for _ALL_ the lists that have to be sorted. + */ +static inline int sort_list(void *new, void *old) +{ + return ((strncmp(((struct sysfs_attribute *)new)->name, + ((struct sysfs_attribute *)old)->name, + strlen(((struct sysfs_attribute *)new)->name))) < 0 ? 1 : 0); +} + + #ifdef __cplusplus } #endif diff --git a/lib/dlist.c b/lib/dlist.c index 6dfcf72..7620653 100644 --- a/lib/dlist.c +++ b/lib/dlist.c @@ -259,6 +259,16 @@ void dlist_unshift(Dlist *list,void *data) dlist_insert(list,data,0); } +void dlist_unshift_sorted(Dlist *list, void *data, + int (*sorter)(void *new, void *old)) +{ + if (list->count == 0) + dlist_unshift(list, data); + else { + list->marker=list->head->next; + dlist_insert_sorted(list, data, sorter); + } +} /* * Remove end node from list. diff --git a/lib/sysfs_bus.c b/lib/sysfs_bus.c index aca3928..821938c 100644 --- a/lib/sysfs_bus.c +++ b/lib/sysfs_bus.c @@ -133,7 +133,7 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) bus->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev); - dlist_unshift(bus->devices, bdev); + dlist_unshift_sorted(bus->devices, bdev, sort_list); } } sysfs_close_directory(devdir); @@ -182,7 +182,7 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) bus->drivers = dlist_new_with_delete (sizeof(struct sysfs_driver), sysfs_close_drv); - dlist_unshift(bus->drivers, driver); + dlist_unshift_sorted(bus->drivers, driver, sort_list); } } sysfs_close_directory(drvdir); @@ -353,49 +353,6 @@ struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, return sysfs_get_directory_attribute(bus->directory, attrname); } -/** - * sysfs_open_bus_device: locates a device on a bus and returns it. Device - * must be closed using sysfs_close_device. - * @busname: Name of bus to search - * @dev_id: Id of device on bus. - * returns sysfs_device if found or NULL if not. - */ -struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, - unsigned char *dev_id) -{ - struct sysfs_device *rdev = NULL; - char path[SYSFS_PATH_MAX]; - - if (busname == NULL || dev_id == NULL) { - errno = EINVAL; - return NULL; - } - - memset(path, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) { - dprintf("Error getting sysfs mount point\n"); - return NULL; - } - - strcat(path, "/"); - strcat(path, SYSFS_BUS_NAME); - strcat(path, "/"); - strcat(path, busname); - strcat(path, "/"); - strcat(path, SYSFS_DEVICES_NAME); - strcat(path, "/"); - strcat(path, dev_id); - - rdev = sysfs_open_device_path(path); - if (rdev == NULL) { - dprintf("Error getting device %s on bus %s\n", - dev_id, busname); - return NULL; - } - - return rdev; -} - /** * sysfs_find_driver_bus: locates the bus the driver is on. * @driver: name of the driver to locate diff --git a/lib/sysfs_class.c b/lib/sysfs_class.c index 600be00..ba6897b 100644 --- a/lib/sysfs_class.c +++ b/lib/sysfs_class.c @@ -210,7 +210,7 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) cls->devices = dlist_new_with_delete (sizeof(struct sysfs_class_device), sysfs_close_cls_dev); - dlist_unshift(cls->devices, dev); + dlist_unshift_sorted(cls->devices, dev, sort_list); } } return cls->devices; diff --git a/lib/sysfs_device.c b/lib/sysfs_device.c index 6365276..3b2030d 100644 --- a/lib/sysfs_device.c +++ b/lib/sysfs_device.c @@ -24,12 +24,12 @@ #include "sysfs.h" /** - * get_device_bus: retrieves the bus name the device is on, checks path to - * bus' link to make sure it has correct device. + * sysfs_get_device_bus: retrieves the bus name the device is on, checks path + * to bus' link to make sure it has correct device. * @dev: device to get busname. * returns 0 with success and -1 with error. */ -static int get_device_bus(struct sysfs_device *dev) +int sysfs_get_device_bus(struct sysfs_device *dev) { unsigned char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX]; unsigned char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL; @@ -209,8 +209,8 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path) */ strncpy(dev->name, dev->bus_id, SYSFS_NAME_LEN); - if (get_device_bus(dev) != 0) - strcpy(dev->bus, SYSFS_UNKNOWN); + if (sysfs_get_device_bus(dev) != 0) + dprintf("Could not get device bus\n"); return dev; } @@ -255,7 +255,8 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path) rootdev->children = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev_tree); - dlist_unshift(rootdev->children, new); + dlist_unshift_sorted(rootdev->children, + new, sort_list); } } @@ -311,7 +312,7 @@ struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root) root->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev_tree); - dlist_unshift(root->devices, dev); + dlist_unshift_sorted(root->devices, dev, sort_list); } return root->devices; diff --git a/lib/sysfs_dir.c b/lib/sysfs_dir.c index 94fd933..5fbd019 100644 --- a/lib/sysfs_dir.c +++ b/lib/sysfs_dir.c @@ -327,7 +327,7 @@ int sysfs_read_attribute_value(const unsigned char *attrpath, struct sysfs_attribute *attr = NULL; size_t length = 0; - if (attrpath == NULL || value == NULL) { + if (attrpath == NULL || value == NULL || vsize == 0) { errno = EINVAL; return -1; } @@ -466,7 +466,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path) } if (sysfs_path_is_dir(path) != 0) { - dprintf("Invalid path directory %s\n", path); + dprintf("Invalid path to directory %s\n", path); errno = EINVAL; return NULL; } @@ -544,7 +544,7 @@ static int add_attribute(struct sysfs_directory *sysdir, sysdir->attributes = dlist_new_with_delete (sizeof(struct sysfs_attribute), sysfs_del_attribute); } - dlist_unshift(sysdir->attributes, attr); + dlist_unshift_sorted(sysdir->attributes, attr, sort_list); return 0; } @@ -568,7 +568,7 @@ static int add_subdirectory(struct sysfs_directory *sysdir, if (sysdir->subdirs == NULL) sysdir->subdirs = dlist_new_with_delete (sizeof(struct sysfs_directory), sysfs_del_directory); - dlist_unshift(sysdir->subdirs, subdir); + dlist_unshift_sorted(sysdir->subdirs, subdir, sort_list); return 0; } @@ -590,7 +590,7 @@ static int add_link(struct sysfs_directory *sysdir, const unsigned char *path) if (sysdir->links == NULL) sysdir->links = dlist_new_with_delete (sizeof(struct sysfs_link), sysfs_del_link); - dlist_unshift(sysdir->links, ln); + dlist_unshift_sorted(sysdir->links, ln, sort_list); return 0; } diff --git a/lib/sysfs_driver.c b/lib/sysfs_driver.c index 636219a..6a7cf68 100644 --- a/lib/sysfs_driver.c +++ b/lib/sysfs_driver.c @@ -178,7 +178,7 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, } attrlist = sysfs_get_driver_attributes(drv); - if (attrlist != NULL) + if (attrlist == NULL) return NULL; return sysfs_get_directory_attribute(drv->directory, @@ -244,7 +244,8 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) driver->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_driver_device); - dlist_unshift(driver->devices, device); + dlist_unshift_sorted(driver->devices, device, + sort_list); } } return (driver->devices); diff --git a/lib/sysfs_utils.c b/lib/sysfs_utils.c index b8de9bd..b7295d6 100644 --- a/lib/sysfs_utils.c +++ b/lib/sysfs_utils.c @@ -23,6 +23,12 @@ #include "libsysfs.h" #include "sysfs.h" +static int sort_char(void *new, void *old) +{ + return ((strncmp((unsigned char *)new, (unsigned char *)old, + strlen((unsigned char *)new))) < 0 ? 1 : 0); +} + /** * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path * @path: Path to look for the trailing '/' @@ -48,7 +54,7 @@ int sysfs_remove_trailing_slash(unsigned char *path) } /** - * sysfs_get_mnt_path: Gets the mount point for specified filesystem. + * sysfs_get_fs_mnt_path: Gets the mount point for specified filesystem. * @fs_type: filesystem type to retrieve mount point * @mnt_path: place to put the retrieved mount path * @len: size of mnt_path @@ -63,7 +69,7 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, size_t dirlen = 0; /* check arg */ - if (fs_type == NULL || mnt_path == NULL) { + if (fs_type == NULL || mnt_path == NULL || len == 0) { errno = EINVAL; return -1; } @@ -106,7 +112,7 @@ int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) char *sysfs_path = NULL; int ret = 0; - if (mnt_path == NULL) { + if (mnt_path == NULL || len == 0) { errno = EINVAL; return -1; } @@ -133,7 +139,7 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, unsigned char tmp[SYSFS_PATH_MAX]; unsigned char *n = NULL; - if (path == NULL || name == NULL) { + if (path == NULL || name == NULL || len == 0) { errno = EINVAL; return -1; } @@ -167,16 +173,18 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) { unsigned char devdir[SYSFS_PATH_MAX]; unsigned char linkpath[SYSFS_PATH_MAX]; + unsigned char temp_path[SYSFS_PATH_MAX]; unsigned char *d = NULL, *s = NULL; int slashes = 0, count = 0; - if (path == NULL || target == NULL) { + if (path == NULL || target == NULL || len == 0) { errno = EINVAL; return -1; } memset(devdir, 0, SYSFS_PATH_MAX); memset(linkpath, 0, SYSFS_PATH_MAX); + memset(temp_path, 0, SYSFS_PATH_MAX); strncpy(devdir, path, SYSFS_PATH_MAX); if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) { @@ -194,18 +202,19 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) /* * handle the case where link is of type ./abcd/xxx */ - strncpy(target, devdir, len); + strncpy(temp_path, devdir, SYSFS_PATH_MAX); if (*(d+1) == '/') d += 2; else if (*(d+1) == '.') goto parse_path; - s = strrchr(target, '/'); + s = strrchr(temp_path, '/'); if (s != NULL) { *(s+1) = '\0'; - strcat(target, d); + strcat(temp_path, d); } else { - strcpy(target, d); + strcpy(temp_path, d); } + strncpy(target, temp_path, len); break; /* * relative path @@ -233,14 +242,15 @@ parse_path: break; default: /* relative path from this directory */ - strncpy(target, devdir, len); - s = strrchr(target, '/'); + strncpy(temp_path, devdir, len); + s = strrchr(temp_path, '/'); if (s != NULL) { *(s+1) = '\0'; - strcat(target, linkpath); + strcat(temp_path, linkpath); } else { - strcpy(target, linkpath); - } + strncpy(temp_path, linkpath, len); + } + strncpy(target, temp_path, len); } return 0; } @@ -314,7 +324,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) struct sysfs_directory) { subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); strcpy(subsys_name, cur->name); - dlist_unshift(list, subsys_name); + dlist_unshift_sorted(list, subsys_name, sort_char); } } sysfs_close_directory(dir); @@ -331,7 +341,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) if ((sysfs_path_is_dir(sysfs_path)) == 0) { subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); strcpy(subsys_name, SYSFS_BLOCK_NAME); - dlist_unshift(list, subsys_name); + dlist_unshift_sorted(list, subsys_name, sort_char); } } out: @@ -390,7 +400,7 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) struct sysfs_link) { device_name = (char *)calloc(1, SYSFS_NAME_LEN); strcpy(device_name, cur->name); - dlist_unshift(list, device_name); + dlist_unshift_sorted(list, device_name, sort_char); } } sysfs_close_directory(dir); -- cgit v1.2.1