fix list handling in enumerate and rules file sorting

This commit is contained in:
Kay Sievers 2008-11-04 20:19:01 +01:00
parent a0e17034ee
commit 1e78dcbe51
7 changed files with 52 additions and 41 deletions

4
TODO
View file

@ -1,6 +1,8 @@
o convert firmware.sh to C
o drop pnp shell script, acpi will take care of loading pnp modules
o add DVB variables to kernel (patch sent), and drop shell script rule
o add DVB variables to kernel (patch merged in v4l tree), drop the
shell script rule
o DEVTYPE for disks is set by the kernel, they will be removed from
the default rules
o "udevadm control" commands will only accept the --<command> syntax

View file

@ -985,7 +985,7 @@ struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device
list_entry = udev_device_get_properties_list_entry(udev_device);
list_entry = udev_list_entry_get_by_name(list_entry, key);
if (list_entry != NULL)
udev_list_entry_remove(list_entry);
udev_list_entry_delete(list_entry);
return NULL;
}
return udev_list_entry_add(udev_device->udev, &udev_device->properties_list, key, value, 1, 0);

View file

@ -320,11 +320,22 @@ static int devices_delay(struct udev *udev, const char *syspath)
/* sort delayed devices to the end of the list */
static int devices_sort(struct udev_enumerate *udev_enumerate)
{
struct udev_list_entry *list_entry;
struct udev_list_entry *entry_loop;
struct udev_list_entry *entry_tmp;
struct udev_list_node devices_list;
udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->devices_list)) {
if (devices_delay(udev_enumerate->udev, udev_list_entry_get_name(list_entry)))
udev_list_entry_move_to_end(list_entry);
udev_list_init(&devices_list);
/* move delayed to delay list */
udev_list_entry_foreach_safe(entry_loop, entry_tmp, udev_list_get_entry(&udev_enumerate->devices_list)) {
if (devices_delay(udev_enumerate->udev, udev_list_entry_get_name(entry_loop))) {
udev_list_entry_remove(entry_loop);
udev_list_entry_append(entry_loop, &devices_list);
}
}
/* move delayed back to end of list */
udev_list_entry_foreach_safe(entry_loop, entry_tmp, udev_list_get_entry(&devices_list)) {
udev_list_entry_remove(entry_loop);
udev_list_entry_append(entry_loop, &udev_enumerate->devices_list);
}
udev_enumerate->devices_sorted = 1;
return 0;
@ -360,7 +371,6 @@ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
struct udev *udev = udev_enumerate_get_udev(udev_enumerate);
char base[UTIL_PATH_SIZE];
struct stat statbuf;
struct udev_list_entry *list_entry;
if (udev_enumerate == NULL)
return -EINVAL;
@ -389,11 +399,6 @@ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
}
}
}
/* sort delayed devices to the end of the list */
udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->devices_list)) {
if (devices_delay(udev, udev_list_entry_get_name(list_entry)))
udev_list_entry_move_to_end(list_entry);
}
return 0;
}

View file

