path-util: introduce path_simplify()
The function is similar to path_kill_slashes() but also removes initial './', trailing '/.', and '/./' in the path. When the second argument of path_simplify() is false, then it behaves as the same as path_kill_slashes(). Hence, this also replaces path_kill_slashes() with path_simplify().
This commit is contained in:
parent
aff4430136
commit
858d36c1ec
|
@ -628,7 +628,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
|
||||||
if (!t)
|
if (!t)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*fs = path_kill_slashes(t);
|
*fs = path_simplify(t, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
path_kill_slashes(*fs);
|
path_simplify(*fs, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1250,7 +1250,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) {
|
||||||
if (!t)
|
if (!t)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*path = path_kill_slashes(t);
|
*path = path_simplify(t, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller)
|
if (controller)
|
||||||
|
@ -1302,7 +1302,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(u);
|
path_simplify(u, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller)
|
if (controller)
|
||||||
|
@ -1333,7 +1333,7 @@ int cg_mangle_path(const char *path, char **result) {
|
||||||
if (!t)
|
if (!t)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*result = path_kill_slashes(t);
|
*result = path_simplify(t, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1234,7 +1234,7 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
|
||||||
|
|
||||||
strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
|
strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
|
||||||
|
|
||||||
*ret = path_kill_slashes(t);
|
*ret = path_simplify(t, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1275,7 +1275,7 @@ int tempfn_random(const char *p, const char *extra, char **ret) {
|
||||||
|
|
||||||
*x = 0;
|
*x = 0;
|
||||||
|
|
||||||
*ret = path_kill_slashes(t);
|
*ret = path_simplify(t, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1315,7 +1315,7 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
|
||||||
|
|
||||||
*x = 0;
|
*x = 0;
|
||||||
|
|
||||||
*ret = path_kill_slashes(t);
|
*ret = path_simplify(t, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
|
||||||
if (!cleaned)
|
if (!cleaned)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(cleaned);
|
path_simplify(cleaned, false);
|
||||||
|
|
||||||
done = set_new(&path_hash_ops);
|
done = set_new(&path_hash_ops);
|
||||||
if (!done)
|
if (!done)
|
||||||
|
|
|
@ -159,7 +159,7 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r) {
|
||||||
if (!r)
|
if (!r)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(r);
|
path_simplify(r, false);
|
||||||
|
|
||||||
*_r = r;
|
*_r = r;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -214,7 +214,7 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r) {
|
||||||
p = mempcpy(p, "../", 3);
|
p = mempcpy(p, "../", 3);
|
||||||
|
|
||||||
strcpy(p, to_path);
|
strcpy(p, to_path);
|
||||||
path_kill_slashes(r);
|
path_simplify(r, false);
|
||||||
|
|
||||||
*_r = r;
|
*_r = r;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -235,7 +235,7 @@ int path_strv_make_absolute_cwd(char **l) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
path_kill_slashes(t);
|
path_simplify(t, false);
|
||||||
free_and_replace(*s, t);
|
free_and_replace(*s, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,17 +335,30 @@ char **path_strv_resolve_uniq(char **l, const char *root) {
|
||||||
return strv_uniq(l);
|
return strv_uniq(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *path_kill_slashes(char *path) {
|
char *path_simplify(char *path, bool kill_dots) {
|
||||||
char *f, *t;
|
char *f, *t;
|
||||||
bool slash = false;
|
bool slash = false, ignore_slash = false, absolute;
|
||||||
|
|
||||||
/* Removes redundant inner and trailing slashes. Modifies the
|
assert(path);
|
||||||
* passed string in-place.
|
|
||||||
|
/* Removes redundant inner and trailing slashes. Also removes unnecessary dots
|
||||||
|
* if kill_dots is true. Modifies the passed string in-place.
|
||||||
*
|
*
|
||||||
* ///foo///bar/ becomes /foo/bar
|
* ///foo//./bar/. becomes /foo/./bar/. (if kill_dots is false)
|
||||||
|
* ///foo//./bar/. becomes /foo/bar (if kill_dots is true)
|
||||||
|
* .//./foo//./bar/. becomes ./foo/bar (if kill_dots is false)
|
||||||
|
* .//./foo//./bar/. becomes foo/bar (if kill_dots is true)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (f = path, t = path; *f; f++) {
|
absolute = path_is_absolute(path);
|
||||||
|
|
||||||
|
f = path;
|
||||||
|
if (kill_dots && *f == '.' && IN_SET(f[1], 0, '/')) {
|
||||||
|
ignore_slash = true;
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (t = path; *f; f++) {
|
||||||
|
|
||||||
if (*f == '/') {
|
if (*f == '/') {
|
||||||
slash = true;
|
slash = true;
|
||||||
|
@ -353,17 +366,21 @@ char *path_kill_slashes(char *path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slash) {
|
if (slash) {
|
||||||
|
if (kill_dots && *f == '.' && IN_SET(f[1], 0, '/'))
|
||||||
|
continue;
|
||||||
|
|
||||||
slash = false;
|
slash = false;
|
||||||
*(t++) = '/';
|
if (ignore_slash)
|
||||||
|
ignore_slash = false;
|
||||||
|
else
|
||||||
|
*(t++) = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
*(t++) = *f;
|
*(t++) = *f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special rule, if we are talking of the root directory, a
|
/* Special rule, if we are talking of the root directory, a trailing slash is good */
|
||||||
trailing slash is good */
|
if (absolute && t == path)
|
||||||
|
|
||||||
if (t == path && slash)
|
|
||||||
*(t++) = '/';
|
*(t++) = '/';
|
||||||
|
|
||||||
*t = 0;
|
*t = 0;
|
||||||
|
@ -530,7 +547,7 @@ int find_binary(const char *name, char **ret) {
|
||||||
/* Found it! */
|
/* Found it! */
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
*ret = path_kill_slashes(j);
|
*ret = path_simplify(j, false);
|
||||||
j = NULL;
|
j = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,12 +701,11 @@ int parse_path_argument_and_warn(const char *path, bool suppress_root, char **ar
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
|
return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
|
||||||
|
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
if (suppress_root && empty_or_root(p))
|
if (suppress_root && empty_or_root(p))
|
||||||
p = mfree(p);
|
p = mfree(p);
|
||||||
|
|
||||||
free(*arg);
|
free_and_replace(*arg, p);
|
||||||
*arg = p;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,12 +50,12 @@ char* path_make_absolute(const char *p, const char *prefix);
|
||||||
int safe_getcwd(char **ret);
|
int safe_getcwd(char **ret);
|
||||||
int path_make_absolute_cwd(const char *p, char **ret);
|
int path_make_absolute_cwd(const char *p, char **ret);
|
||||||
int path_make_relative(const char *from_dir, const char *to_path, char **_r);
|
int path_make_relative(const char *from_dir, const char *to_path, char **_r);
|
||||||
char* path_kill_slashes(char *path);
|
|
||||||
char* path_startswith(const char *path, const char *prefix) _pure_;
|
char* path_startswith(const char *path, const char *prefix) _pure_;
|
||||||
int path_compare(const char *a, const char *b) _pure_;
|
int path_compare(const char *a, const char *b) _pure_;
|
||||||
bool path_equal(const char *a, const char *b) _pure_;
|
bool path_equal(const char *a, const char *b) _pure_;
|
||||||
bool path_equal_or_files_same(const char *a, const char *b, int flags);
|
bool path_equal_or_files_same(const char *a, const char *b, int flags);
|
||||||
char* path_join(const char *root, const char *path, const char *rest);
|
char* path_join(const char *root, const char *path, const char *rest);
|
||||||
|
char* path_simplify(char *path, bool kill_dots);
|
||||||
|
|
||||||
static inline bool path_equal_ptr(const char *a, const char *b) {
|
static inline bool path_equal_ptr(const char *a, const char *b) {
|
||||||
return !!a == !!b && (!a || path_equal(a, b));
|
return !!a == !!b && (!a || path_equal(a, b));
|
||||||
|
@ -101,11 +101,11 @@ int mkfs_exists(const char *fstype);
|
||||||
* the tree, to root. Also returns "" (and not "/"!) for the root
|
* the tree, to root. Also returns "" (and not "/"!) for the root
|
||||||
* directory. Excludes the specified directory itself */
|
* directory. Excludes the specified directory itself */
|
||||||
#define PATH_FOREACH_PREFIX(prefix, path) \
|
#define PATH_FOREACH_PREFIX(prefix, path) \
|
||||||
for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); streq(prefix, "/") ? NULL : strrchr(prefix, '/'); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
|
for (char *_slash = ({ path_simplify(strcpy(prefix, path), false); streq(prefix, "/") ? NULL : strrchr(prefix, '/'); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
|
||||||
|
|
||||||
/* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */
|
/* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */
|
||||||
#define PATH_FOREACH_PREFIX_MORE(prefix, path) \
|
#define PATH_FOREACH_PREFIX_MORE(prefix, path) \
|
||||||
for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); if (streq(prefix, "/")) prefix[0] = 0; strrchr(prefix, 0); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
|
for (char *_slash = ({ path_simplify(strcpy(prefix, path), false); if (streq(prefix, "/")) prefix[0] = 0; strrchr(prefix, 0); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
|
||||||
|
|
||||||
char *prefix_root(const char *root, const char *path);
|
char *prefix_root(const char *root, const char *path);
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ int unit_name_path_escape(const char *f, char **ret) {
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
|
|
||||||
if (empty_or_root(p))
|
if (empty_or_root(p))
|
||||||
s = strdup("-");
|
s = strdup("-");
|
||||||
|
|
|
@ -241,7 +241,7 @@ int main(int argc, char *argv[]) {
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(j);
|
path_simplify(j, false);
|
||||||
path = j;
|
path = j;
|
||||||
} else
|
} else
|
||||||
path = root;
|
path = root;
|
||||||
|
|
|
@ -470,7 +470,7 @@ static int refresh_one(
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
|
|
||||||
r = refresh_one(controller, p, a, b, iteration, depth + 1, &child);
|
r = refresh_one(controller, p, a, b, iteration, depth + 1, &child);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -199,7 +199,7 @@ static int automount_set_where(Automount *a) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
path_kill_slashes(a->where);
|
path_simplify(a->where, false);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1519,7 +1519,7 @@ static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suf
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pp = strjoina("/", pp, suffix_path);
|
pp = strjoina("/", pp, suffix_path);
|
||||||
path_kill_slashes(pp);
|
path_simplify(pp, false);
|
||||||
|
|
||||||
r = sd_bus_call_method(u->manager->system_bus,
|
r = sd_bus_call_method(u->manager->system_bus,
|
||||||
"org.freedesktop.systemd1",
|
"org.freedesktop.systemd1",
|
||||||
|
|
|
@ -935,7 +935,7 @@ int bus_set_transient_exec_command(
|
||||||
|
|
||||||
c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
|
c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
|
||||||
|
|
||||||
path_kill_slashes(c->path);
|
path_simplify(c->path, false);
|
||||||
exec_command_append_list(exec_command, c);
|
exec_command_append_list(exec_command, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2051,7 +2051,7 @@ int bus_exec_context_set_transient_property(
|
||||||
if (!path_is_absolute(i + offset))
|
if (!path_is_absolute(i + offset))
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
|
||||||
|
|
||||||
path_kill_slashes(i + offset);
|
path_simplify(i + offset, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
|
|
@ -108,13 +108,14 @@ static int bus_path_set_transient_property(
|
||||||
if (!k)
|
if (!k)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
path_simplify(k, false);
|
||||||
|
|
||||||
s = new0(PathSpec, 1);
|
s = new0(PathSpec, 1);
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
s->unit = u;
|
s->unit = u;
|
||||||
s->path = path_kill_slashes(k);
|
s->path = TAKE_PTR(k);
|
||||||
k = NULL;
|
|
||||||
s->type = t;
|
s->type = t;
|
||||||
s->inotify_fd = -1;
|
s->inotify_fd = -1;
|
||||||
|
|
||||||
|
|
|
@ -365,7 +365,7 @@ static int bus_socket_set_transient_property(
|
||||||
|
|
||||||
if (p->type != SOCKET_SOCKET) {
|
if (p->type != SOCKET_SOCKET) {
|
||||||
p->path = strdup(a);
|
p->path = strdup(a);
|
||||||
path_kill_slashes(p->path);
|
path_simplify(p->path, false);
|
||||||
|
|
||||||
} else if (streq(t, "Netlink")) {
|
} else if (streq(t, "Netlink")) {
|
||||||
r = socket_address_parse_netlink(&p->address, a);
|
r = socket_address_parse_netlink(&p->address, a);
|
||||||
|
|
|
@ -325,7 +325,7 @@ int config_parse_unit_path_strv_printf(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(k);
|
path_simplify(k, false);
|
||||||
|
|
||||||
r = strv_push(x, k);
|
r = strv_push(x, k);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -376,7 +376,7 @@ int config_parse_socket_listen(const char *unit,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(p->path);
|
path_simplify(p->path, false);
|
||||||
|
|
||||||
} else if (streq(lvalue, "ListenNetlink")) {
|
} else if (streq(lvalue, "ListenNetlink")) {
|
||||||
_cleanup_free_ char *k = NULL;
|
_cleanup_free_ char *k = NULL;
|
||||||
|
@ -673,7 +673,7 @@ int config_parse_exec(
|
||||||
n[nlen] = NULL;
|
n[nlen] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(path);
|
path_simplify(path, false);
|
||||||
|
|
||||||
while (!isempty(p)) {
|
while (!isempty(p)) {
|
||||||
_cleanup_free_ char *word = NULL, *resolved = NULL;
|
_cleanup_free_ char *word = NULL, *resolved = NULL;
|
||||||
|
@ -1624,7 +1624,7 @@ int config_parse_path_spec(const char *unit,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(k);
|
path_simplify(k, false);
|
||||||
|
|
||||||
if (!path_is_absolute(k)) {
|
if (!path_is_absolute(k)) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Path is not absolute, ignoring: %s", k);
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Path is not absolute, ignoring: %s", k);
|
||||||
|
@ -2048,7 +2048,7 @@ int config_parse_working_directory(
|
||||||
return missing_ok ? 0 : -ENOEXEC;
|
return missing_ok ? 0 : -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(k);
|
path_simplify(k, false);
|
||||||
|
|
||||||
if (!utf8_is_valid(k)) {
|
if (!utf8_is_valid(k)) {
|
||||||
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
|
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
|
||||||
|
@ -3871,7 +3871,7 @@ int config_parse_namespace_path_strv(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(resolved);
|
path_simplify(resolved, false);
|
||||||
|
|
||||||
joined = strjoin(ignore_enoent ? "-" : "",
|
joined = strjoin(ignore_enoent ? "-" : "",
|
||||||
shall_prefix ? "+" : "",
|
shall_prefix ? "+" : "",
|
||||||
|
@ -3955,7 +3955,7 @@ int config_parse_temporary_filesystems(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(resolved);
|
path_simplify(resolved, false);
|
||||||
|
|
||||||
r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, w);
|
r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, w);
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
|
@ -4036,7 +4036,7 @@ int config_parse_bind_paths(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(s);
|
path_simplify(s, false);
|
||||||
|
|
||||||
/* Optionally, the destination is specified. */
|
/* Optionally, the destination is specified. */
|
||||||
if (p && p[-1] == ':') {
|
if (p && p[-1] == ':') {
|
||||||
|
@ -4068,7 +4068,7 @@ int config_parse_bind_paths(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
d = path_kill_slashes(dresolved);
|
d = path_simplify(dresolved, false);
|
||||||
|
|
||||||
/* Optionally, there's also a short option string specified */
|
/* Optionally, there's also a short option string specified */
|
||||||
if (p && p[-1] == ':') {
|
if (p && p[-1] == ':') {
|
||||||
|
@ -4203,7 +4203,7 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
|
||||||
if (c++ >= FOLLOW_MAX)
|
if (c++ >= FOLLOW_MAX)
|
||||||
return -ELOOP;
|
return -ELOOP;
|
||||||
|
|
||||||
path_kill_slashes(*filename);
|
path_simplify(*filename, false);
|
||||||
|
|
||||||
/* Add the file name we are currently looking at to
|
/* Add the file name we are currently looking at to
|
||||||
* the names of this unit, but only if it is a valid
|
* the names of this unit, but only if it is a valid
|
||||||
|
|
|
@ -3867,7 +3867,7 @@ Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
|
||||||
assert(path);
|
assert(path);
|
||||||
|
|
||||||
strcpy(p, path);
|
strcpy(p, path);
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
|
|
||||||
return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
|
return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,7 +554,7 @@ static int mount_add_extras(Mount *m) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(m->where);
|
path_simplify(m->where, false);
|
||||||
|
|
||||||
if (!u->description) {
|
if (!u->description) {
|
||||||
r = unit_set_description(u, m->where);
|
r = unit_set_description(u, m->where);
|
||||||
|
|
|
@ -67,7 +67,7 @@ int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
|
||||||
|
|
||||||
(void) sd_event_source_set_description(s->event_source, "path");
|
(void) sd_event_source_set_description(s->event_source, "path");
|
||||||
|
|
||||||
/* This function assumes the path was passed through path_kill_slashes()! */
|
/* This function assumes the path was passed through path_simplify()! */
|
||||||
assert(!strstr(s->path, "//"));
|
assert(!strstr(s->path, "//"));
|
||||||
|
|
||||||
for (slash = strchr(s->path, '/'); ; slash = strchr(slash+1, '/')) {
|
for (slash = strchr(s->path, '/'); ; slash = strchr(slash+1, '/')) {
|
||||||
|
|
|
@ -2887,7 +2887,7 @@ static int service_demand_pid_file(Service *s) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(ps->path);
|
path_simplify(ps->path, false);
|
||||||
|
|
||||||
/* PATH_CHANGED would not be enough. There are daemons (sendmail) that
|
/* PATH_CHANGED would not be enough. There are daemons (sendmail) that
|
||||||
* keep their PID file open all the time. */
|
* keep their PID file open all the time. */
|
||||||
|
|
|
@ -1393,7 +1393,7 @@ static int usbffs_dispatch_eps(SocketPort *p) {
|
||||||
if (!ep)
|
if (!ep)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(ep);
|
path_simplify(ep, false);
|
||||||
|
|
||||||
r = usbffs_address_create(ep);
|
r = usbffs_address_create(ep);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -307,7 +307,7 @@ static int swap_load(Unit *u) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(s->what);
|
path_simplify(s->what, false);
|
||||||
|
|
||||||
if (!UNIT(s)->description) {
|
if (!UNIT(s)->description) {
|
||||||
r = unit_set_description(u, s->what);
|
r = unit_set_description(u, s->what);
|
||||||
|
|
|
@ -4551,7 +4551,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path = path_kill_slashes(p);
|
path = path_simplify(p, false);
|
||||||
|
|
||||||
if (!path_is_normalized(path))
|
if (!path_is_normalized(path))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
|
@ -655,7 +655,7 @@ int main(int argc, char *argv[]) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = optind; i < argc; i++) {
|
for (i = optind; i < argc; i++) {
|
||||||
path_kill_slashes(argv[i]);
|
path_simplify(argv[i], false);
|
||||||
|
|
||||||
k = process_suffix_chop(argv[i]);
|
k = process_suffix_chop(argv[i]);
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
|
|
|
@ -543,7 +543,7 @@ static int parse_fstab(bool initrd) {
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
if (is_path(where)) {
|
if (is_path(where)) {
|
||||||
path_kill_slashes(where);
|
path_simplify(where, false);
|
||||||
|
|
||||||
/* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
|
/* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
|
||||||
* mount units, but causes problems since it historically worked to have symlinks in e.g.
|
* mount units, but causes problems since it historically worked to have symlinks in e.g.
|
||||||
|
|
|
@ -178,7 +178,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
free_and_replace(syspath, new_syspath);
|
free_and_replace(syspath, new_syspath);
|
||||||
path_kill_slashes(syspath);
|
path_simplify(syspath, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path_startswith(syspath, "/sys/devices/")) {
|
if (path_startswith(syspath, "/sys/devices/")) {
|
||||||
|
|
|
@ -354,7 +354,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
if (!arg_mount_what)
|
if (!arg_mount_what)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
path_kill_slashes(arg_mount_what);
|
path_simplify(arg_mount_what, false);
|
||||||
|
|
||||||
if (!path_is_absolute(arg_mount_what)) {
|
if (!path_is_absolute(arg_mount_what)) {
|
||||||
log_error("Only absolute path is supported: %s", arg_mount_what);
|
log_error("Only absolute path is supported: %s", arg_mount_what);
|
||||||
|
@ -372,7 +372,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
if (!arg_mount_where)
|
if (!arg_mount_where)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
path_kill_slashes(arg_mount_where);
|
path_simplify(arg_mount_where, false);
|
||||||
|
|
||||||
if (!path_is_absolute(arg_mount_where)) {
|
if (!path_is_absolute(arg_mount_where)) {
|
||||||
log_error("Only absolute path is supported: %s", arg_mount_where);
|
log_error("Only absolute path is supported: %s", arg_mount_where);
|
||||||
|
@ -992,7 +992,7 @@ static int action_umount(
|
||||||
if (!p)
|
if (!p)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
|
|
||||||
r = stop_mounts(bus, p);
|
r = stop_mounts(bus, p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -630,14 +630,14 @@ static int portable_changes_add(
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
s = strdup(source);
|
s = strdup(source);
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(s);
|
path_simplify(s, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
c[(*n_changes)++] = (PortableChange) {
|
c[(*n_changes)++] = (PortableChange) {
|
||||||
|
|
|
@ -740,7 +740,7 @@ int config_parse_path(
|
||||||
if (!n)
|
if (!n)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
path_kill_slashes(n);
|
path_simplify(n, false);
|
||||||
|
|
||||||
finalize:
|
finalize:
|
||||||
free(*s);
|
free(*s);
|
||||||
|
|
|
@ -309,9 +309,9 @@ int unit_file_changes_add(
|
||||||
if (!p || (source && !s))
|
if (!p || (source && !s))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
if (s)
|
if (s)
|
||||||
path_kill_slashes(s);
|
path_simplify(s, false);
|
||||||
|
|
||||||
c[*n_changes] = (UnitFileChange) { type, p, s };
|
c[*n_changes] = (UnitFileChange) { type, p, s };
|
||||||
p = s = NULL;
|
p = s = NULL;
|
||||||
|
@ -516,7 +516,7 @@ static int mark_symlink_for_removal(
|
||||||
if (!n)
|
if (!n)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(n);
|
path_simplify(n, false);
|
||||||
|
|
||||||
r = set_consume(*remove_symlinks_to, n);
|
r = set_consume(*remove_symlinks_to, n);
|
||||||
if (r == -EEXIST)
|
if (r == -EEXIST)
|
||||||
|
@ -598,7 +598,7 @@ static int remove_marked_symlinks_fd(
|
||||||
p = path_make_absolute(de->d_name, path);
|
p = path_make_absolute(de->d_name, path);
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
path_kill_slashes(p);
|
path_simplify(p, false);
|
||||||
|
|
||||||
q = readlink_malloc(p, &dest);
|
q = readlink_malloc(p, &dest);
|
||||||
if (q == -ENOENT)
|
if (q == -ENOENT)
|
||||||
|
|
|
@ -170,7 +170,7 @@ static int image_new(
|
||||||
if (!i->path)
|
if (!i->path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
path_kill_slashes(i->path);
|
path_simplify(i->path, false);
|
||||||
|
|
||||||
*ret = TAKE_PTR(i);
|
*ret = TAKE_PTR(i);
|
||||||
|
|
||||||
|
|
|
@ -1599,8 +1599,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||||
if (resolved_id) {
|
if (resolved_id) {
|
||||||
if (path_is_absolute(resolved_id)) {
|
if (path_is_absolute(resolved_id)) {
|
||||||
i->uid_path = TAKE_PTR(resolved_id);
|
i->uid_path = TAKE_PTR(resolved_id);
|
||||||
|
path_simplify(i->uid_path, false);
|
||||||
path_kill_slashes(i->uid_path);
|
|
||||||
} else {
|
} else {
|
||||||
_cleanup_free_ char *uid = NULL, *gid = NULL;
|
_cleanup_free_ char *uid = NULL, *gid = NULL;
|
||||||
if (split_pair(resolved_id, ":", &uid, &gid) == 0) {
|
if (split_pair(resolved_id, ":", &uid, &gid) == 0) {
|
||||||
|
@ -1651,8 +1650,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||||
if (resolved_id) {
|
if (resolved_id) {
|
||||||
if (path_is_absolute(resolved_id)) {
|
if (path_is_absolute(resolved_id)) {
|
||||||
i->gid_path = TAKE_PTR(resolved_id);
|
i->gid_path = TAKE_PTR(resolved_id);
|
||||||
|
path_simplify(i->gid_path, false);
|
||||||
path_kill_slashes(i->gid_path);
|
|
||||||
} else {
|
} else {
|
||||||
r = parse_gid(resolved_id, &i->gid);
|
r = parse_gid(resolved_id, &i->gid);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -26,6 +26,16 @@
|
||||||
assert_se(path_equal(b, a) == !result); \
|
assert_se(path_equal(b, a) == !result); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_path_simplify(const char *in, const char *out, const char *out_dot) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = strdupa(in);
|
||||||
|
assert_se(streq(path_simplify(p, false), out));
|
||||||
|
|
||||||
|
p = strdupa(in);
|
||||||
|
assert_se(streq(path_simplify(p, true), out_dot));
|
||||||
|
}
|
||||||
|
|
||||||
static void test_path(void) {
|
static void test_path(void) {
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
|
|
||||||
|
@ -69,15 +79,28 @@ static void test_path(void) {
|
||||||
assert_se(fd >= 0);
|
assert_se(fd >= 0);
|
||||||
assert_se(fd_is_mount_point(fd, "/", 0) > 0);
|
assert_se(fd_is_mount_point(fd, "/", 0) > 0);
|
||||||
|
|
||||||
{
|
test_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc", "aaa/bbb/ccc");
|
||||||
char p1[] = "aaa/bbb////ccc";
|
test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc");
|
||||||
char p2[] = "//aaa/.////ccc";
|
test_path_simplify("///", "/", "/");
|
||||||
char p3[] = "/./";
|
test_path_simplify("///.//", "/.", "/");
|
||||||
|
test_path_simplify("///.//.///", "/./.", "/");
|
||||||
assert_se(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc"));
|
test_path_simplify("////.././///../.", "/.././../.", "/../..");
|
||||||
assert_se(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
|
test_path_simplify(".", ".", "");
|
||||||
assert_se(path_equal(path_kill_slashes(p3), "/./"));
|
test_path_simplify("./", ".", "");
|
||||||
}
|
test_path_simplify(".///.//./.", "./././.", "");
|
||||||
|
test_path_simplify(".///.//././/", "./././.", "");
|
||||||
|
test_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
|
||||||
|
"/./aaa/././.bbb/../c./d.dd/..eeee/.",
|
||||||
|
"/aaa/.bbb/../c./d.dd/..eeee");
|
||||||
|
test_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||||
|
"/./aaa/././.bbb/../c./d.dd/..eeee/..",
|
||||||
|
"/aaa/.bbb/../c./d.dd/..eeee/..");
|
||||||
|
test_path_simplify(".//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||||
|
"././aaa/././.bbb/../c./d.dd/..eeee/..",
|
||||||
|
"aaa/.bbb/../c./d.dd/..eeee/..");
|
||||||
|
test_path_simplify("..//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||||
|
".././aaa/././.bbb/../c./d.dd/..eeee/..",
|
||||||
|
"../aaa/.bbb/../c./d.dd/..eeee/..");
|
||||||
|
|
||||||
assert_se(PATH_IN_SET("/bin", "/", "/bin", "/foo"));
|
assert_se(PATH_IN_SET("/bin", "/", "/bin", "/foo"));
|
||||||
assert_se(PATH_IN_SET("/bin", "/bin"));
|
assert_se(PATH_IN_SET("/bin", "/bin"));
|
||||||
|
|
|
@ -431,7 +431,7 @@ static void load_unix_sockets(void) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(s);
|
path_simplify(s, false);
|
||||||
|
|
||||||
r = set_consume(unix_sockets, s);
|
r = set_consume(unix_sockets, s);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
|
@ -2289,7 +2289,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(i.argument);
|
path_simplify(i.argument, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREATE_CHAR_DEVICE:
|
case CREATE_CHAR_DEVICE:
|
||||||
|
@ -2362,7 +2362,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_kill_slashes(i.path);
|
path_simplify(i.path, false);
|
||||||
|
|
||||||
if (!should_include_path(i.path))
|
if (!should_include_path(i.path))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue