mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
libudev: more list rework
This commit is contained in:
parent
e345e2670a
commit
0de33a61d7
@ -23,8 +23,8 @@ udev_device_get_devpath
|
||||
udev_device_get_devnode
|
||||
udev_device_get_sysname
|
||||
udev_device_get_subsystem
|
||||
udev_device_get_devlinks_list
|
||||
udev_device_get_properties_list
|
||||
udev_device_get_devlinks_list_entry
|
||||
udev_device_get_properties_list_entry
|
||||
udev_device_get_action
|
||||
udev_device_get_driver
|
||||
udev_device_get_devnum
|
||||
@ -33,7 +33,7 @@ udev_device_get_attr_value
|
||||
udev_enumerate_new_from_subsystems
|
||||
udev_enumerate_ref
|
||||
udev_enumerate_unref
|
||||
udev_enumerate_get_list
|
||||
udev_enumerate_get_list_entry
|
||||
udev_monitor_new_from_socket
|
||||
udev_monitor_new_from_netlink
|
||||
udev_monitor_enable_receiving
|
||||
|
@ -263,7 +263,7 @@ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, de
|
||||
char path[UTIL_PATH_SIZE];
|
||||
const char *type_str;
|
||||
struct udev_enumerate *enumerate;
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
struct udev_device *device = NULL;
|
||||
|
||||
if (type == 'b')
|
||||
@ -283,11 +283,10 @@ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, de
|
||||
enumerate = udev_enumerate_new_from_subsystems(udev, NULL);
|
||||
if (enumerate == NULL)
|
||||
return NULL;
|
||||
list = udev_enumerate_get_list(enumerate);
|
||||
while (list != NULL) {
|
||||
udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
|
||||
struct udev_device *device_loop;
|
||||
|
||||
device_loop = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list));
|
||||
device_loop = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
|
||||
if (device_loop != NULL) {
|
||||
if (udev_device_get_devnum(device_loop) == devnum) {
|
||||
device = device_loop;
|
||||
@ -295,7 +294,6 @@ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, de
|
||||
}
|
||||
udev_device_unref(device_loop);
|
||||
}
|
||||
list = udev_list_entry_get_next(list);
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
return device;
|
||||
@ -506,7 +504,7 @@ const char *udev_device_get_subsystem(struct udev_device *udev_device)
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_device_get_devlinks_list:
|
||||
* udev_device_get_devlinks_list_entry:
|
||||
* @udev_device: udev device
|
||||
*
|
||||
* Retrieve the list of device links pointing to the device file of
|
||||
@ -518,7 +516,7 @@ const char *udev_device_get_subsystem(struct udev_device *udev_device)
|
||||
*
|
||||
* Returns: the first entry of the device node link list
|
||||
**/
|
||||
struct udev_list *udev_device_get_devlinks_list(struct udev_device *udev_device)
|
||||
struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
|
||||
{
|
||||
if (udev_device == NULL)
|
||||
return NULL;
|
||||
@ -528,7 +526,7 @@ struct udev_list *udev_device_get_devlinks_list(struct udev_device *udev_device)
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_device_get_properties_list:
|
||||
* udev_device_get_properties_list_entry:
|
||||
* @udev_device: udev device
|
||||
*
|
||||
* Retrieve the list of key/value device properties of the udev
|
||||
@ -539,7 +537,7 @@ struct udev_list *udev_device_get_devlinks_list(struct udev_device *udev_device)
|
||||
*
|
||||
* Returns: the first entry of the property list
|
||||
**/
|
||||
struct udev_list *udev_device_get_properties_list(struct udev_device *udev_device)
|
||||
struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
|
||||
{
|
||||
if (udev_device == NULL)
|
||||
return NULL;
|
||||
@ -587,7 +585,7 @@ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
|
||||
|
||||
const char *udev_device_get_attr_value(struct udev_device *udev_device, const char *attr)
|
||||
{
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
char path[UTIL_PATH_SIZE];
|
||||
char value[UTIL_NAME_SIZE];
|
||||
struct stat statbuf;
|
||||
@ -596,13 +594,11 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch
|
||||
const char *val = NULL;
|
||||
|
||||
/* look for possibly already cached result */
|
||||
list = list_get_entry(&udev_device->attr_list);
|
||||
while (list != NULL) {
|
||||
if (strcmp(udev_list_entry_get_name(list), attr) == 0) {
|
||||
info(udev_device->udev, "got '%s' (%s) from cache\n", attr, udev_list_entry_get_value(list));
|
||||
return udev_list_entry_get_value(list);
|
||||
udev_list_entry_foreach(list_entry, list_get_entry(&udev_device->attr_list)) {
|
||||
if (strcmp(udev_list_entry_get_name(list_entry), attr) == 0) {
|
||||
info(udev_device->udev, "got '%s' (%s) from cache\n", attr, udev_list_entry_get_value(list_entry));
|
||||
return udev_list_entry_get_value(list_entry);
|
||||
}
|
||||
list = udev_list_entry_get_next(list);
|
||||
}
|
||||
|
||||
util_strlcpy(path, udev_device_get_syspath(udev_device), sizeof(path));
|
||||
@ -627,8 +623,8 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch
|
||||
if (pos != NULL) {
|
||||
pos = &pos[1];
|
||||
info(udev_device->udev, "cache '%s' with link value '%s'\n", attr, pos);
|
||||
list = list_insert_entry(udev_device->udev, &udev_device->attr_list, attr, pos, 0);
|
||||
val = udev_list_entry_get_value(list);
|
||||
list_entry = list_entry_add(udev_device->udev, &udev_device->attr_list, attr, pos, 0, 0);
|
||||
val = udev_list_entry_get_value(list_entry);
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
@ -659,8 +655,8 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch
|
||||
value[size] = '\0';
|
||||
util_remove_trailing_chars(value, '\n');
|
||||
info(udev_device->udev, "'%s' has attribute value '%s'\n", path, value);
|
||||
list = list_insert_entry(udev_device->udev, &udev_device->attr_list, attr, value, 0);
|
||||
val = udev_list_entry_get_value(list);
|
||||
list_entry = list_entry_add(udev_device->udev, &udev_device->attr_list, attr, value, 0, 0);
|
||||
val = udev_list_entry_get_value(list_entry);
|
||||
out:
|
||||
return val;
|
||||
}
|
||||
@ -697,14 +693,14 @@ int device_set_devnode(struct udev_device *udev_device, const char *devnode)
|
||||
|
||||
int device_add_devlink(struct udev_device *udev_device, const char *devlink)
|
||||
{
|
||||
if (list_insert_entry(udev_device->udev, &udev_device->devlink_list, devlink, NULL, 0) == NULL)
|
||||
if (list_entry_add(udev_device->udev, &udev_device->devlink_list, devlink, NULL, 1, 0) == NULL)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_add_property(struct udev_device *udev_device, const char *key, const char *value)
|
||||
{
|
||||
if (list_insert_entry(udev_device->udev, &udev_device->properties_list, key, value, 0) == NULL)
|
||||
if (list_entry_add(udev_device->udev, &udev_device->properties_list, key, value, 1, 0) == NULL)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ void udev_enumerate_unref(struct udev_enumerate *udev_enumerate)
|
||||
free(udev_enumerate);
|
||||
}
|
||||
|
||||
struct udev_list *udev_enumerate_get_list(struct udev_enumerate *udev_enumerate)
|
||||
struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)
|
||||
{
|
||||
if (udev_enumerate == NULL)
|
||||
return NULL;
|
||||
@ -87,7 +87,7 @@ static int devices_scan_subsystem(struct udev *udev,
|
||||
util_strlcat(syspath, "/", sizeof(syspath));
|
||||
util_strlcat(syspath, dent->d_name, sizeof(syspath));
|
||||
util_resolve_sys_link(udev, syspath, sizeof(syspath));
|
||||
list_insert_entry(udev, device_list, syspath, NULL, 1);
|
||||
list_entry_add(udev, device_list, syspath, NULL, 1, 1);
|
||||
}
|
||||
closedir(dir);
|
||||
return 0;
|
||||
@ -151,7 +151,7 @@ struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, con
|
||||
struct udev_enumerate *udev_enumerate;
|
||||
char base[UTIL_PATH_SIZE];
|
||||
struct stat statbuf;
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
|
||||
if (udev == NULL)
|
||||
return NULL;
|
||||
@ -168,18 +168,19 @@ struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, con
|
||||
util_strlcpy(base, udev_get_sys_path(udev), sizeof(base));
|
||||
util_strlcat(base, "/subsystem", sizeof(base));
|
||||
if (stat(base, &statbuf) == 0) {
|
||||
info(udev, "searching 'subsystem/*/devices/*' dir\n");
|
||||
devices_scan_subsystems(udev, "/subsystem", subsystem, "/devices", &udev_enumerate->devices_list);
|
||||
} else {
|
||||
info(udev, "searching 'bus/*/devices/*' dir\n");
|
||||
devices_scan_subsystems(udev, "/bus", subsystem, "/devices", &udev_enumerate->devices_list);
|
||||
info(udev, "searching 'class/*' dir\n");
|
||||
devices_scan_subsystems(udev, "/class", subsystem, NULL, &udev_enumerate->devices_list);
|
||||
}
|
||||
|
||||
/* sort delayed devices to the end of the list */
|
||||
list = list_get_entry(&udev_enumerate->devices_list);
|
||||
while (list != NULL) {
|
||||
if (devices_delay(udev, udev_list_entry_get_name(list)))
|
||||
list_move_entry_to_end(list, &udev_enumerate->devices_list);
|
||||
list = udev_list_entry_get_next(list);
|
||||
udev_list_entry_foreach(list_entry, list_get_entry(&udev_enumerate->devices_list)) {
|
||||
if (devices_delay(udev, udev_list_entry_get_name(list_entry)))
|
||||
list_entry_move_to_end(list_entry);
|
||||
}
|
||||
return udev_enumerate;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "libudev.h"
|
||||
#include "libudev-private.h"
|
||||
|
||||
struct udev_list {
|
||||
struct udev_list_entry {
|
||||
struct udev *udev;
|
||||
struct list_node node;
|
||||
struct list_node *list;
|
||||
@ -35,157 +35,171 @@ struct udev_list {
|
||||
char *value;
|
||||
};
|
||||
|
||||
static struct udev_list *node_to_entry(struct list_node *node)
|
||||
{
|
||||
char *list;
|
||||
|
||||
list = (char *)node;
|
||||
list -= offsetof(struct udev_list, node);
|
||||
return (struct udev_list *)list;
|
||||
}
|
||||
|
||||
/* list head point to itself if empty */
|
||||
void list_init(struct list_node *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
static int list_empty(struct list_node *list)
|
||||
static int list_is_empty(struct list_node *list)
|
||||
{
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void list_add(struct list_node *new, struct list_node *list)
|
||||
static void list_node_insert_between(struct list_node *new,
|
||||
struct list_node *prev,
|
||||
struct list_node *next)
|
||||
{
|
||||
struct list_node *next = list->next;
|
||||
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = list;
|
||||
list->next = new;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void list_add_to_end(struct list_node *new, struct list_node *list)
|
||||
{
|
||||
struct list_node *prev = list->prev;
|
||||
|
||||
list->prev = new;
|
||||
new->next = list;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
static void list_del(struct list_node *entry)
|
||||
static void list_node_remove(struct list_node *entry)
|
||||
{
|
||||
struct list_node *prev = entry->prev;
|
||||
struct list_node *next = entry->next;
|
||||
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
|
||||
entry->prev = NULL;
|
||||
entry->next = NULL;
|
||||
}
|
||||
|
||||
#define list_for_each_entry(pos, list) \
|
||||
for (pos = node_to_entry((list)->next); \
|
||||
&pos->node != (list); \
|
||||
pos = node_to_entry(pos->node.next))
|
||||
|
||||
#define list_for_each_entry_safe(pos, tmp, list) \
|
||||
for (pos = node_to_entry((list)->next), \
|
||||
tmp = node_to_entry(pos->node.next); \
|
||||
&pos->node != (list); \
|
||||
pos = tmp, tmp = node_to_entry(tmp->node.next))
|
||||
|
||||
struct udev_list *list_insert_entry(struct udev *udev, struct list_node *list,
|
||||
const char *name, const char *value, int sort)
|
||||
/* return list entry which embeds this node */
|
||||
static struct udev_list_entry *list_node_to_entry(struct list_node *node)
|
||||
{
|
||||
struct udev_list *list_loop;
|
||||
struct udev_list *list_new;
|
||||
char *list;
|
||||
|
||||
/* avoid duplicate entries */
|
||||
list_for_each_entry(list_loop, list) {
|
||||
if (strcmp(list_loop->name, name) == 0) {
|
||||
dbg(udev, "'%s' is already in the list\n", name);
|
||||
return list_loop;
|
||||
list = (char *)node;
|
||||
list -= offsetof(struct udev_list_entry, node);
|
||||
return (struct udev_list_entry *)list;
|
||||
}
|
||||
|
||||
/* insert entry into a list as the last element */
|
||||
static void list_entry_append(struct udev_list_entry *new, struct list_node *list)
|
||||
{
|
||||
/* inserting before the list head make the node the last node in the list */
|
||||
list_node_insert_between(&new->node, list->prev, list);
|
||||
new->list = list;
|
||||
}
|
||||
|
||||
/* insert entry into a list, before a given existing entry */
|
||||
static void list_entry_insert_before(struct udev_list_entry *new, struct udev_list_entry *entry)
|
||||
{
|
||||
list_node_insert_between(&new->node, entry->node.prev, &entry->node);
|
||||
new->list = entry->list;
|
||||
}
|
||||
|
||||
void list_entry_remove(struct udev_list_entry *entry)
|
||||
{
|
||||
list_node_remove(&entry->node);
|
||||
entry->list = NULL;
|
||||
}
|
||||
|
||||
struct udev_list_entry *list_entry_add(struct udev *udev, struct list_node *list,
|
||||
const char *name, const char *value,
|
||||
int unique, int sort)
|
||||
{
|
||||
struct udev_list_entry *entry_loop = NULL;
|
||||
struct udev_list_entry *entry_new;
|
||||
|
||||
if (unique)
|
||||
udev_list_entry_foreach(entry_loop, list_get_entry(list)) {
|
||||
if (strcmp(entry_loop->name, name) == 0) {
|
||||
info(udev, "'%s' is already in the list\n", name);
|
||||
if (value != NULL) {
|
||||
free(entry_loop->value);
|
||||
entry_loop->value = strdup(value);
|
||||
if (entry_loop->value == NULL)
|
||||
return NULL;
|
||||
info(udev, "'%s' value replaced with '%s'\n", name, value);
|
||||
}
|
||||
return entry_loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sort) {
|
||||
list_for_each_entry(list_loop, list) {
|
||||
if (strcmp(list_loop->name, name) > 0)
|
||||
if (sort)
|
||||
udev_list_entry_foreach(entry_loop, list_get_entry(list)) {
|
||||
if (strcmp(entry_loop->name, name) > 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_new = malloc(sizeof(struct udev_list));
|
||||
if (list_new == NULL)
|
||||
entry_new = malloc(sizeof(struct udev_list_entry));
|
||||
if (entry_new == NULL)
|
||||
return NULL;
|
||||
memset(list_new, 0x00, sizeof(struct udev_list));
|
||||
list_new->udev = udev;
|
||||
list_new->list = list;
|
||||
list_new->name = strdup(name);
|
||||
if (list_new->name == NULL) {
|
||||
free(list_new);
|
||||
memset(entry_new, 0x00, sizeof(struct udev_list_entry));
|
||||
entry_new->udev = udev;
|
||||
entry_new->name = strdup(name);
|
||||
if (entry_new->name == NULL) {
|
||||
free(entry_new);
|
||||
return NULL;
|
||||
}
|
||||
if (value != NULL) {
|
||||
list_new->value = strdup(value);
|
||||
if (list_new->value == NULL) {
|
||||
free(list_new);
|
||||
entry_new->value = strdup(value);
|
||||
if (entry_new->value == NULL) {
|
||||
free(entry_new->name);
|
||||
free(entry_new);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
dbg(udev, "adding '%s=%s'\n", list_new->name, list_new->value);
|
||||
list_add_to_end(&list_new->node, &list_loop->node);
|
||||
return list_new;
|
||||
if (entry_loop != NULL)
|
||||
list_entry_insert_before(entry_new, entry_loop);
|
||||
else
|
||||
list_entry_append(entry_new, list);
|
||||
return entry_new;
|
||||
}
|
||||
|
||||
void list_move_entry_to_end(struct udev_list *list_entry, struct list_node *list)
|
||||
void list_entry_move_to_end(struct udev_list_entry *list_entry)
|
||||
{
|
||||
list_del(&list_entry->node);
|
||||
list_add_to_end(&list_entry->node, list);
|
||||
list_node_remove(&list_entry->node);
|
||||
list_node_insert_between(&list_entry->node, list_entry->list->prev, list_entry->list);
|
||||
}
|
||||
|
||||
void list_cleanup(struct udev *udev, struct list_node *list)
|
||||
{
|
||||
struct udev_list *list_loop;
|
||||
struct udev_list *list_tmp;
|
||||
struct udev_list_entry *entry_loop;
|
||||
struct udev_list_entry *entry_tmp;
|
||||
|
||||
list_for_each_entry_safe(list_loop, list_tmp, list) {
|
||||
list_del(&list_loop->node);
|
||||
free(list_loop->name);
|
||||
free(list_loop->value);
|
||||
free(list_loop);
|
||||
list_entry_foreach_safe(entry_loop, entry_tmp, list_get_entry(list)) {
|
||||
list_entry_remove(entry_loop);
|
||||
free(entry_loop->name);
|
||||
free(entry_loop->value);
|
||||
free(entry_loop);
|
||||
}
|
||||
}
|
||||
|
||||
struct udev_list *list_get_entry(struct list_node *list)
|
||||
struct udev_list_entry *list_get_entry(struct list_node *list)
|
||||
{
|
||||
if (list_empty(list))
|
||||
if (list_is_empty(list))
|
||||
return NULL;
|
||||
return node_to_entry(list->next);
|
||||
return list_node_to_entry(list->next);
|
||||
}
|
||||
|
||||
struct udev_list *udev_list_entry_get_next(struct udev_list *list_entry)
|
||||
struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry)
|
||||
{
|
||||
struct list_node *next;
|
||||
|
||||
if (list_entry == NULL)
|
||||
return NULL;
|
||||
next = list_entry->node.next;
|
||||
/* empty list or no more emtries */
|
||||
/* empty list or no more entries */
|
||||
if (next == list_entry->list)
|
||||
return NULL;
|
||||
return node_to_entry(next);
|
||||
return list_node_to_entry(next);
|
||||
}
|
||||
|
||||
const char *udev_list_entry_get_name(struct udev_list *list_entry)
|
||||
const char *udev_list_entry_get_name(struct udev_list_entry *list_entry)
|
||||
{
|
||||
if (list_entry == NULL)
|
||||
return NULL;
|
||||
return list_entry->name;
|
||||
}
|
||||
|
||||
const char *udev_list_entry_get_value(struct udev_list *list_entry)
|
||||
const char *udev_list_entry_get_value(struct udev_list_entry *list_entry)
|
||||
{
|
||||
if (list_entry == NULL)
|
||||
return NULL;
|
||||
|
@ -109,11 +109,18 @@ struct list_node {
|
||||
struct list_node *next, *prev;
|
||||
};
|
||||
extern void list_init(struct list_node *list);
|
||||
extern struct udev_list *list_insert_entry(struct udev *udev, struct list_node *name_list,
|
||||
const char *name, const char *value, int sort);
|
||||
extern struct udev_list *list_get_entry(struct list_node *list);
|
||||
extern void list_move_entry_to_end(struct udev_list *list_entry, struct list_node *list);
|
||||
extern void list_cleanup(struct udev *udev, struct list_node *name_list);
|
||||
extern struct udev_list_entry *list_entry_add(struct udev *udev, struct list_node *list,
|
||||
const char *name, const char *value,
|
||||
int unique, int sort);
|
||||
extern void list_entry_remove(struct udev_list_entry *entry);
|
||||
extern struct udev_list_entry *list_get_entry(struct list_node *list);
|
||||
extern void list_entry_move_to_end(struct udev_list_entry *list_entry);
|
||||
#define list_entry_foreach_safe(entry, tmp, first) \
|
||||
for (entry = first, \
|
||||
tmp = udev_list_entry_get_next(entry); \
|
||||
entry != NULL; \
|
||||
entry = tmp, tmp = udev_list_entry_get_next(tmp))
|
||||
|
||||
/* libudev-utils */
|
||||
#define UTIL_PATH_SIZE 1024
|
||||
|
@ -28,13 +28,8 @@
|
||||
#error "#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE is needed to use this experimental library version"
|
||||
#endif
|
||||
|
||||
struct udev;
|
||||
struct udev_list;
|
||||
struct udev_device;
|
||||
struct udev_enumerate;
|
||||
struct udev_monitor;
|
||||
|
||||
/* library context */
|
||||
struct udev;
|
||||
extern struct udev *udev_new(void);
|
||||
extern struct udev *udev_ref(struct udev *udev);
|
||||
extern void udev_unref(struct udev *udev);
|
||||
@ -55,11 +50,17 @@ extern void udev_selinux_setfscreatecon(struct udev *udev, const char *file, uns
|
||||
extern void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode);
|
||||
|
||||
/* list iteration */
|
||||
extern struct udev_list *udev_list_entry_get_next(struct udev_list *list_entry);
|
||||
extern const char *udev_list_entry_get_name(struct udev_list *list_entry);
|
||||
extern const char *udev_list_entry_get_value(struct udev_list *list_entry);
|
||||
struct udev_list_entry;
|
||||
extern struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry);
|
||||
extern const char *udev_list_entry_get_name(struct udev_list_entry *list_entry);
|
||||
extern const char *udev_list_entry_get_value(struct udev_list_entry *list_entry);
|
||||
#define udev_list_entry_foreach(entry, first) \
|
||||
for (entry = first; \
|
||||
entry != NULL; \
|
||||
entry = udev_list_entry_get_next(entry))
|
||||
|
||||
/* sys devices */
|
||||
struct udev_device;
|
||||
extern struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath);
|
||||
extern struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum);
|
||||
extern struct udev_device *udev_device_get_parent(struct udev_device *udev_device);
|
||||
@ -71,21 +72,16 @@ extern const char *udev_device_get_subsystem(struct udev_device *udev_device);
|
||||
extern const char *udev_device_get_syspath(struct udev_device *udev_device);
|
||||
extern const char *udev_device_get_sysname(struct udev_device *udev_device);
|
||||
extern const char *udev_device_get_devnode(struct udev_device *udev_device);
|
||||
extern struct udev_list *udev_device_get_devlinks_list(struct udev_device *udev_device);
|
||||
extern struct udev_list *udev_device_get_properties_list(struct udev_device *udev_device);
|
||||
extern struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device);
|
||||
extern struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device);
|
||||
extern const char *udev_device_get_driver(struct udev_device *udev_device);
|
||||
extern dev_t udev_device_get_devnum(struct udev_device *udev_device);
|
||||
extern const char *udev_device_get_action(struct udev_device *udev_device);
|
||||
extern unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device);
|
||||
extern const char *udev_device_get_attr_value(struct udev_device *udev_device, const char *attr);
|
||||
|
||||
/* sys enumeration */
|
||||
extern struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, const char *subsystem);
|
||||
extern struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate);
|
||||
extern void udev_enumerate_unref(struct udev_enumerate *udev_enumerate);
|
||||
extern struct udev_list *udev_enumerate_get_list(struct udev_enumerate *udev_enumerate);
|
||||
|
||||
/* udev and kernel device events */
|
||||
struct udev_monitor;
|
||||
extern struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char *socket_path);
|
||||
extern struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev);
|
||||
extern int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor);
|
||||
@ -95,4 +91,11 @@ extern struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor);
|
||||
extern int udev_monitor_get_fd(struct udev_monitor *udev_monitor);
|
||||
extern struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor);
|
||||
|
||||
/* sys enumeration */
|
||||
struct udev_enumerate;
|
||||
extern struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, const char *subsystem);
|
||||
extern struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate);
|
||||
extern void udev_enumerate_unref(struct udev_enumerate *udev_enumerate);
|
||||
extern struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate);
|
||||
|
||||
#endif
|
||||
|
@ -42,44 +42,60 @@ static void print_device(struct udev_device *device)
|
||||
const char *str;
|
||||
dev_t devnum;
|
||||
int count;
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
|
||||
printf("*** device: %p ***\n", device);
|
||||
str = udev_device_get_action(device);
|
||||
printf("action: '%s'\n", str);
|
||||
if (str != NULL)
|
||||
printf("action: '%s'\n", str);
|
||||
|
||||
str = udev_device_get_syspath(device);
|
||||
printf("syspath: '%s'\n", str);
|
||||
|
||||
str = udev_device_get_devpath(device);
|
||||
printf("devpath: '%s'\n", str);
|
||||
|
||||
str = udev_device_get_subsystem(device);
|
||||
printf("subsystem: '%s'\n", str);
|
||||
if (str != NULL)
|
||||
printf("subsystem: '%s'\n", str);
|
||||
|
||||
str = udev_device_get_driver(device);
|
||||
printf("driver: '%s'\n", str);
|
||||
if (str != NULL)
|
||||
printf("driver: '%s'\n", str);
|
||||
|
||||
str = udev_device_get_devnode(device);
|
||||
printf("devname: '%s'\n", str);
|
||||
if (str != NULL)
|
||||
printf("devname: '%s'\n", str);
|
||||
|
||||
devnum = udev_device_get_devnum(device);
|
||||
printf("devnum: %u:%u\n", major(devnum), minor(devnum));
|
||||
if (major(devnum) > 0)
|
||||
printf("devnum: %u:%u\n", major(devnum), minor(devnum));
|
||||
|
||||
count = 0;
|
||||
list = udev_device_get_devlinks_list(device);
|
||||
while (list != NULL) {
|
||||
printf("link: '%s'\n", udev_list_entry_get_name(list));
|
||||
list_entry = udev_device_get_devlinks_list_entry(device);
|
||||
while (list_entry != NULL) {
|
||||
printf("link: '%s'\n", udev_list_entry_get_name(list_entry));
|
||||
count++;
|
||||
list = udev_list_entry_get_next(list);
|
||||
list_entry = udev_list_entry_get_next(list_entry);
|
||||
}
|
||||
printf("found %i links\n", count);
|
||||
if (count > 0)
|
||||
printf("found %i links\n", count);
|
||||
|
||||
count = 0;
|
||||
list = udev_device_get_properties_list(device);
|
||||
while (list != NULL) {
|
||||
printf("property: '%s=%s'\n", udev_list_entry_get_name(list), udev_list_entry_get_value(list));
|
||||
list_entry = udev_device_get_properties_list_entry(device);
|
||||
while (list_entry != NULL) {
|
||||
printf("property: '%s=%s'\n",
|
||||
udev_list_entry_get_name(list_entry),
|
||||
udev_list_entry_get_value(list_entry));
|
||||
count++;
|
||||
list = udev_list_entry_get_next(list);
|
||||
list_entry = udev_list_entry_get_next(list_entry);
|
||||
}
|
||||
printf("found %i properties\n", count);
|
||||
if (count > 0)
|
||||
printf("found %i properties\n", count);
|
||||
|
||||
str = udev_device_get_attr_value(device, "dev");
|
||||
printf("attr{dev}: '%s'\n", str);
|
||||
if (str != NULL)
|
||||
printf("attr{dev}: '%s'\n", str);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
@ -144,17 +160,17 @@ static int test_device_devnum(struct udev *udev)
|
||||
static int test_enumerate(struct udev *udev, const char *subsystem)
|
||||
{
|
||||
struct udev_enumerate *enumerate;
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
int count = 0;
|
||||
|
||||
enumerate = udev_enumerate_new_from_subsystems(udev, NULL);
|
||||
if (enumerate == NULL)
|
||||
return -1;
|
||||
list = udev_enumerate_get_list(enumerate);
|
||||
while (list != NULL) {
|
||||
list_entry = udev_enumerate_get_list_entry(enumerate);
|
||||
while (list_entry != NULL) {
|
||||
struct udev_device *device;
|
||||
|
||||
device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list));
|
||||
device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
|
||||
if (device != NULL) {
|
||||
printf("device: '%s' (%s) '%s'\n",
|
||||
udev_device_get_syspath(device),
|
||||
@ -163,7 +179,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem)
|
||||
udev_device_unref(device);
|
||||
count++;
|
||||
}
|
||||
list = udev_list_entry_get_next(list);
|
||||
list_entry = udev_list_entry_get_next(list_entry);
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
printf("found %i devices\n\n", count);
|
||||
|
@ -130,7 +130,7 @@ static void print_record(struct udev_device *device)
|
||||
{
|
||||
size_t len;
|
||||
int i;
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
|
||||
printf("P: %s\n", udev_device_get_devpath(device));
|
||||
|
||||
@ -149,18 +149,15 @@ static void print_record(struct udev_device *device)
|
||||
if (i != 0)
|
||||
printf("R:%u\n", i);
|
||||
|
||||
list = udev_device_get_devlinks_list(device);
|
||||
while (list != NULL) {
|
||||
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
|
||||
len = strlen(udev_get_dev_path(udev_device_get_udev(device)));
|
||||
printf("S: %s\n", &udev_list_entry_get_name(list)[len+1]);
|
||||
list = udev_list_entry_get_next(list);
|
||||
printf("S: %s\n", &udev_list_entry_get_name(list_entry)[len+1]);
|
||||
}
|
||||
|
||||
list = udev_device_get_properties_list(device);
|
||||
while (list != NULL) {
|
||||
printf("E: %s=%s\n", udev_list_entry_get_name(list), udev_list_entry_get_value(list));
|
||||
list = udev_list_entry_get_next(list);
|
||||
}
|
||||
udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
|
||||
printf("E: %s=%s\n",
|
||||
udev_list_entry_get_name(list_entry),
|
||||
udev_list_entry_get_value(list_entry));
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
@ -187,22 +184,20 @@ static int stat_device(const char *name, int export, const char *prefix)
|
||||
static int export_devices(struct udev *udev)
|
||||
{
|
||||
struct udev_enumerate *enumerate;
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
|
||||
enumerate = udev_enumerate_new_from_subsystems(udev, NULL);
|
||||
if (enumerate == NULL)
|
||||
return -1;
|
||||
list = udev_enumerate_get_list(enumerate);
|
||||
while (list != NULL) {
|
||||
udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
|
||||
struct udev_device *device;
|
||||
|
||||
device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list));
|
||||
device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
|
||||
if (device != NULL) {
|
||||
if (udev_device_get_devnode(device) != NULL)
|
||||
print_record(device);
|
||||
udev_device_unref(device);
|
||||
}
|
||||
list = udev_list_entry_get_next(list);
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
return 0;
|
||||
@ -216,7 +211,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
const char *export_prefix = NULL;
|
||||
char path[UTIL_PATH_SIZE];
|
||||
char name[UTIL_PATH_SIZE];
|
||||
struct udev_list *list;
|
||||
struct udev_list_entry *list_entry;
|
||||
int rc = 0;
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -416,18 +411,18 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
}
|
||||
break;
|
||||
case QUERY_SYMLINK:
|
||||
list = udev_device_get_devlinks_list(device);
|
||||
while (list != NULL) {
|
||||
list_entry = udev_device_get_devlinks_list_entry(device);
|
||||
while (list_entry != NULL) {
|
||||
if (root) {
|
||||
printf("%s", udev_list_entry_get_name(list));
|
||||
printf("%s", udev_list_entry_get_name(list_entry));
|
||||
} else {
|
||||
size_t len;
|
||||
|
||||
len = strlen(udev_get_dev_path(udev_device_get_udev(device)));
|
||||
printf("%s", &udev_list_entry_get_name(list)[len+1]);
|
||||
printf("%s", &udev_list_entry_get_name(list_entry)[len+1]);
|
||||
}
|
||||
list = udev_list_entry_get_next(list);
|
||||
if (list != NULL)
|
||||
list_entry = udev_list_entry_get_next(list_entry);
|
||||
if (list_entry != NULL)
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
@ -436,10 +431,10 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
|
||||
printf("%s\n", udev_device_get_devpath(device));
|
||||
goto exit;
|
||||
case QUERY_ENV:
|
||||
list = udev_device_get_properties_list(device);
|
||||
while (list != NULL) {
|
||||
printf("%s=%s\n", udev_list_entry_get_name(list), udev_list_entry_get_value(list));
|
||||
list = udev_list_entry_get_next(list);
|
||||
list_entry = udev_device_get_properties_list_entry(device);
|
||||
while (list_entry != NULL) {
|
||||
printf("%s=%s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
|
||||
list_entry = udev_list_entry_get_next(list_entry);
|
||||
}
|
||||
break;
|
||||
case QUERY_ALL:
|
||||
|
@ -41,6 +41,29 @@ static void asmlinkage sig_handler(int signum)
|
||||
udev_exit = 1;
|
||||
}
|
||||
|
||||
static void print_device(struct udev_device *device, const char *source, int env)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
printf("%-6s[%llu.%06u] %-8s %s (%s)\n",
|
||||
source,
|
||||
(unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec,
|
||||
udev_device_get_action(device),
|
||||
udev_device_get_devpath(device),
|
||||
udev_device_get_subsystem(device));
|
||||
if (env) {
|
||||
struct udev_list_entry *list_entry;
|
||||
|
||||
udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
|
||||
printf("%s=%s\n",
|
||||
udev_list_entry_get_name(list_entry),
|
||||
udev_list_entry_get_value(list_entry));
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int udevadm_monitor(struct udev *udev, int argc, char *argv[])
|
||||
{
|
||||
struct sigaction act;
|
||||
@ -134,9 +157,6 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
|
||||
|
||||
while (!udev_exit) {
|
||||
int fdcount;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
char timestr[64];
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
if (kernel_monitor != NULL)
|
||||
@ -152,51 +172,23 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gettimeofday(&tv, &tz) == 0) {
|
||||
snprintf(timestr, sizeof(timestr), "%llu.%06u",
|
||||
(unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec);
|
||||
} else
|
||||
timestr[0] = '\0';
|
||||
|
||||
if ((kernel_monitor != NULL) && FD_ISSET(udev_monitor_get_fd(kernel_monitor), &readfds)) {
|
||||
struct udev_device *device = udev_monitor_receive_device(kernel_monitor);
|
||||
struct udev_device *device;
|
||||
|
||||
device = udev_monitor_receive_device(kernel_monitor);
|
||||
if (device == NULL)
|
||||
continue;
|
||||
printf("UEVENT[%s] %-8s %s (%s)\n", timestr,
|
||||
udev_device_get_action(device),
|
||||
udev_device_get_devpath(device),
|
||||
udev_device_get_subsystem(device));
|
||||
if (env) {
|
||||
struct udev_list *list;
|
||||
|
||||
list = udev_device_get_properties_list(device);
|
||||
while (list != NULL) {
|
||||
printf("%s=%s\n", udev_list_entry_get_name(list), udev_list_entry_get_value(list));
|
||||
list = udev_list_entry_get_next(list);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
print_device(device, "UEVENT", env);
|
||||
udev_device_unref(device);
|
||||
}
|
||||
|
||||
if ((udev_monitor != NULL) && FD_ISSET(udev_monitor_get_fd(udev_monitor), &readfds)) {
|
||||
struct udev_device *device = udev_monitor_receive_device(udev_monitor);
|
||||
struct udev_device *device;
|
||||
|
||||
device = udev_monitor_receive_device(udev_monitor);
|
||||
if (device == NULL)
|
||||
continue;
|
||||
printf("UDEV [%s] %-8s %s (%s)\n", timestr,
|
||||
udev_device_get_action(device),
|
||||
udev_device_get_devpath(device),
|
||||
udev_device_get_subsystem(device));
|
||||
if (env) {
|
||||
struct udev_list *list;
|
||||
|
||||
list = udev_device_get_properties_list(device);
|
||||
while (list != NULL) {
|
||||
printf("%s=%s\n", udev_list_entry_get_name(list), udev_list_entry_get_value(list));
|
||||
list = udev_list_entry_get_next(list);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
print_device(device, "UDEV", env);
|
||||
udev_device_unref(device);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user