diff options
Diffstat (limited to 'libsysfs')
| -rw-r--r-- | libsysfs/libsysfs.h | 17 | ||||
| -rw-r--r-- | libsysfs/sysfs_bus.c | 50 | ||||
| -rw-r--r-- | libsysfs/sysfs_class.c | 80 | ||||
| -rw-r--r-- | libsysfs/sysfs_device.c | 88 | ||||
| -rw-r--r-- | libsysfs/sysfs_dir.c | 71 | ||||
| -rw-r--r-- | libsysfs/sysfs_driver.c | 72 | ||||
| -rw-r--r-- | libsysfs/sysfs_utils.c | 26 | 
7 files changed, 232 insertions, 172 deletions
| diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index aca25772b5..2ffe1005cc 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 3e6c22bbb1..d9da0f84cf 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 169600d5fd..16eaf6e514 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 82b54719ff..66d5f9aef7 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -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 diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index ac2ecfcbe1..7dbee8aba8 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 4372b19f10..695ca794f1 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -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; +} + diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index c2ce13433d..009ae94efa 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; | 
