summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormananth <mananth>2004-02-04 10:51:50 +0000
committermananth <mananth>2004-02-04 10:51:50 +0000
commit6cbd7ae67a04b1f0c3269ab3aae2d8ee0efa5a89 (patch)
treeab728dfb40bed686bf802e7e92545e02ea8131b6
parent06d8ed8e147b05fd41c4ba0a36b7c67760d181a9 (diff)
downloadsysfsutils-6cbd7ae67a04b1f0c3269ab3aae2d8ee0efa5a89.tar.gz
Sorting support, removed unneeded functions and other cosmetic changes
-rw-r--r--ChangeLog14
-rw-r--r--cmd/systool.c4
-rw-r--r--include/dlist.h1
-rw-r--r--include/libsysfs.h31
-rw-r--r--lib/dlist.c10
-rw-r--r--lib/sysfs_bus.c47
-rw-r--r--lib/sysfs_class.c2
-rw-r--r--lib/sysfs_device.c15
-rw-r--r--lib/sysfs_dir.c10
-rw-r--r--lib/sysfs_driver.c5
-rw-r--r--lib/sysfs_utils.c44
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 <ananth@in.ibm.com>
+02/04/2004 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
+ * Added list sorting support
+ * Exported get_device_bus()
+ * Removed sysfs_open_bus_device()
+ * Other cosmetic changes
+
+01/07/2004 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
* Modified parameter order for "open" functions to make them
consistent
-01/07/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
+01/07/2004 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
* Added additional CFLAGS for building lib and apps
-01/07/2003 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
+01/07/2004 - Ananth Mavinakayanahalli <ananth@in.ibm.com>
* 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 <mort@bork.org>
+01/07/2004 - Martin Hicks <mort@bork.org>
* Fixed sysfs_get_class_device()
12/26/2003 - Daniel Stekloff <dsteklof@us.ibm.com>
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 <sys/types.h>
+#include <string.h>
#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);
@@ -354,49 +354,6 @@ struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
}
/**
- * 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
* @busname: buffer to copy name to
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);