]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
path-util: allow NULLs in arguments to path_join() 11002/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 30 Nov 2018 10:06:24 +0000 (11:06 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 30 Nov 2018 21:21:17 +0000 (22:21 +0100)
This removes the need to remember to put strempty() in places, thus reducing
the likelihood of a stupid mistake.

src/basic/conf-files.c
src/basic/path-util.c
src/basic/path-util.h
src/journal/journalctl.c
src/libsystemd/sd-hwdb/hwdb-util.c
src/shared/pretty-print.c
src/systemctl/systemctl.c
src/test/test-path-util.c

index 6a2a2055c7138faa9f32bdd01b9e73b0e6a97aef..675746a944c0b1fb3cf65fb858fbdfa3f0c5c92f 100644 (file)
@@ -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();
         }
index 4d2c9b5f383c4d200b3387a7cd0e83a3c506f70c..995f39f16ef0ee770db269a6e943334010f970a3 100644 (file)
@@ -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] != '/')
index b3786ac86c37cc77bf058cd0f6ab8ef073fe386f..78db41b855c2ff13b55e4305bd2b79378d5e28ed 100644 (file)
@@ -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);
 
index abf13415e92978e4438611bad2b52c547cd2ce53..1d3766d971168475b17ca5c3524b20f9b45a596d 100644 (file)
@@ -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;
index ca989da310ccb3ee7169e8d7a4a18afdfb38f2a2..87259daadc78b9a6a98929ee9b1e01d51ce3c33b 100644 (file)
@@ -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;
 
index 654afa6b94ef51392c838ed4665d547eba3fe567..108601864550576d6b9ccca6b6f6cf7ff5cc9697 100644 (file)
@@ -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();
 
index efbc3eef96db090df689d9e171b0a458bc2b90db..87ae4eb5d76a748a43101a91f6b91bddbdb83da1 100644 (file)
@@ -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();
 
index 236aeff13e77e2ab7a2cc6ec3fbd546b06efce7e..8854a94f6ccc730709ebc8e35fa2933de230750a 100644 (file)
@@ -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", "", "", "");