chiark / gitweb /
[PATCH] libsysfs 0.4.0 patch
authordsteklof@us.ibm.com <dsteklof@us.ibm.com>
Sat, 20 Dec 2003 02:29:10 +0000 (18:29 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:13:09 +0000 (21:13 -0700)
Ananth released sysfsutils 0.4.0 last night, I'm sure you saw the email.
Here's a patch with the latest changes from the pre-patch I already
gave you. It includes sysfs_get_device_parent(), which you said you
needed. I've run your test scripts and I've built scsi_id. Please
play around with this and check it out.

There are quite a few changes. Please do not access
structure pointers, like sysfs_device's parent, directly like
dev->parent. Please use the "get" function to retrieve. The functions
load things on demand and refresh views under the covers.

extras/scsi_id/scsi_id.c
libsysfs/libsysfs.h
libsysfs/sysfs_bus.c
libsysfs/sysfs_class.c
libsysfs/sysfs_device.c
libsysfs/sysfs_dir.c
libsysfs/sysfs_driver.c
libsysfs/sysfs_utils.c
udev-add.c

index 3a34643..6bb4113 100644 (file)
@@ -158,7 +158,7 @@ static int get_major_minor(const char *devpath, int *major, int *minor)
        char *dev;
 
        dprintf("%s\n", devpath);
-       class_dev = sysfs_open_class_device(devpath);
+       class_dev = sysfs_open_class_device_path(devpath);
        if (!class_dev) {
                log_message(LOG_WARNING, "open class %s failed: %s\n", devpath,
                            strerror(errno));
@@ -708,7 +708,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev)
                return 1;
        }
 
-       scsi_dev = sysfs_open_class_device(full_dev_path);
+       scsi_dev = sysfs_open_class_device_path(full_dev_path);
        if (!scsi_dev) {
                log_message(LOG_WARNING, "open class %s failed: %s\n",
                            full_dev_path, strerror(errno));
index aca2577..2ffe100 100644 (file)
@@ -182,7 +182,9 @@ extern struct sysfs_attribute *sysfs_get_directory_attribute
 
 /* sysfs driver access */
 extern void sysfs_close_driver(struct sysfs_driver *driver);
-extern struct sysfs_driver *sysfs_open_driver(const unsigned char *path);
+extern struct sysfs_driver *sysfs_open_driver
+       (const unsigned char *drv_name, const unsigned char *bus_name);
+extern struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path);
 extern struct sysfs_attribute *sysfs_get_driver_attr
                (struct sysfs_driver *drv, const unsigned char *name);
 extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver);
@@ -199,12 +201,13 @@ extern struct sysfs_root_device *sysfs_open_root_device
                                                (const unsigned char *name);
 extern struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root);
 extern void sysfs_close_device(struct sysfs_device *dev);
-extern struct sysfs_device *sysfs_open_device(const unsigned char *path);
+extern struct sysfs_device *sysfs_open_device
+               (const unsigned char *bus_id, const unsigned char *bus);
+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 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);
-extern struct sysfs_device *sysfs_open_device_by_id
-               (const unsigned char *bus_id, const unsigned char *bus);
 extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, 
                const unsigned char *bus_id, const unsigned char *attrib);
 
@@ -227,8 +230,10 @@ extern int sysfs_find_driver_bus(const unsigned char *driver,
 
 /* generic sysfs class access */
 extern void sysfs_close_class_device(struct sysfs_class_device *dev);
-extern struct sysfs_class_device *sysfs_open_class_device
+extern struct sysfs_class_device *sysfs_open_class_device_path
                                        (const unsigned char *path);
+extern struct sysfs_class_device *sysfs_open_class_device
+       (const unsigned char *class, const unsigned char *name);
 extern struct sysfs_device *sysfs_get_classdev_device
                                (struct sysfs_class_device *clsdev);
 extern struct sysfs_driver *sysfs_get_classdev_driver
@@ -240,8 +245,6 @@ extern struct sysfs_class *sysfs_open_class(const unsigned char *name);
 extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls);
 extern struct sysfs_class_device *sysfs_get_class_device
        (struct sysfs_class *class, unsigned char *name);
