diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-02-16 09:56:29 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-02-19 15:02:13 +0100 |
commit | 9ecdba8cb75dd9c529ad3a869b25c36752fad90c (patch) | |
tree | fe1272b98a6a3cca28f8ec610c55aeccf0467a94 /src/shared | |
parent | b48382e4e0fe5064d73b4916a06424afe0f6c511 (diff) | |
download | systemd-9ecdba8cb75dd9c529ad3a869b25c36752fad90c.tar.gz |
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.
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/conf-parser.c | 105 | ||||
-rw-r--r-- | src/shared/conf-parser.h | 1 |
2 files changed, 106 insertions, 0 deletions
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index daddb7cf20..5c033e0ec0 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -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; +} diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 8cbb569696..908f530713 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -157,6 +157,7 @@ int config_parse_signal(GENERIC_PARSER_ARGS); int config_parse_personality(GENERIC_PARSER_ARGS); int config_parse_ifname(GENERIC_PARSER_ARGS); int config_parse_ip_port(GENERIC_PARSER_ARGS); +int config_parse_join_controllers(GENERIC_PARSER_ARGS); #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \ int function(GENERIC_PARSER_ARGS) { \ |