_cleanup_free_ char *joined = NULL;
STRV_FOREACH(source, l) {
- r = exec_directory_add(&d->items, &d->n_items, *source, NULL);
+ r = exec_directory_add(d, *source, NULL);
if (r < 0)
return log_oom();
}
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
_cleanup_free_ char *destination_escaped = NULL, *source_escaped = NULL;
- ExecDirectoryItem *item = NULL;
-
- /* Adding new directories is supported from both *DirectorySymlink methods and the
- * older ones, so try to find an existing configuration first and create it if it's
- * not there yet. */
- for (size_t j = 0; j < directory->n_items; ++j)
- if (path_equal(source, directory->items[j].path)) {
- item = &directory->items[j];
- break;
- }
-
- if (item)
- r = strv_extend(&item->symlinks, destination);
- else
- r = exec_directory_add(&directory->items, &directory->n_items, source, STRV_MAKE(destination));
+
+ r = exec_directory_add(directory, source, destination);
if (r < 0)
return r;
d->mode = 0755;
}
-int exec_directory_add(ExecDirectoryItem **d, size_t *n, const char *path, char **symlinks) {
+static ExecDirectoryItem *exec_directory_find(ExecDirectory *d, const char *path) {
+ assert(d);
+ assert(path);
+
+ for (size_t i = 0; i < d->n_items; i++)
+ if (path_equal(d->items[i].path, path))
+ return &d->items[i];
+
+ return NULL;
+}
+
+int exec_directory_add(ExecDirectory *d, const char *path, const char *symlink) {
_cleanup_strv_free_ char **s = NULL;
_cleanup_free_ char *p = NULL;
+ ExecDirectoryItem *existing;
+ int r;
assert(d);
- assert(n);
assert(path);
+ existing = exec_directory_find(d, path);
+ if (existing) {
+ r = strv_extend(&existing->symlinks, symlink);
+ if (r < 0)
+ return r;
+
+ return 0; /* existing item is updated */
+ }
+
p = strdup(path);
if (!p)
return -ENOMEM;
- if (symlinks) {
- s = strv_copy(symlinks);
+ if (symlink) {
+ s = strv_new(symlink);
if (!s)
return -ENOMEM;
}
- if (!GREEDY_REALLOC(*d, *n + 1))
+ if (!GREEDY_REALLOC(d->items, d->n_items + 1))
return -ENOMEM;
- (*d)[(*n) ++] = (ExecDirectoryItem) {
+ d->items[d->n_items++] = (ExecDirectoryItem) {
.path = TAKE_PTR(p),
.symlinks = TAKE_PTR(s),
};
- return 0;
+ return 1; /* new item is added */
}
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(exec_set_credential_hash_ops, char, string_hash_func, string_compare_func, ExecSetCredential, exec_set_credential_free);
DEFINE_TRIVIAL_CLEANUP_FUNC(ExecLoadCredential*, exec_load_credential_free);
void exec_directory_done(ExecDirectory *d);
-int exec_directory_add(ExecDirectoryItem **d, size_t *n, const char *path, char **symlinks);
+int exec_directory_add(ExecDirectory *d, const char *path, const char *symlink);
extern const struct hash_ops exec_set_credential_hash_ops;
extern const struct hash_ops exec_load_credential_hash_ops;
/* For State and Runtime directories we support an optional destination parameter, which
* will be used to create a symlink to the source. */
- _cleanup_strv_free_ char **symlinks = NULL;
+ _cleanup_free_ char *dresolved = NULL;
if (!isempty(dest)) {
- _cleanup_free_ char *dresolved = NULL;
-
if (streq(lvalue, "ConfigurationDirectory")) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Destination parameter is not supported for ConfigurationDirectory, ignoring: %s", tuple);
r = path_simplify_and_warn(dresolved, PATH_CHECK_RELATIVE, unit, filename, line, lvalue);
if (r < 0)
continue;
-
- r = strv_consume(&symlinks, TAKE_PTR(dresolved));
- if (r < 0)
- return log_oom();
}
- r = exec_directory_add(&ed->items, &ed->n_items, sresolved, symlinks);
+ r = exec_directory_add(ed, sresolved, dresolved);
if (r < 0)
return log_oom();
}