-extern struct sysfs_class_device *sysfs_open_class_device_by_name
-       (const unsigned char *class, const unsigned char *name);
 extern struct dlist *sysfs_get_classdev_attributes
        (struct sysfs_class_device *cdev);
 extern struct sysfs_attribute *sysfs_get_classdev_attr
index 3e6c22b..d9da0f8 100644 (file)
@@ -121,16 +121,20 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
                return NULL;
        }
 
-       dlist_for_each_data(devdir->links, curl, struct sysfs_link) {
-               bdev = sysfs_open_device(curl->target);
-               if (bdev == NULL) {
-                       dprintf("Error opening device at %s\n", curl->target);
-                       continue;
+       if (devdir->links != 0) {
+               dlist_for_each_data(devdir->links, curl, struct sysfs_link) {
+                       bdev = sysfs_open_device_path(curl->target);
+                       if (bdev == NULL) {
+                               dprintf("Error opening device at %s\n", 
+                                                               curl->target);
+                               continue;
+                       }
+                       if (bus->devices == NULL)
+                               bus->devices = dlist_new_with_delete
+                                       (sizeof(struct sysfs_device), 
+                                                       sysfs_close_dev);
+                       dlist_unshift(bus->devices, bdev);
                }
-               if (bus->devices == NULL)
-                       bus->devices = dlist_new_with_delete
-                               (sizeof(struct sysfs_device), sysfs_close_dev);
-               dlist_unshift(bus->devices, bdev);
        }
        sysfs_close_directory(devdir);
 
@@ -165,16 +169,21 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus)
                sysfs_close_directory(drvdir);
                return NULL;
        }
-       dlist_for_each_data(drvdir->subdirs, cursub, struct sysfs_directory) {
-               driver = sysfs_open_driver(cursub->path);
-               if (driver == NULL) {
-                       dprintf("Error opening driver at %s\n", cursub->path);
-                       continue;
+       if (drvdir->subdirs != NULL) {
+               dlist_for_each_data(drvdir->subdirs, cursub, 
+                                               struct sysfs_directory) {
+                       driver = sysfs_open_driver_path(cursub->path);
+                       if (driver == NULL) {
+                               dprintf("Error opening driver at %s\n", 
+                                                               cursub->path);
+                               continue;
+                       }
+                       if (bus->drivers == NULL)
+                               bus->drivers = dlist_new_with_delete
+                                       (sizeof(struct sysfs_driver), 
+                                                       sysfs_close_drv);
+                       dlist_unshift(bus->drivers, driver);
                }
-               if (bus->drivers == NULL)
-                       bus->drivers = dlist_new_with_delete
-                               (sizeof(struct sysfs_driver), sysfs_close_drv);
-               dlist_unshift(bus->drivers, driver);
        }
        sysfs_close_directory(drvdir);
        return (bus->drivers);
@@ -347,10 +356,9 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname,
                dprintf("Error getting sysfs mount point\n");
                return NULL;
        }
-       
+
        if (sysfs_trailing_slash(path) == 0)
                strcat(path, "/");
-
        strcat(path, SYSFS_BUS_NAME);
        strcat(path, "/");
        strcat(path, busname);
@@ -359,7 +367,7 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname,
        strcat(path, "/");
        strcat(path, dev_id);
 
-       rdev = sysfs_open_device(path);
+       rdev = sysfs_open_device_path(path);
        if (rdev == NULL) {
                dprintf("Error getting device %s on bus %s\n",
                                dev_id, busname);
index 169600d..16eaf6e 100644 (file)
@@ -130,11 +130,12 @@ static void set_classdev_classname(struct sysfs_class_device *cdev)
 }
 
 /**
- * sysfs_open_class_device: Opens and populates class device
+ * sysfs_open_class_device_path: Opens and populates class device
  * @path: path to class device.
  * returns struct sysfs_class_device with success and NULL with error.
  */
-struct sysfs_class_device *sysfs_open_class_device(const unsigned char *path)
+struct sysfs_class_device *sysfs_open_class_device_path
+                                       (const unsigned char *path)
 {
        struct sysfs_class_device *cdev = NULL;
 
@@ -184,22 +185,24 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls)
                        return NULL;
        }
 
-       if ((sysfs_read_dir_subdirs(cls->directory) != 0) 
-           || cls->directory->subdirs == NULL)
+       if ((sysfs_read_dir_subdirs(cls->directory)) != 0) 
                return NULL;
 
