From: dsteklof@us.ibm.com Date: Sat, 20 Dec 2003 02:29:10 +0000 (-0800) Subject: [PATCH] libsysfs 0.4.0 patch X-Git-Tag: 010~19 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=bcbe2d8e7d4ccd975e79d0c7defbe1d64d1b129c;hp=7591c18a8f3460d3e7cab85d02915c4b51638b5c [PATCH] libsysfs 0.4.0 patch 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. --- diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 3a34643c8..6bb41132d 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -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)); diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index aca25772b..2ffe1005c 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -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 diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 3e6c22bbb..d9da0f84c 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -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); diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 169600d5f..16eaf6e51 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -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; } + diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 82b54719f..66d5f9aef 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -104,14 +104,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 */ @@ -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 diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index ac2ecfcbe..7dbee8aba 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -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; } /** diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 4372b19f1..695ca794f 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -65,29 +65,6 @@ static int open_driver_dir(struct sysfs_driver *driver) return 0; } -/** - * 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; +} + diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index c2ce13433..009ae94ef 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -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; diff --git a/udev-add.c b/udev-add.c index 33ee633fd..ba5c86416 100644 --- a/udev-add.c +++ b/udev-add.c @@ -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);