summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-11-12 12:39:34 +0100
committerLennart Poettering <lennart@poettering.net>2018-11-14 17:01:54 +0100
commit1e7a599671ccf1dccd21e02414f515efca069be6 (patch)
tree37f0055a8bc871e272d96a389bc6c7a1689bf355 /src/basic
parentf6dd5e7c189bf4577541a37e062bd877273823ff (diff)
downloadsystemd-1e7a599671ccf1dccd21e02414f515efca069be6.tar.gz
proc-cmdline: split out rd. prefix handling in proc_cmdline_parse_given() and proc_cmdline_get_key()
This introduces a wrapper around extrac_first_word() called proc_cmdline_extract_first(), which suppresses "rd." parameters depending on the specified calls. This allows us to share more code between proc_cmdline_parse_given() and proc_cmdline_get_key(), and makes it easier to reuse this logic for other purposes.
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/proc-cmdline.c107
1 files changed, 62 insertions, 45 deletions
diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c
index a52e58002e..112f3b7aa2 100644
--- a/src/basic/proc-cmdline.c
+++ b/src/basic/proc-cmdline.c
@@ -39,42 +39,71 @@ int proc_cmdline(char **ret) {
return read_one_line_file("/proc/cmdline", ret);
}
-int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, void *data, ProcCmdlineFlags flags) {
- const char *p;
+static int proc_cmdline_extract_first(const char **p, char **ret_word, ProcCmdlineFlags flags) {
+ const char *q = *p;
int r;
- assert(parse_item);
-
- p = line;
for (;;) {
_cleanup_free_ char *word = NULL;
- char *value, *key, *q;
+ const char *c;
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
+ r = extract_first_word(&q, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
if (r < 0)
return r;
if (r == 0)
break;
- key = word;
-
/* Filter out arguments that are intended only for the initrd */
- q = startswith(word, "rd.");
- if (q) {
+ c = startswith(word, "rd.");
+ if (c) {
if (!in_initrd())
continue;
- if (FLAGS_SET(flags, PROC_CMDLINE_STRIP_RD_PREFIX))
- key = q;
+ if (FLAGS_SET(flags, PROC_CMDLINE_STRIP_RD_PREFIX)) {
+ r = free_and_strdup(&word, c);
+ if (r < 0)
+ return r;
+ }
} else if (FLAGS_SET(flags, PROC_CMDLINE_RD_STRICT) && in_initrd())
continue; /* And optionally filter out arguments that are intended only for the host */
- value = strchr(key, '=');
+ *p = q;
+ *ret_word = TAKE_PTR(word);
+ return 1;
+ }
+
+ *p = q;
+ *ret_word = NULL;
+ return 0;
+}
+
+int proc_cmdline_parse_given(const char *line, proc_cmdline_parse_t parse_item, void *data, ProcCmdlineFlags flags) {
+ const char *p;
+ int r;
+
+ assert(parse_item);
+
+ /* The PROC_CMDLINE_VALUE_OPTIONAL flag doesn't really make sense for proc_cmdline_parse(), let's make this
+ * clear. */
+ assert(!FLAGS_SET(flags, PROC_CMDLINE_VALUE_OPTIONAL));
+
+ p = line;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ char *value;
+
+ r = proc_cmdline_extract_first(&p, &word, flags);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ value = strchr(word, '=');
if (value)
*(value++) = 0;
- r = parse_item(key, value, data);
+ r = parse_item(word, value, data);
if (r < 0)
return r;
}
@@ -127,29 +156,29 @@ bool proc_cmdline_key_streq(const char *x, const char *y) {
return true;
}
-int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **value) {
+int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_value) {
_cleanup_free_ char *line = NULL, *ret = NULL;
bool found = false;
const char *p;
int r;
- /* Looks for a specific key on the kernel command line. Supports two modes:
+ /* Looks for a specific key on the kernel command line. Supports three modes:
*
- * a) The "value" parameter is used. In this case a parameter beginning with the "key" string followed by "="
- * is searched, and the value following this is returned in "value".
+ * a) The "ret_value" parameter is used. In this case a parameter beginning with the "key" string followed by
+ * "=" is searched for, and the value following it is returned in "ret_value".
*
- * b) as above, but the PROC_CMDLINE_VALUE_OPTIONAL flag is set. In this case if the key is found as a
- * separate word (i.e. not followed by "=" but instead by whitespace or the end of the command line), then
- * this is also accepted, and "value" is returned as NULL.
+ * b) as above, but the PROC_CMDLINE_VALUE_OPTIONAL flag is set. In this case if the key is found as a separate
+ * word (i.e. not followed by "=" but instead by whitespace or the end of the command line), then this is
+ * also accepted, and "value" is returned as NULL.
*
- * c) The "value" parameter is NULL. In this case a search for the exact "key" parameter is performed.
+ * c) The "ret_value" parameter is NULL. In this case a search for the exact "key" parameter is performed.
*
* In all three cases, > 0 is returned if the key is found, 0 if not. */
if (isempty(key))
return -EINVAL;
- if (FLAGS_SET(flags, PROC_CMDLINE_VALUE_OPTIONAL) && !value)
+ if (FLAGS_SET(flags, PROC_CMDLINE_VALUE_OPTIONAL) && !ret_value)
return -EINVAL;
r = proc_cmdline(&line);
@@ -159,31 +188,17 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **value)
p = line;
for (;;) {
_cleanup_free_ char *word = NULL;
- const char *e, *k, *q;
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
+ r = proc_cmdline_extract_first(&p, &word, flags);
if (r < 0)
return r;
if (r == 0)
break;
- k = word;
-
- /* Automatically filter out arguments that are intended only for the initrd, if we are not in the
- * initrd. */
- q = startswith(word, "rd.");
- if (q) {
- if (!in_initrd())
- continue;
-
- if (FLAGS_SET(flags, PROC_CMDLINE_STRIP_RD_PREFIX))
- k = q;
-
- } else if (FLAGS_SET(flags, PROC_CMDLINE_RD_STRICT) && in_initrd())
- continue;
+ if (ret_value) {
+ const char *e;
- if (value) {
- e = proc_cmdline_key_startswith(k, key);
+ e = proc_cmdline_key_startswith(word, key);
if (!e)
continue;
@@ -198,13 +213,15 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **value)
found = true;
} else {
- if (streq(k, key))
+ if (streq(word, key)) {
found = true;
+ break; /* we found what we were looking for */
+ }
}
}
- if (value)
- *value = TAKE_PTR(ret);
+ if (ret_value)
+ *ret_value = TAKE_PTR(ret);
return found;
}