-       dlist_for_each_data(cls->directory->subdirs, cur, 
-                       struct sysfs_directory) {
-               dev = sysfs_open_class_device(cur->path);
-               if (dev == NULL) {
-                       dprintf("Error opening device at %s\n", cur->path);
-                       continue;
-               }
-               if (cls->devices == NULL)
-                       cls->devices = dlist_new_with_delete
+       if (cls->directory->subdirs != NULL) {
+               dlist_for_each_data(cls->directory->subdirs, cur, 
+                                               struct sysfs_directory) {
+                       dev = sysfs_open_class_device_path(cur->path);
+                       if (dev == NULL) {
+                               dprintf("Error opening device at %s\n", 
+                                                               cur->path);
+                               continue;
+                       }
+                       if (cls->devices == NULL)
+                               cls->devices = dlist_new_with_delete
                                        (sizeof(struct sysfs_class_device),
                                                        sysfs_close_cls_dev);
-               dlist_unshift(cls->devices, dev);
+                       dlist_unshift(cls->devices, dev);
+               }
        }
        return cls->devices;
 }
@@ -223,7 +226,6 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name)
                 dprintf("Sysfs not supported on this system\n");
                 return NULL;
         }
-
        if (sysfs_trailing_slash(classpath) == 0)
                strcat(classpath, "/");
 
@@ -307,7 +309,7 @@ struct sysfs_device *sysfs_get_classdev_device
        if (devlink == NULL) 
                return NULL;
 
-       clsdev->sysdevice = sysfs_open_device(devlink->target);
+       clsdev->sysdevice = sysfs_open_device_path(devlink->target);
        if (clsdev->sysdevice == NULL)
                return NULL;
        if (clsdev->driver != NULL) 
