diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 1b0221edc4..ca31dee4a7 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -628,7 +628,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch if (!t) return -ENOMEM; - *fs = path_kill_slashes(t); + *fs = path_simplify(t, false); return 0; } @@ -645,7 +645,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch if (r < 0) return r; - path_kill_slashes(*fs); + path_simplify(*fs, false); return 0; } @@ -1250,7 +1250,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) { if (!t) return -ENOMEM; - *path = path_kill_slashes(t); + *path = path_simplify(t, false); } if (controller) @@ -1302,7 +1302,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) { return -EINVAL; } - path_kill_slashes(u); + path_simplify(u, false); } if (controller) @@ -1333,7 +1333,7 @@ int cg_mangle_path(const char *path, char **result) { if (!t) return -ENOMEM; - *result = path_kill_slashes(t); + *result = path_simplify(t, false); return 0; } diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 6dd00e0698..c12b4ac7f5 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -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"); - *ret = path_kill_slashes(t); + *ret = path_simplify(t, false); return 0; } @@ -1275,7 +1275,7 @@ int tempfn_random(const char *p, const char *extra, char **ret) { *x = 0; - *ret = path_kill_slashes(t); + *ret = path_simplify(t, false); return 0; } @@ -1315,7 +1315,7 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { *x = 0; - *ret = path_kill_slashes(t); + *ret = path_simplify(t, false); return 0; } diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index 2774e48cf3..68a83ebae7 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -413,7 +413,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl if (!cleaned) return -ENOMEM; - path_kill_slashes(cleaned); + path_simplify(cleaned, false); done = set_new(&path_hash_ops); if (!done) diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 4f428818d1..769417c6a9 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -159,7 +159,7 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r) { if (!r) return -ENOMEM; - path_kill_slashes(r); + path_simplify(r, false); *_r = r; return 0; @@ -214,7 +214,7 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r) { p = mempcpy(p, "../", 3); strcpy(p, to_path); - path_kill_slashes(r); + path_simplify(r, false); *_r = r; return 0; @@ -235,7 +235,7 @@ int path_strv_make_absolute_cwd(char **l) { if (r < 0) return r; - path_kill_slashes(t); + path_simplify(t, false); free_and_replace(*s, t); } @@ -335,17 +335,30 @@ char **path_strv_resolve_uniq(char **l, const char *root) { return strv_uniq(l); } -char *path_kill_slashes(char *path) { +char *path_simplify(char *path, bool kill_dots) { char *f, *t; - bool slash = false; + bool slash = false, ignore_slash = false, absolute; - /* Removes redundant inner and trailing slashes. Modifies the - * passed string in-place. + assert(path); + + /* 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 == '/') { slash = true; @@ -353,17 +366,21 @@ char *path_kill_slashes(char *path) { } if (slash) { + if (kill_dots && *f == '.' && IN_SET(f[1], 0, '/')) + continue; + slash = false; - *(t++) = '/'; + if (ignore_slash) + ignore_slash = false; + else + *(t++) = '/'; } *(t++) = *f; } - /* Special rule, if we are talking of the root directory, a - trailing slash is good */ - - if (t == path && slash) + /* Special rule, if we are talking of the root directory, a trailing slash is good */ + if (absolute && t == path) *(t++) = '/'; *t = 0; @@ -530,7 +547,7 @@ int find_binary(const char *name, char **ret) { /* Found it! */ if (ret) { - *ret = path_kill_slashes(j); + *ret = path_simplify(j, false); j = NULL; } @@ -684,12 +701,11 @@ int parse_path_argument_and_warn(const char *path, bool suppress_root, char **ar if (r < 0) 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)) p = mfree(p); - free(*arg); - *arg = p; + free_and_replace(*arg, p); return 0; } diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 134e1ebc98..fd6dc1ed1a 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -50,12 +50,12 @@ char* path_make_absolute(const char *p, const char *prefix); int safe_getcwd(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); -char* path_kill_slashes(char *path); char* path_startswith(const char *path, const char *prefix) _pure_; int path_compare(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); 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) { 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 * directory. Excludes the specified directory itself */ #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 */ #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); diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index 479079099b..4fa00663e4 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -383,7 +383,7 @@ int unit_name_path_escape(const char *f, char **ret) { if (!p) return -ENOMEM; - path_kill_slashes(p); + path_simplify(p, false); if (empty_or_root(p)) s = strdup("-"); diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index 7c7ea18b61..4ad84bec93 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -241,7 +241,7 @@ int main(int argc, char *argv[]) { goto finish; } - path_kill_slashes(j); + path_simplify(j, false); path = j; } else path = root; diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index 401c08600a..b2b6a25b48 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -470,7 +470,7 @@ static int refresh_one( if (!p) return -ENOMEM; - path_kill_slashes(p); + path_simplify(p, false); r = refresh_one(controller, p, a, b, iteration, depth + 1, &child); if (r < 0) diff --git a/src/core/automount.c b/src/core/automount.c index c49b523eb2..e7ef6e78da 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -199,7 +199,7 @@ static int automount_set_where(Automount *a) { if (r < 0) return r; - path_kill_slashes(a->where); + path_simplify(a->where, false); return 1; } diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 25778320ab..b3f8600eb4 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1519,7 +1519,7 @@ static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suf return -EINVAL; pp = strjoina("/", pp, suffix_path); - path_kill_slashes(pp); + path_simplify(pp, false); r = sd_bus_call_method(u->manager->system_bus, "org.freedesktop.systemd1", diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index ec1b62fb42..8c752ceaa6 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -935,7 +935,7 @@ int bus_set_transient_exec_command( 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); } @@ -2051,7 +2051,7 @@ int bus_exec_context_set_transient_property( if (!path_is_absolute(i + offset)) 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)) { diff --git a/src/core/dbus-path.c b/src/core/dbus-path.c index fec67d595f..7bd0acac22 100644 --- a/src/core/dbus-path.c +++ b/src/core/dbus-path.c @@ -108,13 +108,14 @@ static int bus_path_set_transient_property( if (!k) return -ENOMEM; + path_simplify(k, false); + s = new0(PathSpec, 1); if (!s) return -ENOMEM; s->unit = u; - s->path = path_kill_slashes(k); - k = NULL; + s->path = TAKE_PTR(k); s->type = t; s->inotify_fd = -1; diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 88e180a037..aee81430bb 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -365,7 +365,7 @@ static int bus_socket_set_transient_property( if (p->type != SOCKET_SOCKET) { p->path = strdup(a); - path_kill_slashes(p->path); + path_simplify(p->path, false); } else if (streq(t, "Netlink")) { r = socket_address_parse_netlink(&p->address, a); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index dd4c755894..8e692bf677 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -325,7 +325,7 @@ int config_parse_unit_path_strv_printf( return 0; } - path_kill_slashes(k); + path_simplify(k, false); r = strv_push(x, k); if (r < 0) @@ -376,7 +376,7 @@ int config_parse_socket_listen(const char *unit, return 0; } - path_kill_slashes(p->path); + path_simplify(p->path, false); } else if (streq(lvalue, "ListenNetlink")) { _cleanup_free_ char *k = NULL; @@ -673,7 +673,7 @@ int config_parse_exec( n[nlen] = NULL; } - path_kill_slashes(path); + path_simplify(path, false); while (!isempty(p)) { _cleanup_free_ char *word = NULL, *resolved = NULL; @@ -1624,7 +1624,7 @@ int config_parse_path_spec(const char *unit, return 0; } - path_kill_slashes(k); + path_simplify(k, false); if (!path_is_absolute(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; } - path_kill_slashes(k); + path_simplify(k, false); if (!utf8_is_valid(k)) { log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue); @@ -3871,7 +3871,7 @@ int config_parse_namespace_path_strv( continue; } - path_kill_slashes(resolved); + path_simplify(resolved, false); joined = strjoin(ignore_enoent ? "-" : "", shall_prefix ? "+" : "", @@ -3955,7 +3955,7 @@ int config_parse_temporary_filesystems( continue; } - path_kill_slashes(resolved); + path_simplify(resolved, false); r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, w); if (r == -ENOMEM) @@ -4036,7 +4036,7 @@ int config_parse_bind_paths( return 0; } - path_kill_slashes(s); + path_simplify(s, false); /* Optionally, the destination is specified. */ if (p && p[-1] == ':') { @@ -4068,7 +4068,7 @@ int config_parse_bind_paths( return 0; } - d = path_kill_slashes(dresolved); + d = path_simplify(dresolved, false); /* Optionally, there's also a short option string specified */ if (p && p[-1] == ':') { @@ -4203,7 +4203,7 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { if (c++ >= FOLLOW_MAX) return -ELOOP; - path_kill_slashes(*filename); + path_simplify(*filename, false); /* Add the file name we are currently looking at to * the names of this unit, but only if it is a valid diff --git a/src/core/manager.c b/src/core/manager.c index b4f197c204..b5742f1f7f 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -3867,7 +3867,7 @@ Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) { assert(path); strcpy(p, path); - path_kill_slashes(p); + path_simplify(p, false); return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p); } diff --git a/src/core/mount.c b/src/core/mount.c index d5463b7621..d9bc4abb20 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -554,7 +554,7 @@ static int mount_add_extras(Mount *m) { return r; } - path_kill_slashes(m->where); + path_simplify(m->where, false); if (!u->description) { r = unit_set_description(u, m->where); diff --git a/src/core/path.c b/src/core/path.c index c0c0f07563..e0b9238ce0 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -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"); - /* 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, "//")); for (slash = strchr(s->path, '/'); ; slash = strchr(slash+1, '/')) { diff --git a/src/core/service.c b/src/core/service.c index 1af3032597..068fd67be7 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -2887,7 +2887,7 @@ static int service_demand_pid_file(Service *s) { return -ENOMEM; } - path_kill_slashes(ps->path); + path_simplify(ps->path, false); /* PATH_CHANGED would not be enough. There are daemons (sendmail) that * keep their PID file open all the time. */ diff --git a/src/core/socket.c b/src/core/socket.c index 238c942a1a..0ef355a73b 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1393,7 +1393,7 @@ static int usbffs_dispatch_eps(SocketPort *p) { if (!ep) return -ENOMEM; - path_kill_slashes(ep); + path_simplify(ep, false); r = usbffs_address_create(ep); if (r < 0) diff --git a/src/core/swap.c b/src/core/swap.c index e75c9f2464..95534bdda4 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -307,7 +307,7 @@ static int swap_load(Unit *u) { return -ENOMEM; } - path_kill_slashes(s->what); + path_simplify(s->what, false); if (!UNIT(s)->description) { r = unit_set_description(u, s->what); diff --git a/src/core/unit.c b/src/core/unit.c index 2567365937..fd0d8da3aa 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -4551,7 +4551,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) if (!p) return -ENOMEM; - path = path_kill_slashes(p); + path = path_simplify(p, false); if (!path_is_normalized(path)) return -EPERM; diff --git a/src/delta/delta.c b/src/delta/delta.c index aab1dbfad2..074ef426a9 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -655,7 +655,7 @@ int main(int argc, char *argv[]) { int i; for (i = optind; i < argc; i++) { - path_kill_slashes(argv[i]); + path_simplify(argv[i], false); k = process_suffix_chop(argv[i]); if (k < 0) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 5c7e1df8f1..daa8f5cd16 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -543,7 +543,7 @@ static int parse_fstab(bool initrd) { return log_oom(); if (is_path(where)) { - path_kill_slashes(where); + path_simplify(where, false); /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for * mount units, but causes problems since it historically worked to have symlinks in e.g. diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 7726cdb3aa..0e92fcbe03 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -178,7 +178,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { return log_oom(); free_and_replace(syspath, new_syspath); - path_kill_slashes(syspath); + path_simplify(syspath, false); } if (path_startswith(syspath, "/sys/devices/")) { diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index 02989301fe..5e22a434f1 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -354,7 +354,7 @@ static int parse_argv(int argc, char *argv[]) { if (!arg_mount_what) return log_oom(); - path_kill_slashes(arg_mount_what); + path_simplify(arg_mount_what, false); if (!path_is_absolute(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) return log_oom(); - path_kill_slashes(arg_mount_where); + path_simplify(arg_mount_where, false); if (!path_is_absolute(arg_mount_where)) { log_error("Only absolute path is supported: %s", arg_mount_where); @@ -992,7 +992,7 @@ static int action_umount( if (!p) return log_oom(); - path_kill_slashes(p); + path_simplify(p, false); r = stop_mounts(bus, p); if (r < 0) diff --git a/src/portable/portable.c b/src/portable/portable.c index aaabe9fb36..eac0a4d616 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -630,14 +630,14 @@ static int portable_changes_add( if (!p) return -ENOMEM; - path_kill_slashes(p); + path_simplify(p, false); if (source) { s = strdup(source); if (!s) return -ENOMEM; - path_kill_slashes(s); + path_simplify(s, false); } c[(*n_changes)++] = (PortableChange) { diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index c74c83ba5b..f10366c265 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -740,7 +740,7 @@ int config_parse_path( if (!n) return log_oom(); - path_kill_slashes(n); + path_simplify(n, false); finalize: free(*s); diff --git a/src/shared/install.c b/src/shared/install.c index ecda662f28..46e07ebb98 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -309,9 +309,9 @@ int unit_file_changes_add( if (!p || (source && !s)) return -ENOMEM; - path_kill_slashes(p); + path_simplify(p, false); if (s) - path_kill_slashes(s); + path_simplify(s, false); c[*n_changes] = (UnitFileChange) { type, p, s }; p = s = NULL; @@ -516,7 +516,7 @@ static int mark_symlink_for_removal( if (!n) return -ENOMEM; - path_kill_slashes(n); + path_simplify(n, false); r = set_consume(*remove_symlinks_to, n); if (r == -EEXIST) @@ -598,7 +598,7 @@ static int remove_marked_symlinks_fd( p = path_make_absolute(de->d_name, path); if (!p) return -ENOMEM; - path_kill_slashes(p); + path_simplify(p, false); q = readlink_malloc(p, &dest); if (q == -ENOENT) diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index e67f1f0645..404dd2aace 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -170,7 +170,7 @@ static int image_new( if (!i->path) return -ENOMEM; - path_kill_slashes(i->path); + path_simplify(i->path, false); *ret = TAKE_PTR(i); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index c14cfd48af..7caa97e27b 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1599,8 +1599,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { if (resolved_id) { if (path_is_absolute(resolved_id)) { i->uid_path = TAKE_PTR(resolved_id); - - path_kill_slashes(i->uid_path); + path_simplify(i->uid_path, false); } else { _cleanup_free_ char *uid = NULL, *gid = NULL; 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 (path_is_absolute(resolved_id)) { i->gid_path = TAKE_PTR(resolved_id); - - path_kill_slashes(i->gid_path); + path_simplify(i->gid_path, false); } else { r = parse_gid(resolved_id, &i->gid); if (r < 0) diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index c65b0b06b4..d963d1ccbb 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -26,6 +26,16 @@ 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) { _cleanup_close_ int fd = -1; @@ -69,15 +79,28 @@ static void test_path(void) { assert_se(fd >= 0); assert_se(fd_is_mount_point(fd, "/", 0) > 0); - { - char p1[] = "aaa/bbb////ccc"; - char p2[] = "//aaa/.////ccc"; - char p3[] = "/./"; - - assert_se(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc")); - assert_se(path_equal(path_kill_slashes(p2), "/aaa/./ccc")); - assert_se(path_equal(path_kill_slashes(p3), "/./")); - } + test_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc", "aaa/bbb/ccc"); + test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc"); + test_path_simplify("///", "/", "/"); + test_path_simplify("///.//", "/.", "/"); + test_path_simplify("///.//.///", "/./.", "/"); + test_path_simplify("////.././///../.", "/.././../.", "/../.."); + test_path_simplify(".", ".", ""); + 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")); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index ae39d720a2..6bfa44f076 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -431,7 +431,7 @@ static void load_unix_sockets(void) { goto fail; } - path_kill_slashes(s); + path_simplify(s, false); r = set_consume(unix_sockets, s); if (r < 0 && r != -EEXIST) { @@ -2289,7 +2289,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool return -EBADMSG; } - path_kill_slashes(i.argument); + path_simplify(i.argument, false); break; case CREATE_CHAR_DEVICE: @@ -2362,7 +2362,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool return -EBADMSG; } - path_kill_slashes(i.path); + path_simplify(i.path, false); if (!should_include_path(i.path)) return 0;