int set_config_path_item(char **conf_item, const char *value)
{
- __do_free char *normalized = NULL;
+ __do_free char *valdup = NULL;
- normalized = lxc_deslashify(value);
- if (!normalized)
- return syserror_set(-ENOMEM, "Failed to normalize path config item");
+ valdup = path_simplify(value);
+ if (!valdup)
+ return -ENOMEM;
- return set_config_string_item_max(conf_item, normalized, PATH_MAX);
+ return set_config_string_item_max(conf_item, valdup, PATH_MAX);
}
int set_config_bool_item(bool *conf_item, const char *value, bool empty_conf_action)
return log_error_errno(-ENOMEM, ENOMEM, "Failed to duplicate limit cgroup path");
}
- tmp = lxc_deslashify(cgroup_base_path);
+ tmp = path_simplify(cgroup_base_path);
if (!tmp)
return log_error_errno(-ENOMEM, ENOMEM, "Failed to remove extraneous slashes from \"%s\"", tmp);
free_move_ptr(cgroup_base_path, tmp);
* don't need to record a dependency. If we would restore would
* also fail.
*/
- clean_old_path = lxc_deslashify(oldpath);
+ clean_old_path = path_simplify(oldpath);
if (!clean_old_path)
return log_error_errno(-ENOMEM, ENOMEM, "Failed to create clean path for \"%s\"", oldpath);
- clean_new_path = lxc_deslashify(lxcpath);
+ clean_new_path = path_simplify(lxcpath);
if (!clean_new_path)
return log_error_errno(-ENOMEM, ENOMEM, "Failed to create clean path for \"%s\"", lxcpath);
char **lxc_normalize_path(const char *path)
{
char **components;
- char **p;
size_t components_len = 0;
size_t pos = 0;
if (!components)
return NULL;
- for (p = components; *p; p++)
- components_len++;
-
/* resolve '.' and '..' */
for (pos = 0; pos < components_len;) {
if (strequal(components[pos], ".") ||
return components;
}
-char *lxc_deslashify(const char *path)
+/* taken from systemd */
+char *path_simplify(const char *path)
{
- char *dup, *p;
- char **parts = NULL;
- size_t n, len;
+ __do_free char *path_new = NULL;
+ char *f, *t;
+ bool slash = false, ignore_slash = false, absolute;
- dup = strdup(path);
- if (!dup)
+ path_new = strdup(path);
+ if (!path_new)
return NULL;
- parts = lxc_normalize_path(dup);
- if (!parts) {
- free(dup);
- return NULL;
+ if (is_empty_string(path_new))
+ return move_ptr(path_new);
+
+ absolute = abspath(path_new);
+
+ f = path_new;
+ if (*f == '.' && IN_SET(f[1], 0, '/')) {
+ ignore_slash = true;
+ f++;
}
- /* We'll end up here if path == "///" or path == "". */
- if (!*parts) {
- len = strlen(dup);
- if (!len) {
- lxc_free_array((void **)parts, free);
- return dup;
- }
+ for (t = path_new; *f; f++) {
- n = strcspn(dup, "/");
- if (n == len) {
- free(dup);
- lxc_free_array((void **)parts, free);
+ if (*f == '/') {
+ slash = true;
+ continue;
+ }
- p = strdup("/");
- if (!p)
- return NULL;
+ if (slash) {
+ if (*f == '.' && IN_SET(f[1], 0, '/'))
+ continue;
- return p;
+ slash = false;
+ if (ignore_slash)
+ ignore_slash = false;
+ else
+ *(t++) = '/';
}
+
+ *(t++) = *f;
+ }
+
+ if (t == path_new) {
+ if (absolute)
+ *(t++) = '/';
+ else
+ *(t++) = '.';
}
- p = lxc_string_join("/", (const char **)parts, *dup == '/');
- free(dup);
- lxc_free_array((void **)parts, free);
- return p;
+ *t = 0;
+ return move_ptr(path_new);
}
char *lxc_append_paths(const char *first, const char *second)
(__iterator = __it); \
__iterator = __it = strtok_r(NULL, __separators, &__p))
+__hidden extern char *path_simplify(const char *path);
+
#endif /* __LXC_STRING_UTILS_H */
#include "macro.h"
#include "utils.h"
-void test_lxc_deslashify(void)
+void test_path_simplify(void)
{
char *s = "/A///B//C/D/E/";
char *t;
- t = lxc_deslashify(s);
+ t = path_simplify(s);
if (!t)
exit(EXIT_FAILURE);
s = "/A";
- t = lxc_deslashify(s);
+ t = path_simplify(s);
if (!t)
exit(EXIT_FAILURE);
free(t);
s = "";
- t = lxc_deslashify(s);
+ t = path_simplify(s);
if (!t)
exit(EXIT_FAILURE);
s = "//";
- t = lxc_deslashify(s);
+ t = path_simplify(s);
if (!t)
exit(EXIT_FAILURE);
{
test_lxc_string_replace();
test_lxc_string_in_array();
- test_lxc_deslashify();
+ test_path_simplify();
test_detect_ramfs_rootfs();
test_lxc_safe_uint();
test_lxc_safe_int();