@@ -343,7 +345,7 @@ struct sysfs_driver *sysfs_get_classdev_driver
        }
        drvlink = sysfs_get_directory_link(clsdev->directory, "driver");
        if (drvlink != NULL) {
-               clsdev->driver = sysfs_open_driver(drvlink->target);
+               clsdev->driver = sysfs_open_driver_path(drvlink->target);
                if (clsdev->driver == NULL)
                        return NULL;
                        
@@ -401,7 +403,7 @@ static int get_blockdev_parent(struct sysfs_class_device *clsdev)
                goto errout;
 
        *c = '\0';
-       clsdev->parent = sysfs_open_class_device(parent_path);
+       clsdev->parent = sysfs_open_class_device_path(parent_path);
        if (clsdev->parent == NULL) {
                dprintf("Error opening the parent class device at %s\n", 
                                                                parent_path);
@@ -482,7 +484,7 @@ static int get_classdev_path(const unsigned char *classname,
 }
 
 /**
- * sysfs_open_class_device_by_name: Locates a specific class_device and returns it.
+ * sysfs_open_class_device: Locates a specific class_device and returns it.
  * Class_device must be closed using sysfs_close_class_device
  * @classname: Class to search
  * @name: name of the class_device
@@ -490,7 +492,7 @@ static int get_classdev_path(const unsigned char *classname,
  * NOTE:
  *     Call sysfs_close_class_device() to close the class device
  */
-struct sysfs_class_device *sysfs_open_class_device_by_name
+struct sysfs_class_device *sysfs_open_class_device
                (const unsigned char *classname, const unsigned char *name)
 {
        unsigned char devpath[SYSFS_PATH_MAX];
@@ -509,7 +511,7 @@ struct sysfs_class_device *sysfs_open_class_device_by_name
                return NULL;
        }
        
-       cdev = sysfs_open_class_device(devpath);
+       cdev = sysfs_open_class_device_path(devpath);
        if (cdev == NULL) {
                dprintf("Error getting class device %s from class %s\n",
                                name, classname);
@@ -572,32 +574,41 @@ struct sysfs_attribute *sysfs_get_classdev_attr
                errno = EINVAL;
                return NULL;
        }
+       
        /* 
         * First, see if it's in the current directory. Then look at 
         * subdirs since class devices can have subdirs of attributes.
         */ 
        attrlist = sysfs_get_classdev_attributes(clsdev);
-       if (attrlist == NULL)
-               return NULL;
-       cur = sysfs_get_directory_attribute(clsdev->directory,
+       if (attrlist != NULL) {
+               cur = sysfs_get_directory_attribute(clsdev->directory,
                                                (unsigned char *)name);
-       if (cur != NULL)
-               return cur;
+               if (cur != NULL)
+                       return cur;
+       }
 
        if (clsdev->directory->subdirs == NULL) 
                if ((sysfs_read_dir_subdirs(clsdev->directory)) != 0 ||
                    clsdev->directory->subdirs == NULL) 
                        return NULL;
 
-       dlist_for_each_data(clsdev->directory->subdirs, sdir,
-                               struct sysfs_directory) {
-               cur = sysfs_get_directory_attribute(sdir, 
-                                               (unsigned char *)name);
-               if (cur != NULL)
-                       return cur;
+       if (clsdev->directory->subdirs != NULL) {
+               dlist_for_each_data(clsdev->directory->subdirs, sdir,
+                                               struct sysfs_directory) {
+                       if ((sysfs_path_is_dir(sdir->path)) != 0) 
+                               continue;
+                       if (sdir->attributes == NULL) {
+                               cur = sysfs_get_directory_attribute(sdir,
+                                                       (unsigned char *)name);
+                       } else {
+                               if ((sysfs_refresh_attributes
+                                               (sdir->attributes)) == 0)
+                               cur = sysfs_get_directory_attribute(sdir, 
+                                                       (unsigned char *)name);
+                       }
+               }
        }
-               
-       return NULL;
+       return cur;
 }
 
 /**
@@ -643,3 +654,4 @@ struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname,
        }
        return attribute;
 }
+
index 82b5471..66d5f9a 100644 (file)
@@ -105,14 +105,6 @@ static void sysfs_close_device_tree(struct sysfs_device *devroot)
 }
 
 /**
- * sysfs_del_device: routine for dlist integration
- */
-static void sysfs_del_device(void *dev)
-{
-       sysfs_close_device((struct sysfs_device *)dev);
-}
-
-/**
  * sysfs_close_dev_tree: routine for dlist integration
  */
 static void sysfs_close_dev_tree(void *dev)
@@ -127,6 +119,8 @@ static void sysfs_close_dev_tree(void *dev)
 void sysfs_close_device(struct sysfs_device *dev)
 {
        if (dev != NULL) {
+               if (dev->parent != NULL)
+                       sysfs_close_device(dev->parent);
                if (dev->directory != NULL)
                        sysfs_close_directory(dev->directory);
                if (dev->children != NULL && dev->children->count == 0)
@@ -164,7 +158,7 @@ static struct sysfs_directory *open_device_dir(const unsigned char *path)
                dprintf ("Device %s not supported on this system\n", path);
                return NULL;
        }
-       if ((sysfs_read_directory(rdir)) != 0) {
+       if ((sysfs_read_dir_subdirs(rdir)) != 0) {
                dprintf ("Error reading device at dir %s\n", path);
                sysfs_close_directory(rdir);
                return NULL;
@@ -174,11 +168,11 @@ static struct sysfs_directory *open_device_dir(const unsigned char *path)
 }
 
 /**
- * sysfs_open_device: opens and populates device structure
+ * sysfs_open_device_path: opens and populates device structure
  * @path: path to device, this is the /sys/devices/ path
  * returns sysfs_device structure with success or NULL with error
  */
-struct sysfs_device *sysfs_open_device(const unsigned char *path)
+struct sysfs_device *sysfs_open_device_path(const unsigned char *path)
 {
        struct sysfs_device *dev = NULL;
 
@@ -232,7 +226,7 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path)
                errno = EINVAL;
                return NULL;
        }
-       rootdev = sysfs_open_device(path);
+       rootdev = sysfs_open_device_path(path);
        if (rootdev == NULL) {
                dprintf("Error opening root device at %s\n", path);
                return NULL;
@@ -255,7 +249,7 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path)
                        if (rootdev->children == NULL)
                                rootdev->children = dlist_new_with_delete
                                        (sizeof(struct sysfs_device),
-                                       sysfs_del_device);
+                                       sysfs_close_dev_tree);
                        dlist_unshift(rootdev->children, new);
                }
        }
@@ -342,7 +336,6 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name)
 
        if (sysfs_trailing_slash(rootpath) == 0)
                strcat(rootpath, "/");
