Move config_parse_join_controllers to shared, add test
config_parse_join_controllers would free the destination argument on failure, which is contrary to our normal style, where failed parsing has no effect. Moving it to shared also allows a test to be added.
This commit is contained in:
@@ -1021,3 +1021,108 @@ int config_parse_ip_port(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_join_controllers(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
char ****ret = data;
|
||||
const char *whole_rvalue = rvalue;
|
||||
unsigned n = 0;
|
||||
_cleanup_(strv_free_freep) char ***controllers = NULL;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(ret);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
char **l;
|
||||
int r;
|
||||
|
||||
r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
|
||||
return r;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
l = strv_split(word, ",");
|
||||
if (!l)
|
||||
return log_oom();
|
||||
strv_uniq(l);
|
||||
|
||||
if (strv_length(l) <= 1) {
|
||||
strv_free(l);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!controllers) {
|
||||
controllers = new(char**, 2);
|
||||
if (!controllers) {
|
||||
strv_free(l);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
controllers[0] = l;
|
||||
controllers[1] = NULL;
|
||||
|
||||
n = 1;
|
||||
} else {
|
||||
char ***a;
|
||||
char ***t;
|
||||
|
||||
t = new0(char**, n+2);
|
||||
if (!t) {
|
||||
strv_free(l);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
for (a = controllers; *a; a++)
|
||||
if (strv_overlap(*a, l)) {
|
||||
if (strv_extend_strv(&l, *a, false) < 0) {
|
||||
strv_free(l);
|
||||
strv_free_free(t);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
} else {
|
||||
char **c;
|
||||
|
||||
c = strv_copy(*a);
|
||||
if (!c) {
|
||||
strv_free(l);
|
||||
strv_free_free(t);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
t[n++] = c;
|
||||
}
|
||||
|
||||
t[n++] = strv_uniq(l);
|
||||
|
||||
strv_free_free(controllers);
|
||||
controllers = t;
|
||||
}
|
||||
}
|
||||
if (!isempty(rvalue))
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
|
||||
|
||||
strv_free_free(*ret);
|
||||
*ret = controllers;
|
||||
controllers = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user