mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 16:59:03 +03:00
sysusers,strv: export the hash ops to map char* → strv
Also make string_strv_hashmap_put return 0 only if the entry already existed.
This commit is contained in:
parent
b124d3f2ce
commit
cde7910993
@ -889,3 +889,63 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) {
|
||||||
|
char **l;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
l = hashmap_get(h, key);
|
||||||
|
if (l) {
|
||||||
|
/* A list for this key already exists, let's append to it if it is not listed yet */
|
||||||
|
if (strv_contains(l, value))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = strv_extend(&l, value);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
assert_se(hashmap_update(h, key, l) >= 0);
|
||||||
|
} else {
|
||||||
|
/* No list for this key exists yet, create one */
|
||||||
|
_cleanup_strv_free_ char **l2 = NULL;
|
||||||
|
_cleanup_free_ char *t = NULL;
|
||||||
|
|
||||||
|
t = strdup(key);
|
||||||
|
if (!t)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = strv_extend(&l2, value);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = hashmap_put(h, t, l2);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
TAKE_PTR(t);
|
||||||
|
TAKE_PTR(l2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = hashmap_ensure_allocated(h, &string_strv_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return string_strv_hashmap_put_internal(*h, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h), key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "extract-word.h"
|
#include "extract-word.h"
|
||||||
|
#include "hashmap.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
|
||||||
@ -188,3 +189,7 @@ int fputstrv(FILE *f, char **l, const char *separator, bool *space);
|
|||||||
(b) = NULL; \
|
(b) = NULL; \
|
||||||
0; \
|
0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
extern const struct hash_ops string_strv_hash_ops;
|
||||||
|
int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value);
|
||||||
|
int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value);
|
||||||
|
@ -1358,8 +1358,6 @@ static bool item_equal(Item *a, Item *b) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIVATE_HASH_OPS_FULL(members_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free);
|
|
||||||
|
|
||||||
static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||||
|
|
||||||
static const Specifier specifier_table[] = {
|
static const Specifier specifier_table[] = {
|
||||||
@ -1511,8 +1509,6 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case ADD_MEMBER: {
|
case ADD_MEMBER: {
|
||||||
char **l;
|
|
||||||
|
|
||||||
/* Try to extend an existing member or group item */
|
/* Try to extend an existing member or group item */
|
||||||
if (!name)
|
if (!name)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
@ -1535,38 +1531,9 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
fname, line, action[0],
|
fname, line, action[0],
|
||||||
description ? "GECOS" : home ? "home directory" : "login shell");
|
description ? "GECOS" : home ? "home directory" : "login shell");
|
||||||
|
|
||||||
r = ordered_hashmap_ensure_allocated(&members, &members_hash_ops);
|
r = string_strv_ordered_hashmap_put(&members, resolved_id, resolved_name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_error_errno(r, "Failed to store mapping for %s: %m", resolved_id);
|
||||||
|
|
||||||
l = ordered_hashmap_get(members, resolved_id);
|
|
||||||
if (l) {
|
|
||||||
/* A list for this group name already exists, let's append to it */
|
|
||||||
r = strv_push(&l, resolved_name);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
resolved_name = NULL;
|
|
||||||
|
|
||||||
assert_se(ordered_hashmap_update(members, resolved_id, l) >= 0);
|
|
||||||
} else {
|
|
||||||
/* No list for this group name exists yet, create one */
|
|
||||||
|
|
||||||
l = new0(char *, 2);
|
|
||||||
if (!l)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
l[0] = resolved_name;
|
|
||||||
l[1] = NULL;
|
|
||||||
|
|
||||||
r = ordered_hashmap_put(members, resolved_id, l);
|
|
||||||
if (r < 0) {
|
|
||||||
free(l);
|
|
||||||
return log_oom();
|
|
||||||
}
|
|
||||||
|
|
||||||
resolved_id = resolved_name = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user