-
        strcat(rootpath, SYSFS_DEVICES_NAME);
        strcat(rootpath, "/");
        strcat(rootpath, name);
@@ -357,6 +350,7 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name)
                dprintf("calloc failure\n");
                return NULL;
        }
+       strcpy(root->name, name);
        strcpy(root->path, rootpath);
        return root;
 }
@@ -416,10 +410,8 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev,
 
        cur = sysfs_get_directory_attribute(dev->directory, 
                        (unsigned char *)name);
-       if (cur != NULL)
-               return cur;
 
-       return NULL;
+       return cur;
 }
 
 /**
@@ -445,10 +437,8 @@ static int get_device_absolute_path(const unsigned char *device,
                dprintf ("Sysfs not supported on this system\n");
                return -1;
        }
-
        if (sysfs_trailing_slash(bus_path) == 0)
                strcat(bus_path, "/");
-
        strcat(bus_path, SYSFS_BUS_NAME);
        strcat(bus_path, "/");
        strcat(bus_path, bus);
@@ -468,7 +458,7 @@ static int get_device_absolute_path(const unsigned char *device,
 }
 
 /**
- * sysfs_open_device_by_id: open a device by id (use the "bus" subsystem)
+ * sysfs_open_device: open a device by id (use the "bus" subsystem)
  * @bus_id: bus_id of the device to open - has to be the "bus_id" in 
  *             /sys/bus/xxx/devices
  * @bus: bus the device belongs to
@@ -478,7 +468,7 @@ static int get_device_absolute_path(const unsigned char *device,
  * 2. Bus the device is on must be supplied
  *     Use sysfs_find_device_bus to get the bus name
  */
-struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, 
+struct sysfs_device *sysfs_open_device(const unsigned char *bus_id, 
                                                const unsigned char *bus)
 {
        char sysfs_path[SYSFS_PATH_MAX];
@@ -495,7 +485,7 @@ struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id,
                return NULL;
        }
        
-       device = sysfs_open_device(sysfs_path);
+       device = sysfs_open_device_path(sysfs_path);
        if (device == NULL) {
                dprintf("Error opening device %s\n", bus_id);
                return NULL;
@@ -504,6 +494,60 @@ struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id,
        return device;
 }
 