@ -28,8 +28,8 @@
#include "libudev-private.h"
struct udev_list_entry {
struct udev *udev;
struct udev_list_node node;
struct udev *udev;
struct udev_list_node *list;
char *name;
char *value;
@ -86,15 +86,22 @@ static struct udev_list_entry *list_node_to_entry(struct udev_list_node *node)
}
/* insert entry into a list as the last element */
static void list_entry_append(struct udev_list_entry *new, struct udev_list_node *list)
void udev_list_entry_append(struct udev_list_entry *new, struct udev_list_node *list)
{
/* inserting before the list head make the node the last node in the list */
udev_list_node_insert_between(&new->node, list->prev, list);
new->list = list;
}
/* remove entry from a list */
void udev_list_entry_remove(struct udev_list_entry *entry)
{
udev_list_node_remove(&entry->node);
entry->list = NULL;
}
/* 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)
void udev_list_entry_insert_before(struct udev_list_entry *new, struct udev_list_entry *entry)
{
udev_list_node_insert_between(&new->node, entry->node.prev, &entry->node);
new->list = entry->list;
@ -150,14 +157,14 @@ struct udev_list_entry *udev_list_entry_add(struct udev *udev, struct udev_list_
}
}
if (entry_loop != NULL)
list_entry_insert_before(entry_new, entry_loop);
udev_list_entry_insert_before(entry_new, entry_loop);
else
list_entry_append(entry_new, list);
udev_list_entry_append(entry_new, list);
dbg(udev, "'%s=%s' added\n", entry_new->name, entry_new->value);
return entry_new;
}
void udev_list_entry_remove(struct udev_list_entry *entry)
void udev_list_entry_delete(struct udev_list_entry *entry)
{
udev_list_node_remove(&entry->node);
free(entry->name);
@ -171,20 +178,7 @@ void udev_list_cleanup_entries(struct udev *udev, struct udev_list_node *list)
struct udev_list_entry *entry_tmp;
udev_list_entry_foreach_safe(entry_loop, entry_tmp, udev_list_get_entry(list))
udev_list_entry_remove(entry_loop);
}
void udev_list_entry_move_to_end(struct udev_list_entry *list_entry)
{
udev_list_node_remove(&list_entry->node);
udev_list_node_insert_between(&list_entry->node, list_entry->list->prev, list_entry->list);
}
void udev_list_entry_move_before(struct udev_list_entry *list_entry, struct udev_list_entry *entry)
{
udev_list_node_remove(&list_entry->node);
udev_list_node_insert_between(&list_entry->node, entry->node.prev, &entry->node);
list_entry->list = entry->list;
udev_list_entry_delete(entry_loop);
}
struct udev_list_entry *udev_list_get_entry(struct udev_list_node *list)

View file

@ -139,11 +139,12 @@ extern void udev_list_node_remove(struct udev_list_node *entry);
extern struct udev_list_entry *udev_list_entry_add(struct udev *udev, struct udev_list_node *list,
const char *name, const char *value,
int unique, int sort);
extern void udev_list_entry_delete(struct udev_list_entry *entry);
extern void udev_list_entry_remove(struct udev_list_entry *entry);
extern void udev_list_entry_insert_before(struct udev_list_entry *new, struct udev_list_entry *entry);
extern void udev_list_entry_append(struct udev_list_entry *new, struct udev_list_node *list);
extern void udev_list_cleanup_entries(struct udev *udev, struct udev_list_node *name_list);
extern struct udev_list_entry *udev_list_get_entry(struct udev_list_node *list);
extern void udev_list_entry_move_to_end(struct udev_list_entry *list_entry);
extern void udev_list_entry_move_before(struct udev_list_entry *list_entry, struct udev_list_entry *entry);
extern int udev_list_entry_get_flag(struct udev_list_entry *list_entry);
extern void udev_list_entry_set_flag(struct udev_list_entry *list_entry, int flag);
#define udev_list_entry_foreach_safe(entry, tmp, first) \

View file

@ -370,7 +370,7 @@ struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, co
list_entry = udev_get_properties_list_entry(udev);
list_entry = udev_list_entry_get_by_name(list_entry, key);
if (list_entry != NULL)
udev_list_entry_remove(list_entry);
udev_list_entry_delete(list_entry);
return NULL;
}
return udev_list_entry_add(udev, &udev->properties_list, key, value, 1, 0);

View file

@ -1631,7 +1631,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
if (sort_base == NULL)
continue;
/* sort entry into existing list */
udev_list_entry_foreach_safe(file_loop, file_tmp, udev_list_get_entry(&file_list)) {
const char *file_name = udev_list_entry_get_name(file_loop);
const char *file_base = strrchr(file_name, '/');
@ -1641,15 +1641,24 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
if (strcmp(file_base, sort_base) == 0) {
info(udev, "rule file basename '%s' already added, ignoring '%s'\n",
file_name, sort_name);
udev_list_entry_remove(sort_loop);
udev_list_entry_delete(sort_loop);
sort_loop = NULL;
break;
}
if (strcmp(file_base, sort_base) > 0)
if (strcmp(file_base, sort_base) > 0) {
/* found later file, insert before */
udev_list_entry_remove(sort_loop);
udev_list_entry_insert_before(sort_loop, file_loop);
sort_loop = NULL;
break;
}
}
if (sort_loop != NULL)
udev_list_entry_move_before(sort_loop, file_loop);
/* current file already handled */
if (sort_loop == NULL)
continue;
/* no later file, append to end of list */
udev_list_entry_remove(sort_loop);
udev_list_entry_append(sort_loop, &file_list);
}
}
@ -1673,7 +1682,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
parse_file(rules, filename, filename_off);
else
info(udev, "can not read '%s'\n", filename);
udev_list_entry_remove(file_loop);
udev_list_entry_delete(file_loop);
}
memset(&end_token, 0x00, sizeof(struct token));