Add new function to filter fstab options
This fixes parsing of options in shared/generator.c. Existing code had some issues: - it would treate whitespace and semicolons as seperators. fstab(5) is pretty clear that only commas matter. And the syntax does not allow for spaces to be inserted in the field in fstab. Whitespace might be escaped, but then it should not seperate options. Treat whitespace and semicolons as any other character. - it assumed that x-systemd.device-timeout would always be followed by "=". But this is not guaranteed, hasmntopt will return this option even if there's no value. Uninitialized memory could be read. - some error paths would log, and inconsistently, some would just return an error code. Filtering is split out to a separate function and tests are added. Similar code paths in other places are adjusted to use the new function.
This commit is contained in:
parent
1e39ff926f
commit
d15d0333be
|
@ -769,6 +769,8 @@ libsystemd_shared_la_SOURCES = \
|
|||
src/shared/architecture.h \
|
||||
src/shared/efivars.c \
|
||||
src/shared/efivars.h \
|
||||
src/shared/fstab-util.c \
|
||||
src/shared/fstab-util.h \
|
||||
src/shared/path-util.c \
|
||||
src/shared/path-util.h \
|
||||
src/shared/time-util.c \
|
||||
|
@ -1367,6 +1369,7 @@ tests += \
|
|||
test-calendarspec \
|
||||
test-strip-tab-ansi \
|
||||
test-cgroup-util \
|
||||
test-fstab-util \
|
||||
test-prioq \
|
||||
test-fileio \
|
||||
test-time \
|
||||
|
@ -1609,6 +1612,12 @@ test_fdset_LDADD = \
|
|||
libsystemd-shared.la \
|
||||
libsystemd-internal.la
|
||||
|
||||
test_fstab_util_SOURCES = \
|
||||
src/test/test-fstab-util.c
|
||||
|
||||
test_fstab_util_LDADD = \
|
||||
libsystemd-shared.la
|
||||
|
||||
test_ratelimit_SOURCES = \
|
||||
src/test/test-ratelimit.c
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "bus-common-errors.h"
|
||||
#include "exit-status.h"
|
||||
#include "def.h"
|
||||
#include "fstab-util.h"
|
||||
|
||||
#define RETRY_UMOUNT_MAX 32
|
||||
|
||||
|
@ -70,7 +71,7 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
|
|||
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
||||
|
||||
static bool mount_needs_network(const char *options, const char *fstype) {
|
||||
if (mount_test_option(options, "_netdev"))
|
||||
if (fstab_test_option(options, "_netdev\0"))
|
||||
return true;
|
||||
|
||||
if (fstype && fstype_is_network(fstype))
|
||||
|
@ -88,16 +89,10 @@ static bool mount_is_network(const MountParameters *p) {
|
|||
static bool mount_is_bind(const MountParameters *p) {
|
||||
assert(p);
|
||||
|
||||
if (mount_test_option(p->options, "bind"))
|
||||
if (fstab_test_option(p->options, "bind\0" "rbind\0"))
|
||||
return true;
|
||||
|
||||
if (p->fstype && streq(p->fstype, "bind"))
|
||||
return true;
|
||||
|
||||
if (mount_test_option(p->options, "rbind"))
|
||||
return true;
|
||||
|
||||
if (p->fstype && streq(p->fstype, "rbind"))
|
||||
if (p->fstype && STR_IN_SET(p->fstype, "bind", "rbind"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -106,7 +101,7 @@ static bool mount_is_bind(const MountParameters *p) {
|
|||
static bool mount_is_auto(const MountParameters *p) {
|
||||
assert(p);
|
||||
|
||||
return !mount_test_option(p->options, "noauto");
|
||||
return !fstab_test_option(p->options, "noauto\0");
|
||||
}
|
||||
|
||||
static bool needs_quota(const MountParameters *p) {
|
||||
|
@ -118,11 +113,8 @@ static bool needs_quota(const MountParameters *p) {
|
|||
if (mount_is_bind(p))
|
||||
return false;
|
||||
|
||||
return mount_test_option(p->options, "usrquota") ||
|
||||
mount_test_option(p->options, "grpquota") ||
|
||||
mount_test_option(p->options, "quota") ||
|
||||
mount_test_option(p->options, "usrjquota") ||
|
||||
mount_test_option(p->options, "grpjquota");
|
||||
return fstab_test_option(p->options,
|
||||
"usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
|
||||
}
|
||||
|
||||
static void mount_init(Unit *u) {
|
||||
|
@ -369,7 +361,7 @@ static bool should_umount(Mount *m) {
|
|||
return false;
|
||||
|
||||
p = get_mount_parameters(m);
|
||||
if (p && mount_test_option(p->options, "x-initrd.mount") &&
|
||||
if (p && fstab_test_option(p->options, "x-initrd.mount\0") &&
|
||||
!in_initrd())
|
||||
return false;
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "path-util.h"
|
||||
#include "virt.h"
|
||||
#include "udev-util.h"
|
||||
#include "fstab-util.h"
|
||||
|
||||
static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
|
||||
[SWAP_DEAD] = UNIT_INACTIVE,
|
||||
|
@ -704,71 +705,6 @@ fail:
|
|||
swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
|
||||
}
|
||||
|
||||
static int mount_find_pri(const char *options, int *ret) {
|
||||
const char *opt;
|
||||
char *end;
|
||||
unsigned long r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (!options)
|
||||
return 0;
|
||||
|
||||
opt = mount_test_option(options, "pri");
|
||||
if (!opt)
|
||||
return 0;
|
||||
|
||||
opt += strlen("pri");
|
||||
if (*opt != '=')
|
||||
return -EINVAL;
|
||||
|
||||
errno = 0;
|
||||
r = strtoul(opt + 1, &end, 10);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
|
||||
if (end == opt + 1 || (*end != ',' && *end != 0))
|
||||
return -EINVAL;
|
||||
|
||||
*ret = (int) r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mount_find_discard(const char *options, char **ret) {
|
||||
const char *opt;
|
||||
char *ans;
|
||||
size_t len;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (!options)
|
||||
return 0;
|
||||
|
||||
opt = mount_test_option(options, "discard");
|
||||
if (!opt)
|
||||
return 0;
|
||||
|
||||
opt += strlen("discard");
|
||||
if (*opt == ',' || *opt == '\0')
|
||||
ans = strdup("all");
|
||||
else {
|
||||
if (*opt != '=')
|
||||
return -EINVAL;
|
||||
|
||||
len = strcspn(opt + 1, ",");
|
||||
if (len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
ans = strndup(opt + 1, len);
|
||||
}
|
||||
|
||||
if (!ans)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = ans;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void swap_enter_activating(Swap *s) {
|
||||
_cleanup_free_ char *discard = NULL;
|
||||
int r, priority = -1;
|
||||
|
@ -779,11 +715,12 @@ static void swap_enter_activating(Swap *s) {
|
|||
s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
|
||||
|
||||
if (s->from_fragment) {
|
||||
mount_find_discard(s->parameters_fragment.options, &discard);
|
||||
fstab_filter_options(s->parameters_fragment.options, "discard\0",
|
||||
NULL, &discard, NULL);
|
||||
|
||||
priority = s->parameters_fragment.priority;
|
||||
if (priority < 0)
|
||||
mount_find_pri(s->parameters_fragment.options, &priority);
|
||||
fstab_find_pri(s->parameters_fragment.options, &priority);
|
||||
}
|
||||
|
||||
r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "util.h"
|
||||
#include "unit-name.h"
|
||||
#include "path-util.h"
|
||||
#include "fstab-util.h"
|
||||
#include "mount-setup.h"
|
||||
#include "special.h"
|
||||
#include "mkdir.h"
|
||||
|
@ -47,33 +48,6 @@ static char *arg_usr_what = NULL;
|
|||
static char *arg_usr_fstype = NULL;
|
||||
static char *arg_usr_options = NULL;
|
||||
|
||||
static int mount_find_pri(struct mntent *me, int *ret) {
|
||||
char *end, *opt;
|
||||
unsigned long r;
|
||||
|
||||
assert(me);
|
||||
assert(ret);
|
||||
|
||||
opt = hasmntopt(me, "pri");
|
||||
if (!opt)
|
||||
return 0;
|
||||
|
||||
opt += strlen("pri");
|
||||
if (*opt != '=')
|
||||
return -EINVAL;
|
||||
|
||||
errno = 0;
|
||||
r = strtoul(opt + 1, &end, 10);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
|
||||
if (end == opt + 1 || (*end != ',' && *end != 0))
|
||||
return -EINVAL;
|
||||
|
||||
*ret = (int) r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_swap(
|
||||
const char *what,
|
||||
struct mntent *me,
|
||||
|
@ -97,11 +71,9 @@ static int add_swap(
|
|||
return 0;
|
||||
}
|
||||
|
||||
r = mount_find_pri(me, &pri);
|
||||
if (r < 0) {
|
||||
log_error("Failed to parse priority");
|
||||
return r;
|
||||
}
|
||||
r = fstab_find_pri(me->mnt_opts, &pri);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse priority: %m");
|
||||
|
||||
name = unit_name_from_path(what, ".swap");
|
||||
if (!name)
|
||||
|
@ -434,8 +406,7 @@ static int add_root_mount(void) {
|
|||
if (!arg_root_options)
|
||||
opts = arg_root_rw > 0 ? "rw" : "ro";
|
||||
else if (arg_root_rw >= 0 ||
|
||||
(!mount_test_option(arg_root_options, "ro") &&
|
||||
!mount_test_option(arg_root_options, "rw")))
|
||||
!fstab_test_option(arg_root_options, "ro\0" "rw\0"))
|
||||
opts = strappenda(arg_root_options, ",", arg_root_rw > 0 ? "rw" : "ro");
|
||||
else
|
||||
opts = arg_root_options;
|
||||
|
@ -492,8 +463,7 @@ static int add_usr_mount(void) {
|
|||
|
||||
if (!arg_usr_options)
|
||||
opts = arg_root_rw > 0 ? "rw" : "ro";
|
||||
else if (!mount_test_option(arg_usr_options, "ro") &&
|
||||
!mount_test_option(arg_usr_options, "rw"))
|
||||
else if (!fstab_test_option(arg_usr_options, "ro\0" "rw\0"))
|
||||
opts = strappenda(arg_usr_options, ",", arg_root_rw > 0 ? "rw" : "ro");
|
||||
else
|
||||
opts = arg_usr_options;
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2015 Zbigniew Jędrzejewski-Szmek
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "fstab-util.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
|
||||
int fstab_filter_options(const char *opts, const char *names,
|
||||
const char **namefound, char **value, char **filtered) {
|
||||
const char *name, *n = NULL, *x;
|
||||
_cleanup_strv_free_ char **stor = NULL;
|
||||
_cleanup_free_ char *v = NULL, **strv = NULL;
|
||||
|
||||
assert(names && *names);
|
||||
|
||||
if (!opts)
|
||||
goto answer;
|
||||
|
||||
/* If !value and !filtered, this function is not allowed to fail. */
|
||||
|
||||
if (!filtered) {
|
||||
const char *word, *state;
|
||||
size_t l;
|
||||
|
||||
FOREACH_WORD_SEPARATOR(word, l, opts, ",", state)
|
||||
NULSTR_FOREACH(name, names) {
|
||||
if (l < strlen(name))
|
||||
continue;
|
||||
if (!strneq(word, name, strlen(name)))
|
||||
continue;
|
||||
|
||||
/* we know that the string is NUL
|
||||
* terminated, so *x is valid */
|
||||
x = word + strlen(name);
|
||||
if (IN_SET(*x, '\0', '=', ',')) {
|
||||
n = name;
|
||||
if (value) {
|
||||
free(v);
|
||||
if (IN_SET(*x, '\0', ','))
|
||||
v = NULL;
|
||||
else {
|
||||
assert(*x == '=');
|
||||
x++;
|
||||
v = strndup(x, l - strlen(name) - 1);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char **t, **s;
|
||||
|
||||
stor = strv_split(opts, ",");
|
||||
if (!stor)
|
||||
return -ENOMEM;
|
||||
strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
|
||||
if (!strv)
|
||||
return -ENOMEM;
|
||||
|
||||
for (s = t = strv; *s; s++) {
|
||||
NULSTR_FOREACH(name, names) {
|
||||
x = startswith(*s, name);
|
||||
if (x && IN_SET(*x, '\0', '='))
|
||||
goto found;
|
||||
}
|
||||
|
||||
*t = *s;
|
||||
t++;
|
||||
continue;
|
||||
found:
|
||||
/* Keep the last occurence found */
|
||||
n = name;
|
||||
if (value) {
|
||||
free(v);
|
||||
if (*x == '\0')
|
||||
v = NULL;
|
||||
else {
|
||||
assert(*x == '=');
|
||||
x++;
|
||||
v = strdup(x);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
*t = NULL;
|
||||
}
|
||||
|
||||
answer:
|
||||
if (namefound)
|
||||
*namefound = n;
|
||||
if (filtered) {
|
||||
char *f;
|
||||
|
||||
f = strv_join(strv, ",");
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
*filtered = f;
|
||||
}
|
||||
if (value) {
|
||||
*value = v;
|
||||
v = NULL;
|
||||
}
|
||||
|
||||
return !!n;
|
||||
}
|
||||
|
||||
int fstab_find_pri(const char *options, int *ret) {
|
||||
_cleanup_free_ char *opt = NULL;
|
||||
int r;
|
||||
unsigned pri;
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = safe_atou(opt, &pri);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = (int) r;
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2015 Zbigniew Jędrzejewski-Szmek
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int fstab_filter_options(const char *opts, const char *names,
|
||||
const char **namefound, char **value, char **filtered);
|
||||
|
||||
static inline bool fstab_test_option(const char *opts, const char *names) {
|
||||
return !!fstab_filter_options(opts, names, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int fstab_find_pri(const char *options, int *ret);
|
|
@ -28,6 +28,7 @@
|
|||
#include "unit-name.h"
|
||||
#include "generator.h"
|
||||
#include "path-util.h"
|
||||
#include "fstab-util.h"
|
||||
#include "dropin.h"
|
||||
|
||||
int generator_write_fsck_deps(
|
||||
|
@ -92,42 +93,16 @@ int generator_write_timeouts(const char *dir, const char *what, const char *wher
|
|||
* endless device timeouts for devices that show up only after
|
||||
* user input, like crypto devices. */
|
||||
|
||||
_cleanup_free_ char *node = NULL, *unit = NULL, *t = NULL;
|
||||
char *start, *timeout;
|
||||
_cleanup_free_ char *node = NULL, *unit = NULL, *timeout = NULL;
|
||||
usec_t u;
|
||||
int r;
|
||||
size_t len;
|
||||
|
||||
if ((start = mount_test_option(opts, "comment=systemd.device-timeout")))
|
||||
timeout = start + 31;
|
||||
else if ((start = mount_test_option(opts, "x-systemd.device-timeout")))
|
||||
timeout = start + 25;
|
||||
else {
|
||||
if (filtered) {
|
||||
*filtered = strdup(opts ?: "");
|
||||
if (!*filtered)
|
||||
return log_oom();
|
||||
}
|
||||
r = fstab_filter_options(opts, "comment=systemd.device-timeout\0" "x-systemd.device-timeout\0",
|
||||
NULL, &timeout, filtered);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = strcspn(timeout, ",;" WHITESPACE);
|
||||
t = strndup(timeout, len);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
if (filtered) {
|
||||
char *prefix, *postfix;
|
||||
|
||||
prefix = strndupa(opts, start - opts - (start != opts));
|
||||
postfix = timeout + len + (start == opts && timeout[len] != '\0');
|
||||
*filtered = strjoin(prefix, *postfix ? postfix : NULL, NULL);
|
||||
if (!*filtered)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = parse_sec(t, &u);
|
||||
r = parse_sec(timeout, &u);
|
||||
if (r < 0) {
|
||||
log_warning("Failed to parse timeout for %s, ignoring: %s",
|
||||
where, timeout);
|
||||
|
@ -140,7 +115,7 @@ int generator_write_timeouts(const char *dir, const char *what, const char *wher
|
|||
|
||||
unit = unit_name_from_path(node, ".device");
|
||||
if (!unit)
|
||||
return -ENOMEM;
|
||||
return log_oom();
|
||||
|
||||
return write_drop_in_format(dir, unit, 50, "device-timeout",
|
||||
"# Automatically generated by %s\n\n"
|
||||
|
|
|
@ -6744,23 +6744,6 @@ uint64_t physical_memory(void) {
|
|||
return (uint64_t) mem * (uint64_t) page_size();
|
||||
}
|
||||
|
||||
char* mount_test_option(const char *haystack, const char *needle) {
|
||||
|
||||
struct mntent me = {
|
||||
.mnt_opts = (char*) haystack
|
||||
};
|
||||
|
||||
assert(needle);
|
||||
|
||||
/* Like glibc's hasmntopt(), but works on a string, not a
|
||||
* struct mntent */
|
||||
|
||||
if (!haystack)
|
||||
return NULL;
|
||||
|
||||
return hasmntopt(&me, needle);
|
||||
}
|
||||
|
||||
void hexdump(FILE *f, const void *p, size_t s) {
|
||||
const uint8_t *b = p;
|
||||
unsigned n = 0;
|
||||
|
|
|
@ -1010,8 +1010,6 @@ const char *personality_to_string(unsigned long);
|
|||
|
||||
uint64_t physical_memory(void);
|
||||
|
||||
char* mount_test_option(const char *haystack, const char *needle);
|
||||
|
||||
void hexdump(FILE *f, const void *p, size_t s);
|
||||
|
||||
union file_handle_union {
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2015 Zbigniew Jędrzejewski-Szmek
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "fstab-util.h"
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
|
||||
/*
|
||||
int fstab_filter_options(const char *opts, const char *names,
|
||||
const char **namefound, char **value, char **filtered);
|
||||
*/
|
||||
|
||||
static void do_fstab_filter_options(const char *opts,
|
||||
const char *remove,
|
||||
int r_expected,
|
||||
const char *name_expected,
|
||||
const char *value_expected,
|
||||
const char *filtered_expected) {
|
||||
|
||||
int r;
|
||||
const char *name;
|
||||
_cleanup_free_ char *value, *filtered;
|
||||
|
||||
r = fstab_filter_options(opts, remove, &name, &value, &filtered);
|
||||
log_info("\"%s\" → %d, \"%s\", \"%s\", \"%s\", expected %d, \"%s\", \"%s\", \"%s\"",
|
||||
opts, r, name, value, filtered,
|
||||
r_expected, name_expected, value_expected, filtered_expected ?: opts);
|
||||
assert_se(r == r_expected);
|
||||
assert_se(streq_ptr(name, name_expected));
|
||||
assert_se(streq_ptr(value, value_expected));
|
||||
assert_se(streq_ptr(filtered, filtered_expected ?: opts));
|
||||
|
||||
/* also test the malloc-less mode */
|
||||
r = fstab_filter_options(opts, remove, &name, NULL, NULL);
|
||||
log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"",
|
||||
opts, r, name,
|
||||
r_expected, name_expected);
|
||||
assert_se(r == r_expected);
|
||||
assert_se(streq_ptr(name, name_expected));
|
||||
}
|
||||
|
||||
static void test_fstab_filter_options(void) {
|
||||
do_fstab_filter_options("opt=0", "opt\0x-opt\0", 1, "opt", "0", "");
|
||||
do_fstab_filter_options("opt=0", "x-opt\0opt\0", 1, "opt", "0", "");
|
||||
do_fstab_filter_options("opt", "opt\0x-opt\0", 1, "opt", NULL, "");
|
||||
do_fstab_filter_options("opt", "x-opt\0opt\0", 1, "opt", NULL, "");
|
||||
do_fstab_filter_options("x-opt", "x-opt\0opt\0", 1, "x-opt", NULL, "");
|
||||
|
||||
do_fstab_filter_options("opt=0,other", "opt\0x-opt\0", 1, "opt", "0", "other");
|
||||
do_fstab_filter_options("opt=0,other", "x-opt\0opt\0", 1, "opt", "0", "other");
|
||||
do_fstab_filter_options("opt,other", "opt\0x-opt\0", 1, "opt", NULL, "other");
|
||||
do_fstab_filter_options("opt,other", "x-opt\0opt\0", 1, "opt", NULL, "other");
|
||||
do_fstab_filter_options("x-opt,other", "opt\0x-opt\0", 1, "x-opt", NULL, "other");
|
||||
|
||||
do_fstab_filter_options("opto=0,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||
do_fstab_filter_options("opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||
do_fstab_filter_options("x-opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||
|
||||
do_fstab_filter_options("first,opt=0", "opt\0x-opt\0", 1, "opt", "0", "first");
|
||||
do_fstab_filter_options("first=1,opt=0", "opt\0x-opt\0", 1, "opt", "0", "first=1");
|
||||
do_fstab_filter_options("first,opt=", "opt\0x-opt\0", 1, "opt", "", "first");
|
||||
do_fstab_filter_options("first=1,opt", "opt\0x-opt\0", 1, "opt", NULL, "first=1");
|
||||
do_fstab_filter_options("first=1,x-opt", "opt\0x-opt\0", 1, "x-opt", NULL, "first=1");
|
||||
|
||||
do_fstab_filter_options("first,opt=0,last=1", "opt\0x-opt\0", 1, "opt", "0", "first,last=1");
|
||||
do_fstab_filter_options("first=1,opt=0,last=2", "x-opt\0opt\0", 1, "opt", "0", "first=1,last=2");
|
||||
do_fstab_filter_options("first,opt,last", "opt\0", 1, "opt", NULL, "first,last");
|
||||
do_fstab_filter_options("first=1,opt,last", "x-opt\0opt\0", 1, "opt", NULL, "first=1,last");
|
||||
do_fstab_filter_options("first=,opt,last", "opt\0noopt\0", 1, "opt", NULL, "first=,last");
|
||||
|
||||
/* check repeated options */
|
||||
do_fstab_filter_options("first,opt=0,noopt=1,last=1", "opt\0noopt\0", 1, "noopt", "1", "first,last=1");
|
||||
do_fstab_filter_options("first=1,opt=0,last=2,opt=1", "opt\0", 1, "opt", "1", "first=1,last=2");
|
||||
do_fstab_filter_options("x-opt=0,x-opt=1", "opt\0x-opt\0", 1, "x-opt", "1", "");
|
||||
do_fstab_filter_options("opt=0,x-opt=1", "opt\0x-opt\0", 1, "x-opt", "1", "");
|
||||
|
||||
/* check that semicolons are not misinterpreted */
|
||||
do_fstab_filter_options("opt=0;", "opt\0", 1, "opt", "0;", "");
|
||||
do_fstab_filter_options("opt;=0", "x-opt\0opt\0noopt\0x-noopt\0", 0, NULL, NULL, NULL);
|
||||
do_fstab_filter_options("opt;", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||
|
||||
/* check that spaces are not misinterpreted */
|
||||
do_fstab_filter_options("opt=0 ", "opt\0", 1, "opt", "0 ", "");
|
||||
do_fstab_filter_options("opt =0", "x-opt\0opt\0noopt\0x-noopt\0", 0, NULL, NULL, NULL);
|
||||
do_fstab_filter_options(" opt ", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||
|
||||
/* check function will NULL args */
|
||||
do_fstab_filter_options(NULL, "opt\0", 0, NULL, NULL, "");
|
||||
do_fstab_filter_options("", "opt\0", 0, NULL, NULL, "");
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
test_fstab_filter_options();
|
||||
}
|
Loading…
Reference in New Issue