+/**
+ * sysfs_get_device_parent: opens up given device's parent and returns a 
+ *     reference to its sysfs_device
+ * @dev: sysfs_device whose parent is requested
+ * Returns sysfs_device of the parent on success and NULL on failure
+ */
+struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev)
+{
+       unsigned char ppath[SYSFS_PATH_MAX], *tmp = NULL;
+
+       if (dev == NULL) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if (dev->parent != NULL)
+               return (dev->parent);
+
+       memset(ppath, 0, SYSFS_PATH_MAX);
+       strcpy(ppath, dev->path);
+       tmp = strrchr(ppath, '/');
+       if (tmp == NULL) {
+               dprintf("Invalid path to device %s\n", ppath);
+               return NULL;
+       }
+       if (*(tmp +1) == '\0') {
+               *tmp = '\0';
+               tmp = strrchr(tmp, '/');
+               if (tmp == NULL) {
+                       dprintf("Invalid path to device %s\n", ppath);
+                       return NULL;
+               }
+       }
+       *tmp = '\0';
+       
+       /*
+        * All "devices" have the "detach_state" attribute - validate here
+        */
+       strcat(ppath, "/detach_state");
+       if ((sysfs_path_is_file(ppath)) != 0) {
+               dprintf("Device at %s does not have a parent\n", dev->path);
+               return NULL;
+       }
+       tmp = strrchr(ppath, '/');
+       *tmp = '\0';
+       dev->parent = sysfs_open_device_path(ppath);
+       if (dev->parent == NULL) {
+               dprintf("Error opening device %s's parent at %s\n", 
+                                       dev->bus_id, ppath);
+               return NULL;
+       }
+       return (dev->parent);
+}
+
 /*
  * sysfs_open_device_attr: open the given device's attribute
  * @bus: Bus on which to look
index ac2ecfc..7dbee8a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * syfs_dir.c
+ * sysfs_dir.c
  *
  * Directory utility functions for libsysfs
  *
@@ -147,7 +147,7 @@ struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path)
                sysfs_close_attribute(sysattr);
                return NULL;
        }
-       strncpy(sysattr->path, path, sizeof(sysattr->path));
+       strncpy(sysattr->path, path, SYSFS_PATH_MAX);
        if ((stat(sysattr->path, &fileinfo)) != 0) {
                dprintf("Stat failed: No such attribute?\n");
                sysattr->method = 0;
@@ -260,7 +260,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr)
 {
        unsigned char *fbuf = NULL;
        unsigned char *vbuf = NULL;
-       size_t length = 0;
+       ssize_t length = 0;
        long pgsize = 0;
        int fd;
 
@@ -441,13 +441,15 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir)
                return -1;
        }
        if (sysdir->subdirs == NULL) 
-               if ((sysfs_read_dir_subdirs(sysdir) != 0) 
-                   || sysdir->subdirs == NULL)
+               if ((sysfs_read_dir_subdirs(sysdir)) != 0) 
                        return 0;
-       dlist_for_each_data(sysdir->subdirs, cursub, struct sysfs_directory) {
-               if ((sysfs_read_directory(cursub)) != 0) 
-                       dprintf ("Error reading subdirectory %s\n",
-                               cursub->name);
+       if (sysdir->subdirs != NULL) {
+               dlist_for_each_data(sysdir->subdirs, cursub, 
+                                               struct sysfs_directory) {
+                       if ((sysfs_read_dir_subdirs(cursub)) != 0) 
+                               dprintf ("Error reading subdirectory %s\n",
+                                               cursub->name);
+               }
        }
        return 0;
 }
@@ -476,7 +478,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path)
                sysfs_close_directory(sdir);
                return NULL;
        }
-       strncpy(sdir->path, path, sizeof(sdir->path));
+       strncpy(sdir->path, path, SYSFS_PATH_MAX);
 
        return sdir;
 }
@@ -527,7 +529,8 @@ int sysfs_refresh_attributes(struct dlist *attrlist)
        dlist_for_each_data(attrlist, attr, struct sysfs_attribute) {
                if (attr->method & SYSFS_METHOD_SHOW) {
                        if ((sysfs_read_attribute(attr)) != 0) {
-                               dprintf("Error reading attribute %s\n", attr->path);
+                               dprintf("Error reading attribute %s\n", 
+                                                               attr->path);
                                if ((sysfs_path_is_file(attr->path)) != 0) {
                                        dprintf("Attr %s no longer exists\n", 
                                                                attr->name);
@@ -540,12 +543,6 @@ int sysfs_refresh_attributes(struct dlist *attrlist)
                        }
                }
        }
-       if (attrlist->count == 0) {
-               dprintf("No attributes in the list, destroying list now\n");
-               dlist_destroy(attrlist);
-               attrlist = NULL;
-               return 1;
-       }
        return 0;
 }
 
@@ -655,9 +652,9 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, sizeof(file_path));
-               strncat(file_path, "/", sizeof(file_path));
-               strncat(file_path, dirent->d_name, sizeof(file_path));
+               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
+               strcat(file_path, "/");
+               strcat(file_path, dirent->d_name);
                if ((lstat(file_path, &astats)) != 0) {
                        dprintf("stat failed\n");
                        continue;
@@ -697,9 +694,9 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, sizeof(file_path));
-               strncat(file_path, "/", sizeof(file_path));
-               strncat(file_path, dirent->d_name, sizeof(file_path));
+               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
+               strcat(file_path, "/");
+               strcat(file_path, dirent->d_name);
                if ((lstat(file_path, &astats)) != 0) {
                        dprintf("stat failed\n");
                        continue;
@@ -742,9 +739,9 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, sizeof(file_path));
-               strncat(file_path, "/", sizeof(file_path));
-               strncat(file_path, dirent->d_name, sizeof(file_path));
+               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
+               strcat(file_path, "/");
+               strcat(file_path, dirent->d_name);
                if ((lstat(file_path, &astats)) != 0) {
                        dprintf("stat failed\n");
                        continue;
@@ -784,9 +781,9 @@ int sysfs_read_directory(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, sizeof(file_path));
-               strncat(file_path, "/", sizeof(file_path));
-               strncat(file_path, dirent->d_name, sizeof(file_path));
+               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
+               strcat(file_path, "/");
+               strcat(file_path, dirent->d_name);
                if ((lstat(file_path, &astats)) != 0) {
                        dprintf("stat failed\n");
                        continue;
@@ -829,26 +826,20 @@ struct sysfs_attribute *sysfs_get_directory_attribute
 
        attr = (struct sysfs_attribute *)dlist_find_custom
                        (dir->attributes, attrname, dir_attribute_name_equal);
-       if (attr != NULL) {
-               /*
-                * don't read here since we would have read the attribute in 
-                * in the routine that called this routine
-                */ 
-               return attr;
-       } else {
+       if (attr == NULL) {
                memset(new_path, 0, SYSFS_PATH_MAX);
                strcpy(new_path, dir->path);
                strcat(new_path, "/");
                strcat(new_path, attrname);
                if ((sysfs_path_is_file(new_path)) == 0) {
                        if ((add_attribute(dir, new_path)) == 0) {
-                               attr = (struct sysfs_attribute *)dlist_find_custom
-                                       (dir->attributes, attrname, dir_attribute_name_equal);
+                               attr = (struct sysfs_attribute *)
+                                       dlist_find_custom(dir->attributes, 
+                                       attrname, dir_attribute_name_equal);
                        }
-                       return attr;
                }
        }
-       return NULL;
+       return attr;
 }
 
 /**
index 4372b19..695ca79 100644 (file)
@@ -66,29 +66,6 @@ static int open_driver_dir(struct sysfs_driver *driver)
 }
 
 /**
- * read_driver_dir: Read driver directory's subdirs and links
- * @driver: Driver to read
- * Returns 0 on success and 1 on failure
- */
-static int read_driver_dir(struct sysfs_driver *driver)
-{
-       if (driver == NULL) {
-               errno = EINVAL;
-               return 1;
-       }
-       if (driver->directory == NULL) {
-               if ((open_driver_dir(driver)) == 1)
-                       return 1;
-       }
-       if ((sysfs_read_directory(driver->directory)) != 0) {
-               dprintf("Error reading driver directory at %s\n", 
-                               driver->path);
-               return 1;
-       }
-       return 0;
-}
-
-/**
  * alloc_driver: allocates and initializes driver
  * returns struct sysfs_driver with success and NULL with error.
  */
