1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-05 06:52:22 +03:00

udevadm: do not free node on success

A fix for ff03aed06a.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2013-04-05 17:39:46 -04:00
parent bad490b051
commit 8c62ecf1a9

View File

@ -84,14 +84,12 @@ static int trie_children_cmp(const void *v1, const void *v2) {
static int node_add_child(struct trie *trie, struct trie_node *node, struct trie_node *node_child, uint8_t c) { static int node_add_child(struct trie *trie, struct trie_node *node, struct trie_node *node_child, uint8_t c) {
struct trie_child_entry *child; struct trie_child_entry *child;
int err = 0;
/* extend array, add new entry, sort for bisection */ /* extend array, add new entry, sort for bisection */
child = realloc(node->children, (node->children_count + 1) * sizeof(struct trie_child_entry)); child = realloc(node->children, (node->children_count + 1) * sizeof(struct trie_child_entry));
if (!child) { if (!child)
err = -ENOMEM; return -ENOMEM;
goto out;
}
node->children = child; node->children = child;
trie->children_count++; trie->children_count++;
node->children[node->children_count].c = c; node->children[node->children_count].c = c;
@ -99,8 +97,8 @@ static int node_add_child(struct trie *trie, struct trie_node *node, struct trie
node->children_count++; node->children_count++;
qsort(node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp); qsort(node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
trie->nodes_count++; trie->nodes_count++;
out:
return err; return 0;
} }
static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) { static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) {
@ -176,53 +174,51 @@ static int trie_insert(struct trie *trie, struct trie_node *node, const char *se
const char *key, const char *value) { const char *key, const char *value) {
size_t i = 0; size_t i = 0;
int err = 0; int err = 0;
struct trie_node _cleanup_free_ *child = NULL;
for (;;) { for (;;) {
size_t p; size_t p;
uint8_t c; uint8_t c;
struct trie_node *child;
for (p = 0; (c = trie->strings->buf[node->prefix_off + p]); p++) { for (p = 0; (c = trie->strings->buf[node->prefix_off + p]); p++) {
char *s; char _cleanup_free_ *s = NULL;
ssize_t off; ssize_t off;
struct trie_node _cleanup_free_ *new_child = NULL;
if (c == search[i + p]) if (c == search[i + p])
continue; continue;
/* split node */ /* split node */
child = calloc(sizeof(struct trie_node), 1); new_child = calloc(sizeof(struct trie_node), 1);
if (!child) { if (!new_child)
err = -ENOMEM; return -ENOMEM;
goto out;
}
/* move values from parent to child */ /* move values from parent to child */
child->prefix_off = node->prefix_off + p+1; new_child->prefix_off = node->prefix_off + p+1;
child->children = node->children; new_child->children = node->children;
child->children_count = node->children_count; new_child->children_count = node->children_count;
child->values = node->values; new_child->values = node->values;
child->values_count = node->values_count; new_child->values_count = node->values_count;
/* update parent; use strdup() because the source gets realloc()d */ /* update parent; use strdup() because the source gets realloc()d */
s = strndup(trie->strings->buf + node->prefix_off, p); s = strndup(trie->strings->buf + node->prefix_off, p);
if (!s) { if (!s)
err = -ENOMEM; return -ENOMEM;
goto out;
}
off = strbuf_add_string(trie->strings, s, p); off = strbuf_add_string(trie->strings, s, p);
free(s); if (off < 0)
if (off < 0) { return off;
err = off;
goto out;
}
node->prefix_off = off; node->prefix_off = off;
node->children = NULL; node->children = NULL;
node->children_count = 0; node->children_count = 0;
node->values = NULL; node->values = NULL;
node->values_count = 0; node->values_count = 0;
err = node_add_child(trie, node, child, c); err = node_add_child(trie, node, new_child, c);
if (err) if (err)
goto out; return err;
new_child = NULL; /* avoid cleanup */
break; break;
} }
i += p; i += p;
@ -237,28 +233,28 @@ static int trie_insert(struct trie *trie, struct trie_node *node, const char *se
/* new child */ /* new child */
child = calloc(sizeof(struct trie_node), 1); child = calloc(sizeof(struct trie_node), 1);
if (!child) { if (!child)
err = -ENOMEM; return -ENOMEM;
goto out;
}
off = strbuf_add_string(trie->strings, search + i+1, strlen(search + i+1)); off = strbuf_add_string(trie->strings, search + i+1, strlen(search + i+1));
if (off < 0) { if (off < 0) {
err = off; free(child);
goto out; return off;
} }
child->prefix_off = off; child->prefix_off = off;
err = node_add_child(trie, node, child, c); err = node_add_child(trie, node, child, c);
if (err) if (err) {
goto out; free(child);
return err;
}
return trie_node_add_value(trie, child, key, value); return trie_node_add_value(trie, child, key, value);
} }
node = child; node = child;
child = NULL; /* avoid cleanup */
i++; i++;
} }
out:
return err;
} }
struct trie_f { struct trie_f {