From: Zbigniew Jędrzejewski-Szmek Date: Fri, 30 Nov 2018 10:06:24 +0000 (+0100) Subject: path-util: allow NULLs in arguments to path_join() X-Git-Tag: v240~164^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=652ef29887c2d46e363c73524f9ea47a7e99aace;p=thirdparty%2Fsystemd.git path-util: allow NULLs in arguments to path_join() This removes the need to remember to put strempty() in places, thus reducing the likelihood of a stupid mistake. --- diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c index 6a2a2055c71..675746a944c 100644 --- a/src/basic/conf-files.c +++ b/src/basic/conf-files.c @@ -216,7 +216,7 @@ int conf_files_insert(char ***strv, const char *root, char **dirs, const char *p p2 = path_startswith(path, *dir); if (p2) { /* Our new entry has higher priority */ - t = path_join(strempty(root), path); + t = path_join(root, path); if (!t) return log_oom(); @@ -232,7 +232,7 @@ int conf_files_insert(char ***strv, const char *root, char **dirs, const char *p /* … we are not there yet, let's continue */ } - t = path_join(strempty(root), path); + t = path_join(root, path); if (!t) return log_oom(); @@ -318,7 +318,7 @@ int conf_files_list_with_replacement( if (r < 0) return log_error_errno(r, "Failed to extend config file list: %m"); - p = path_join(strempty(root), replacement); + p = path_join(root, replacement); if (!p) return log_oom(); } diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 4d2c9b5f383..995f39f16ef 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -488,11 +488,10 @@ char* path_join_internal(const char *first, ...) { bool slash; size_t sz; - assert(first); - - /* Joins all listed strings until NULL and places an "/" between them unless the strings end/begin already with - * one so that it is unnecessary. Note that "/" which are already duplicate won't be removed. The string - * returned is hence always equal or longer than the sum of the lengths of each individual string. + /* Joins all listed strings until the sentinel and places a "/" between them unless the strings end/begin + * already with one so that it is unnecessary. Note that slashes which are already duplicate won't be + * removed. The string returned is hence always equal to or longer than the sum of the lengths of each + * individual string. * * Note: any listed empty string is simply skipped. This can be useful for concatenating strings of which some * are optional. @@ -503,22 +502,18 @@ char* path_join_internal(const char *first, ...) { * path_join("foo/", "bar") → "foo/bar" * path_join("", "foo", "", "bar", "") → "foo/bar" */ - sz = strlen(first); + sz = strlen_ptr(first); va_start(ap, first); - while ((p = va_arg(ap, char*))) { - - if (*p == 0) /* Skip empty items */ - continue; - - sz += 1 + strlen(p); - } + while ((p = va_arg(ap, char*)) != (const char*) -1) + if (!isempty(p)) + sz += 1 + strlen(p); va_end(ap); joined = new(char, sz + 1); if (!joined) return NULL; - if (first[0] != 0) { + if (!isempty(first)) { q = stpcpy(joined, first); slash = endswith(first, "/"); } else { @@ -529,9 +524,8 @@ char* path_join_internal(const char *first, ...) { } va_start(ap, first); - while ((p = va_arg(ap, char*))) { - - if (*p == 0) /* Skip empty items */ + while ((p = va_arg(ap, char*)) != (const char*) -1) { + if (isempty(p)) continue; if (!slash && p[0] != '/') diff --git a/src/basic/path-util.h b/src/basic/path-util.h index b3786ac86c3..78db41b855c 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -49,8 +49,8 @@ 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_internal(const char *first, ...) _sentinel_; -#define path_join(x, ...) path_join_internal(x, __VA_ARGS__, NULL) +char* path_join_internal(const char *first, ...); +#define path_join(x, ...) path_join_internal(x, __VA_ARGS__, (const char*) -1) char* path_simplify(char *path, bool kill_dots); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index abf13415e92..1d3766d9711 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -2110,7 +2110,7 @@ int main(int argc, char *argv[]) { case ACTION_UPDATE_CATALOG: { _cleanup_free_ char *database; - database = path_join(strempty(arg_root), CATALOG_DATABASE); + database = path_join(arg_root, CATALOG_DATABASE); if (!database) { r = log_oom(); goto finish; diff --git a/src/libsystemd/sd-hwdb/hwdb-util.c b/src/libsystemd/sd-hwdb/hwdb-util.c index ca989da310c..87259daadc7 100644 --- a/src/libsystemd/sd-hwdb/hwdb-util.c +++ b/src/libsystemd/sd-hwdb/hwdb-util.c @@ -651,7 +651,7 @@ int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool co log_debug("strings dedup'ed: %8zu bytes (%8zu)", trie->strings->dedup_len, trie->strings->dedup_count); - hwdb_bin = path_join(strempty(root), hwdb_bin_dir ?: default_hwdb_bin_dir, "hwdb.bin"); + hwdb_bin = path_join(root, hwdb_bin_dir ?: default_hwdb_bin_dir, "hwdb.bin"); if (!hwdb_bin) return -ENOMEM; diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index 654afa6b94e..10860186455 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -217,7 +217,7 @@ int conf_files_cat(const char *root, const char *name) { if (r < 0) return log_error_errno(r, "Failed to query file list: %m"); - path = path_join(strempty(root), "/etc", name); + path = path_join(root, "/etc", name); if (!path) return log_oom(); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index efbc3eef96d..87ae4eb5d76 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -5975,7 +5975,7 @@ static int enable_sysv_units(const char *verb, char **args) { if (found_native && streq(verb, "is-enabled")) continue; - p = path_join(strempty(arg_root), SYSTEM_SYSVINIT_PATH, name); + p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name); if (!p) return log_oom(); diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index 236aeff13e7..8854a94f6cc 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -251,10 +251,19 @@ static void test_path_join(void) { test_join("/c", "", "/", "c"); test_join("/", "", "/", NULL); + test_join("/a/b/c", NULL, "/a/b", "/c"); + test_join("a/b/c", NULL, "a/b", "c"); + test_join("/a/b/c", NULL, "/a/b", "c"); + test_join("/c", NULL, "/", "c"); + test_join("/", NULL, "/", NULL); + test_join("", "", NULL); + test_join("", NULL, ""); + test_join("", NULL, NULL); test_join("foo/bar", "foo", "bar"); test_join("foo/bar", "", "foo", "bar"); + test_join("foo/bar", NULL, "foo", NULL, "bar"); test_join("foo/bar", "", "foo", "", "bar", ""); test_join("foo/bar", "", "", "", "", "foo", "", "", "", "bar", "", "", "");