@@ -98,11 +75,11 @@ static struct sysfs_driver *alloc_driver(void)
 }
 
 /**
- * sysfs_open_driver: opens and initializes driver structure
+ * sysfs_open_driver_path: opens and initializes driver structure
  * @path: path to driver directory
  * returns struct sysfs_driver with success and NULL with error
  */
-struct sysfs_driver *sysfs_open_driver(const unsigned char *path)
+struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path)
 {
        struct sysfs_driver *driver = NULL;
 
@@ -185,13 +162,10 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv,
         }
        
        attrlist = sysfs_get_driver_attributes(drv);
-       if (attrlist != NULL) {
+       if (attrlist != NULL) 
                cur = sysfs_get_directory_attribute(drv->directory,
                                                (unsigned char *)name);
-               if (cur != NULL)
-                       return cur;
-       }
-        return NULL;
+        return cur;
 }
 
 /**
@@ -209,7 +183,7 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver)
        if (driver->directory == NULL) {
                if ((open_driver_dir(driver)) == 1)
                        return NULL;
-               if ((read_driver_dir(driver)) != 0) 
+               if ((sysfs_read_dir_links(driver->directory)) != 0) 
                        return NULL;
        }
        return(driver->directory->links);
@@ -236,13 +210,13 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver)
        if (driver->directory == NULL) {
                if ((open_driver_dir(driver)) == 1) 
                        return NULL;
-               if ((read_driver_dir(driver)) != 0) 
+               if ((sysfs_read_dir_links(driver->directory)) != 0) 
                        return NULL;
        }
        if (driver->directory->links != NULL) {
                dlist_for_each_data(driver->directory->links, curlink, 
                                                struct sysfs_link) {
-                       device = sysfs_open_device(curlink->target);
+                       device = sysfs_open_device_path(curlink->target);
                        if (device == NULL) {
                                dprintf("Error opening device at %s\n", 
                                                curlink->target);
@@ -345,7 +319,7 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus,
                return NULL;
        }
 
-       memset(path, 0, SYSFS_NAME_LEN);
+       memset(path, 0, SYSFS_PATH_MAX);
        if ((get_driver_path(bus, drv, path, SYSFS_PATH_MAX)) != 0) {
                dprintf("Error getting to driver %s\n", drv);
                return NULL;
@@ -367,3 +341,33 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus,
        return attribute;
 }
 
+/**
+ * sysfs_open_driver: open driver by name, given its bus
+ * @drv_name: Name of the driver
+ * @bus_name: Name of the bus
+ * Returns the sysfs_driver reference on success and NULL on failure
+ */
+struct sysfs_driver *sysfs_open_driver(const unsigned char *drv_name,
+                               const unsigned char *bus_name)
+{
+       unsigned char path[SYSFS_PATH_MAX];
+       struct sysfs_driver *driver = NULL;
+
+       if (drv_name == NULL || bus_name == NULL) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       memset(path, 0, SYSFS_PATH_MAX);
+       if ((get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) != 0) {
+               dprintf("Error getting to driver %s\n", drv_name);
+               return NULL;
+       }
+       driver = sysfs_open_driver_path(path);
+       if (driver == NULL) {
+               dprintf("Error opening driver at %s\n", path);
+               return NULL;
+       }
+       return driver;
+}
+
index c2ce134..009ae94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * syfs_utils.c
+ * sysfs_utils.c
  *
  * System utility functions for libsysfs
  *
