mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
[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.
This commit is contained in:
parent
7591c18a8f
commit
bcbe2d8e7d
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user