diff --git a/src/lxc/criu.c b/src/lxc/criu.c index b1ab5d46e..245b06984 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c @@ -263,7 +263,7 @@ static void exec_criu(struct criu_opts *opts) for (i = 0; i < cgroup_num_hierarchies(); i++) { char **controllers = NULL, *fullname; - char *path; + char *path, *tmp; if (!cgroup_get_hierarchies(i, &controllers)) { ERROR("failed to get hierarchy %d", i); @@ -296,11 +296,15 @@ static void exec_criu(struct criu_opts *opts) } } - if (!lxc_deslashify(&path)) { - ERROR("failed to deslashify %s", path); + tmp = lxc_deslashify(path); + if (!tmp) { + ERROR("Failed to remove extraneous slashes from \"%s\"", + path); free(path); goto err; } + free(path); + path = tmp; fullname = lxc_string_join(",", (const char **) controllers, false); if (!fullname) { diff --git a/src/lxc/utils.c b/src/lxc/utils.c index d3b0fdc5d..d36107020 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -729,47 +729,46 @@ char **lxc_normalize_path(const char *path) return components; } -bool lxc_deslashify(char **path) +char *lxc_deslashify(const char *path) { - bool ret = false; - char *p; + char *dup, *p; char **parts = NULL; size_t n, len; - parts = lxc_normalize_path(*path); - if (!parts) - return false; + dup = strdup(path); + if (!dup) + return NULL; + + parts = lxc_normalize_path(dup); + if (!parts) { + free(dup); + return NULL; + } /* We'll end up here if path == "///" or path == "". */ if (!*parts) { - len = strlen(*path); + len = strlen(dup); if (!len) { - ret = true; - goto out; + lxc_free_array((void **)parts, free); + return dup; } - n = strcspn(*path, "/"); + n = strcspn(dup, "/"); if (n == len) { + free(dup); + lxc_free_array((void **)parts, free); + p = strdup("/"); if (!p) - goto out; - free(*path); - *path = p; - ret = true; - goto out; + return NULL; + + return p; } } - p = lxc_string_join("/", (const char **)parts, **path == '/'); - if (!p) - goto out; - - free(*path); - *path = p; - ret = true; - -out: + p = lxc_string_join("/", (const char **)parts, *dup == '/'); + free(dup); lxc_free_array((void **)parts, free); - return ret; + return p; } char *lxc_append_paths(const char *first, const char *second) diff --git a/src/lxc/utils.h b/src/lxc/utils.h index fc0e5c01c..4408c6d69 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -275,7 +275,7 @@ extern char *lxc_string_join(const char *sep, const char **parts, bool use_as_pr */ extern char **lxc_normalize_path(const char *path); /* remove multiple slashes from the path, e.g. ///foo//bar -> /foo/bar */ -extern bool lxc_deslashify(char **path); +extern char *lxc_deslashify(const char *path); extern char *lxc_append_paths(const char *first, const char *second); /* Note: the following two functions use strtok(), so they will never * consider an empty element, even if two delimiters are next to diff --git a/src/tests/lxc-test-utils.c b/src/tests/lxc-test-utils.c index 01d8cd6eb..aba7706ab 100644 --- a/src/tests/lxc-test-utils.c +++ b/src/tests/lxc-test-utils.c @@ -41,33 +41,37 @@ void test_lxc_deslashify(void) { - char *s = strdup("/A///B//C/D/E/"); - if (!s) - exit(EXIT_FAILURE); - lxc_test_assert_abort(lxc_deslashify(&s)); - lxc_test_assert_abort(strcmp(s, "/A/B/C/D/E") == 0); - free(s); + char *s = "/A///B//C/D/E/"; + char *t; - s = strdup("/A"); - if (!s) + t = lxc_deslashify(s); + if (!t) exit(EXIT_FAILURE); - lxc_test_assert_abort(lxc_deslashify(&s)); - lxc_test_assert_abort(strcmp(s, "/A") == 0); - free(s); + lxc_test_assert_abort(strcmp(t, "/A/B/C/D/E") == 0); + free(t); - s = strdup(""); - if (!s) - exit(EXIT_FAILURE); - lxc_test_assert_abort(lxc_deslashify(&s)); - lxc_test_assert_abort(strcmp(s, "") == 0); - free(s); + s = "/A"; - s = strdup("//"); - if (!s) + t = lxc_deslashify(s); + if (!t) exit(EXIT_FAILURE); - lxc_test_assert_abort(lxc_deslashify(&s)); - lxc_test_assert_abort(strcmp(s, "/") == 0); - free(s); + lxc_test_assert_abort(strcmp(t, "/A") == 0); + free(t); + + s = ""; + t = lxc_deslashify(s); + if (!t) + exit(EXIT_FAILURE); + lxc_test_assert_abort(strcmp(t, "") == 0); + free(t); + + s = "//"; + + t = lxc_deslashify(s); + if (!t) + exit(EXIT_FAILURE); + lxc_test_assert_abort(strcmp(t, "/") == 0); + free(t); } /* /proc/int_as_str/ns/mnt\0 = (5 + 21 + 7 + 1) */