@@ -135,17 +135,21 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name,
        }
        memset(tmp, 0, SYSFS_PATH_MAX);
        strcpy(tmp, path);
-       n = &tmp[strlen(tmp)-1];
-       if (strncmp(n, "/", 1) == 0)
-               *n = '\0';      
        n = strrchr(tmp, '/');
        if (n == NULL) {
                errno = EINVAL;
                return -1;
        }
+       if (*(n+1) == '\0') {
+               *n = '\0';
+               n = strrchr(tmp, '/');
+               if (n == NULL) {
+                       errno = EINVAL;
+                       return -1;
+               }
+       }
        n++;
        strncpy(name, n, len);
-
        return 0;
 }
 
@@ -233,7 +237,6 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
        unsigned char *c = NULL;
        struct sysfs_directory *dir = NULL, *cur = NULL;
        struct dlist *list = NULL;
-       struct stat astats;
        
        if (name == NULL)
                return NULL;
@@ -242,7 +245,6 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
                dprintf("Error getting sysfs mount point\n");
                return NULL;
        }
-
        if (sysfs_trailing_slash(sysfs_path) == 0)
                strcat(sysfs_path, "/");
        strcat(sysfs_path, name);
@@ -252,7 +254,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
                return NULL;
        }
 
-       if (sysfs_read_directory(dir) != 0) {
+       if ((sysfs_read_dir_subdirs(dir)) != 0) {
                dprintf("Error reading sysfs_directory at %s\n", sysfs_path);
                sysfs_close_directory(dir);
                return NULL;
@@ -285,11 +287,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
                if (c == NULL)
                        goto out;
                strcpy(c, SYSFS_BLOCK_NAME);
-               if ((lstat(sysfs_path, &astats)) != 0) {
-                       dprintf("stat() failed\n");
-                       goto out;
-               }
-               if (S_ISDIR(astats.st_mode)) {
+               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);
@@ -333,7 +331,7 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name)
                return NULL;
        }
 
-       if (sysfs_read_directory(dir) != 0) {
+       if ((sysfs_read_dir_links(dir)) != 0) {
                dprintf("Error reading sysfs_directory at %s\n", sysfs_path);
                sysfs_close_directory(dir);
                return NULL;
index 33ee633..ba5c864 100644 (file)
@@ -242,9 +242,9 @@ static struct sysfs_class_device *get_class_dev(char *device_name)
        dbg("looking at '%s'", dev_path);
 
        /* open up the sysfs class device for this thing... */
-       class_dev = sysfs_open_class_device(dev_path);
+       class_dev = sysfs_open_class_device_path(dev_path);
        if (class_dev == NULL) {
-               dbg ("sysfs_open_class_device failed");
+               dbg ("sysfs_open_class_device_path failed");
                goto exit;
        }
        dbg("class_dev->name='%s'", class_dev->name);