From: Kay Sievers Date: Tue, 4 Nov 2008 19:19:01 +0000 (+0100) Subject: fix list handling in enumerate and rules file sorting X-Git-Tag: 174~1351 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=1e78dcbe51419124846e1f35e540cb0253362231 fix list handling in enumerate and rules file sorting --- diff --git a/TODO b/TODO index ac0618ec1..3320d9134 100644 --- a/TODO +++ b/TODO @@ -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 -- syntax diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index e9d040cdf..eda3f5d97 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -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); diff --git a/udev/lib/libudev-enumerate.c b/udev/lib/libudev-enumerate.c index 1b40d6348..618ffbc3e 100644 --- a/udev/lib/libudev-enumerate.c +++ b/udev/lib/libudev-enumerate.c @@ -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; } diff --git a/udev/lib/libudev-list.c b/udev/lib/libudev-list.c index e681e23e8..9d157616a 100644 --- a/udev/lib/libudev-list.c +++ b/udev/lib/libudev-list.c @@ -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) diff --git a/udev/lib/libudev-private.h b/udev/lib/libudev-private.h index 11e9ad9cb..2f8b8259b 100644 --- a/udev/lib/libudev-private.h +++ b/udev/lib/libudev-private.h @@ -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) \ diff --git a/udev/lib/libudev.c b/udev/lib/libudev.c index f427151f4..2d8b7754f 100644 --- a/udev/lib/libudev.c +++ b/udev/lib/libudev.c @@ -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); diff --git a/udev/udev-rules.c b/udev/udev-rules.c index 226f35296..21fa11775 100644 --- a/udev/udev-rules.c +++ b/udev/udev-rules.c @@ -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));