int shall_restore_state(void) {
_cleanup_free_ char *line = NULL;
- const char *word, *state;
- size_t l;
+ const char *p;
int r;
r = proc_cmdline(&line);
return r;
r = 1;
- FOREACH_WORD_QUOTED(word, l, line, state) {
+ p = line;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
const char *e;
- char n[l+1];
int k;
- memcpy(n, word, l);
- n[l] = 0;
+ k = unquote_first_word(&p, &word, true);
+ if (k < 0)
+ return k;
+ if (k == 0)
+ break;
- e = startswith(n, "systemd.restore_state=");
+ e = startswith(word, "systemd.restore_state=");
if (!e)
continue;
int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
_cleanup_free_ char *line = NULL;
- const char *w, *state;
- size_t l;
+ const char *p;
int r;
assert(parse_item);
if (r < 0)
return r;
- FOREACH_WORD_QUOTED(w, l, line, state) {
- char word[l+1], *value;
+ p = line;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ char *value = NULL;
- memcpy(word, w, l);
- word[l] = 0;
+ r = unquote_first_word(&p, &word, true);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
/* Filter out arguments that are intended only for the
* initrd */
return !!S_ISDIR(st.st_mode);
}
-int unquote_first_word(const char **p, char **ret) {
+int unquote_first_word(const char **p, char **ret, bool relax) {
_cleanup_free_ char *s = NULL;
size_t allocated = 0, sz = 0;
break;
case VALUE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
break;
case SINGLE_QUOTE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
- else if (c == '\'')
+ } else if (c == '\'')
state = VALUE;
else if (c == '\\')
state = SINGLE_QUOTE_ESCAPE;
break;
case SINGLE_QUOTE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
break;
case DOUBLE_QUOTE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
l = newa0(char*, n);
for (c = 0; c < n; c++) {
- r = unquote_first_word(p, &l[c]);
+ r = unquote_first_word(p, &l[c], false);
if (r < 0) {
int j;
char *t;
p = original = "foobar waldo";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "foobar"));
free(t);
assert_se(p == original + 7);
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "waldo"));
free(t);
assert_se(p == original + 12);
- assert_se(unquote_first_word(&p, &t) == 0);
+ assert_se(unquote_first_word(&p, &t, false) == 0);
assert_se(!t);
assert_se(p == original + 12);
p = original = "\"foobar\" \'waldo\'";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "foobar"));
free(t);
assert_se(p == original + 9);
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "waldo"));
free(t);
assert_se(p == original + 16);
- assert_se(unquote_first_word(&p, &t) == 0);
+ assert_se(unquote_first_word(&p, &t, false) == 0);
assert_se(!t);
assert_se(p == original + 16);
p = original = "\"";
- assert_se(unquote_first_word(&p, &t) == -EINVAL);
+ assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
assert_se(p == original + 1);
p = original = "\'";
- assert_se(unquote_first_word(&p, &t) == -EINVAL);
+ assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
assert_se(p == original + 1);
+ p = original = "\'fooo";
+ assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
+ assert_se(p == original + 5);
+
+ p = original = "\'fooo";
+ assert_se(unquote_first_word(&p, &t, true) > 0);
+ assert_se(streq(t, "fooo"));
+ assert_se(p == original + 5);
+
p = original = "yay\'foo\'bar";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "yayfoobar"));
free(t);
assert_se(p == original + 11);
p = original = " foobar ";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "foobar"));
free(t);
assert_se(p == original + 12);
free(a);
}
+static int parse_item(const char *key, const char *value) {
+ assert_se(key);
+
+ log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
+ return 0;
+}
+
+static void test_parse_proc_cmdline(void) {
+ assert_se(parse_proc_cmdline(parse_item) >= 0);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
test_execute_directory();
test_unquote_first_word();
test_unquote_many_words();
+ test_parse_proc_cmdline();
return 0;
}