]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: Get rid of prefix_roota() in favor of path_join()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 5 May 2025 10:05:15 +0000 (12:05 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 6 May 2025 15:40:33 +0000 (17:40 +0200)
We deprecated prefix_roota() in favor of chase() and path_join().
Let's finish the removal by replacing the few remaining call sites
with path_join().

14 files changed:
TODO
src/basic/path-util.h
src/bootctl/bootctl-install.c
src/network/generator/main.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn.c
src/shared/install.c
src/shared/tests.h
src/shared/vpick.c
src/sysusers/sysusers.c
src/test/test-cgroup.c
src/test/test-dev-setup.c
src/test/test-path-util.c
src/tmpfiles/tmpfiles.c

diff --git a/TODO b/TODO
index dfc3e97ba624bfd95ef35dc4a3955c7995cf6caf..d91dbcee286ff8ebc5f330987a212cdb474ebfa1 100644 (file)
--- a/TODO
+++ b/TODO
@@ -66,9 +66,6 @@ Janitorial Clean-ups:
 * rework mount.c and swap.c to follow proper state enumeration/deserialization
   semantics, like we do for device.c now
 
-* get rid of prefix_roota() and similar, only use chase() and related
-  calls instead.
-
 * get rid of basename() and replace by path_extract_filename()
 
 * Replace our fstype_is_network() with a call to libmount's mnt_fstype_is_netfs()?
index 436bd5d8927b3cca3dd8e11e5f634a9176ff3eb6..74406d7698afd162a4afb3a739668c286f142300 100644 (file)
@@ -154,32 +154,6 @@ int fsck_exists_for_fstype(const char *fstype);
              _slash && ((*_slash = 0), true);                           \
              _slash = strrchr((prefix), '/'))
 
-/* Similar to path_join(), but only works for two components, and only the first one may be NULL and returns
- * an alloca() buffer, or possibly a const pointer into the path parameter. */
-/* DEPRECATED: use path_join() instead */
-#define prefix_roota(root, path)                                        \
-        ({                                                              \
-                const char* _path = (path), *_root = (root), *_ret;     \
-                char *_p, *_n;                                          \
-                size_t _l;                                              \
-                while (_path[0] == '/' && _path[1] == '/')              \
-                        _path++;                                        \
-                if (isempty(_root))                                     \
-                        _ret = _path;                                   \
-                else {                                                  \
-                        _l = strlen(_root) + 1 + strlen(_path) + 1;     \
-                        _n = newa(char, _l);                            \
-                        _p = stpcpy(_n, _root);                         \
-                        while (_p > _n && _p[-1] == '/')                \
-                                _p--;                                   \
-                        if (_path[0] != '/')                            \
-                                *(_p++) = '/';                          \
-                        strcpy(_p, _path);                              \
-                        _ret = _n;                                      \
-                }                                                       \
-                _ret;                                                   \
-        })
-
 int path_find_first_component(const char **p, bool accept_dot_dot, const char **ret);
 int path_find_last_component(const char *path, bool accept_dot_dot, const char **next, const char **ret);
 const char* last_path_component(const char *path);
index 16ae5de99f6e5c9e2524396e812553fffc3578e5..20c3336009f2d5022fe24da0d67bf338db6b6272 100644 (file)
@@ -1118,9 +1118,10 @@ static int remove_boot_efi(const char *esp_path) {
 }
 
 static int rmdir_one(const char *prefix, const char *suffix) {
-        const char *p;
+        _cleanup_free_ char *p = path_join(prefix, suffix);
+        if (!p)
+                return log_oom();
 
-        p = prefix_roota(prefix, suffix);
         if (rmdir(p) < 0) {
                 bool ignore = IN_SET(errno, ENOENT, ENOTEMPTY);
 
@@ -1160,10 +1161,12 @@ static int remove_entry_directory(const char *root) {
 }
 
 static int remove_binaries(const char *esp_path) {
-        const char *p;
         int r, q;
 
-        p = prefix_roota(esp_path, "/EFI/systemd");
+        _cleanup_free_ char *p = path_join(esp_path, "/EFI/systemd");
+        if (!p)
+                return log_oom();
+
         r = rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
 
         q = remove_boot_efi(esp_path);
@@ -1174,12 +1177,13 @@ static int remove_binaries(const char *esp_path) {
 }
 
 static int remove_file(const char *root, const char *file) {
-        const char *p;
-
         assert(root);
         assert(file);
 
-        p = prefix_roota(root, file);
+        _cleanup_free_ char *p = path_join(root, file);
+        if (!p)
+                return log_oom();
+
         if (unlink(p) < 0) {
                 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
                                "Failed to unlink file \"%s\": %m", p);
index 0911656e889c01057f165f229ca85dbc7c9e1175..c15dfa16cd7333643457fa47c18e5da280ad14d5 100644 (file)
@@ -123,7 +123,9 @@ static int context_save(Context *context) {
         Link *link;
         int r;
 
-        const char *p = prefix_roota(arg_root, NETWORK_UNIT_DIRECTORY);
+        _cleanup_free_ char *p = path_join(arg_root, NETWORK_UNIT_DIRECTORY);
+        if (!p)
+                return log_oom();
 
         r = mkdir_p(p, 0755);
         if (r < 0)
index 075cf3d45ac618491ec225a880745067246e18bd..d1a9ced8ea4ffcbf9c6e10e7798c230408270a97 100644 (file)
@@ -1091,19 +1091,21 @@ static int setup_volatile_state(const char *directory) {
 
 static int setup_volatile_state_after_remount_idmap(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) {
         _cleanup_free_ char *buf = NULL;
-        const char *p, *options;
         int r;
 
         assert(directory);
 
         /* Then, after remount_idmap(), overmount /var/ with a tmpfs. */
 
-        p = prefix_roota(directory, "/var");
+        _cleanup_free_ char *p = path_join(directory, "/var");
+        if (!p)
+                return log_oom();
+
         r = mkdir(p, 0755);
         if (r < 0 && errno != EEXIST)
                 return log_error_errno(errno, "Failed to create %s: %m", directory);
 
-        options = "mode=0755" TMPFS_LIMITS_VOLATILE_STATE;
+        const char *options = "mode=0755" TMPFS_LIMITS_VOLATILE_STATE;
         r = tmpfs_patch_options(options, uid_shift == 0 ? UID_INVALID : uid_shift, selinux_apifs_context, &buf);
         if (r < 0)
                 return log_oom();
@@ -1116,8 +1118,7 @@ static int setup_volatile_state_after_remount_idmap(const char *directory, uid_t
 static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) {
         bool tmpfs_mounted = false, bind_mounted = false;
         _cleanup_(rmdir_and_freep) char *template = NULL;
-        _cleanup_free_ char *buf = NULL, *bindir = NULL;
-        const char *f, *t, *options;
+        _cleanup_free_ char *buf = NULL, *bindir = NULL, *f = NULL, *t = NULL;
         struct stat st;
         int r;
 
@@ -1148,7 +1149,7 @@ static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char
         if (r < 0)
                 return log_error_errno(r, "Failed to create temporary directory: %m");
 
-        options = "mode=0755" TMPFS_LIMITS_ROOTFS;
+        const char *options = "mode=0755" TMPFS_LIMITS_ROOTFS;
         r = tmpfs_patch_options(options, uid_shift == 0 ? UID_INVALID : uid_shift, selinux_apifs_context, &buf);
         if (r < 0)
                 goto fail;
@@ -1161,8 +1162,17 @@ static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char
 
         tmpfs_mounted = true;
 
-        f = prefix_roota(directory, "/usr");
-        t = prefix_roota(template, "/usr");
+        f = path_join(directory, "/usr");
+        if (!f) {
+                r = log_oom();
+                goto fail;
+        }
+
+        t = path_join(template, "/usr");
+        if (!t) {
+                r = log_oom();
+                goto fail;
+        }
 
         r = mkdir(t, 0755);
         if (r < 0 && errno != EEXIST) {
index bda38db1058462db210e64ce9699575ad04c8856..33397fd759786c4a4806c4978c3fc7c18dfa9d94 100644 (file)
@@ -2260,7 +2260,6 @@ static int make_extra_nodes(const char *dest) {
 
 static int setup_pts(const char *dest, uid_t chown_uid) {
         _cleanup_free_ char *options = NULL;
-        const char *p;
         int r;
 
 #if HAVE_SELINUX
@@ -2279,7 +2278,10 @@ static int setup_pts(const char *dest, uid_t chown_uid) {
                 return log_oom();
 
         /* Mount /dev/pts itself */
-        p = prefix_roota(dest, "/dev/pts");
+        _cleanup_free_ char *p = path_join(dest, "/dev/pts");
+        if (!p)
+                return log_oom();
+
         r = RET_NERRNO(mkdir(p, 0755));
         if (r < 0)
                 return log_error_errno(r, "Failed to create /dev/pts: %m");
@@ -2292,7 +2294,11 @@ static int setup_pts(const char *dest, uid_t chown_uid) {
                 return log_error_errno(r, "Failed to chown /dev/pts: %m");
 
         /* Create /dev/ptmx symlink */
-        p = prefix_roota(dest, "/dev/ptmx");
+        free(p);
+        p = path_join(dest, "/dev/ptmx");
+        if (!p)
+                return log_oom();
+
         if (symlink("pts/ptmx", p) < 0)
                 return log_error_errno(errno, "Failed to create /dev/ptmx symlink: %m");
         r = userns_lchown(p, 0, 0);
@@ -2300,7 +2306,11 @@ static int setup_pts(const char *dest, uid_t chown_uid) {
                 return log_error_errno(r, "Failed to chown /dev/ptmx: %m");
 
         /* And fix /dev/pts/ptmx ownership */
-        p = prefix_roota(dest, "/dev/pts/ptmx");
+        free(p);
+        p = path_join(dest, "/dev/pts/ptmx");
+        if (!p)
+                return log_oom();
+
         r = userns_lchown(p, 0, 0);
         if (r < 0)
                 return log_error_errno(r, "Failed to chown /dev/pts/ptmx: %m");
@@ -2384,7 +2394,6 @@ int make_run_host(const char *root) {
 
 static int setup_credentials(const char *root) {
         bool world_readable = false;
-        const char *q;
         int r;
 
         if (arg_credentials.n_credentials == 0)
@@ -2411,7 +2420,10 @@ static int setup_credentials(const char *root) {
         if (r < 0)
                 return log_error_errno(r, "Failed to create /run/host/credentials: %m");
 
-        q = prefix_roota(root, "/run/host/credentials");
+        _cleanup_free_ char *q = path_join(root, "/run/host/credentials");
+        if (!q)
+                return log_oom();
+
         r = mount_nofollow_verbose(LOG_ERR, NULL, q, "ramfs", MS_NOSUID|MS_NOEXEC|MS_NODEV, "mode=0700");
         if (r < 0)
                 return r;
@@ -2527,7 +2539,6 @@ static int setup_hostname(void) {
 
 static int setup_journal(const char *directory) {
         _cleanup_free_ char *d = NULL;
-        const char *p, *q;
         sd_id128_t this_id;
         bool try;
         int r;
@@ -2563,8 +2574,13 @@ static int setup_journal(const char *directory) {
                 }
         }
 
-        p = strjoina("/var/log/journal/", SD_ID128_TO_STRING(arg_uuid));
-        q = prefix_roota(directory, p);
+        _cleanup_free_ char *p = path_join("/var/log/journal/", SD_ID128_TO_STRING(arg_uuid));
+        if (!p)
+                return log_oom();
+
+        _cleanup_free_ char *q = path_join(directory, p);
+        if (!q)
+                return log_oom();
 
         if (path_is_mount_point(p) > 0) {
                 if (try)
@@ -2741,7 +2757,6 @@ static int reset_audit_loginuid(void) {
 }
 
 static int mount_tunnel_dig(const char *root) {
-        const char *p, *q;
         int r;
 
         if (arg_userns_mode == USER_NAMESPACE_MANAGED) {
@@ -2751,7 +2766,10 @@ static int mount_tunnel_dig(const char *root) {
 
         (void) mkdir_p("/run/systemd/nspawn/", 0755);
         (void) mkdir_p("/run/systemd/nspawn/propagate", 0600);
-        p = strjoina("/run/systemd/nspawn/propagate/", arg_machine);
+        _cleanup_free_ char *p = path_join("/run/systemd/nspawn/propagate/", arg_machine);
+        if (!p)
+                return log_oom();
+
         (void) mkdir_p(p, 0600);
 
         r = make_run_host(root);
@@ -2762,7 +2780,10 @@ static int mount_tunnel_dig(const char *root) {
         if (r < 0)
                 return log_error_errno(r, "Failed to create "NSPAWN_MOUNT_TUNNEL": %m");
 
-        q = prefix_roota(root, NSPAWN_MOUNT_TUNNEL);
+        _cleanup_free_ char *q = path_join(root, NSPAWN_MOUNT_TUNNEL);
+        if (!q)
+                return log_oom();
+
         r = mount_nofollow_verbose(LOG_ERR, p, q, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
@@ -3819,7 +3840,6 @@ static int outer_child(
         _cleanup_(bind_user_context_freep) BindUserContext *bind_user_context = NULL;
         _cleanup_strv_free_ char **os_release_pairs = NULL;
         bool idmap = false;
-        const char *p;
         pid_t pid;
         ssize_t l;
         int r;
@@ -4157,7 +4177,10 @@ static int outer_child(
 
         (void) dev_setup(directory, chown_uid, chown_uid);
 
-        p = prefix_roota(directory, "/run/host");
+        _cleanup_free_ char *p = path_join(directory, "/run/host");
+        if (!p)
+                return log_oom();
+
         (void) make_inaccessible_nodes(p, chown_uid, chown_uid);
 
         r = setup_unix_export_host_inside(directory, unix_export_path);
@@ -4212,11 +4235,19 @@ static int outer_child(
                 return r;
 
         /* The same stuff as the $container env var, but nicely readable for the entire payload */
-        p = prefix_roota(directory, "/run/host/container-manager");
+        free(p);
+        p = path_join(directory, "/run/host/container-manager");
+        if (!p)
+                return log_oom();
+
         (void) write_string_file(p, arg_container_service_name, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0444);
 
         /* The same stuff as the $container_uuid env var */
-        p = prefix_roota(directory, "/run/host/container-uuid");
+        free(p);
+        p = path_join(directory, "/run/host/container-uuid");
+        if (!p)
+                return log_oom();
+
         (void) write_string_filef(p, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0444, SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(arg_uuid));
 
         if (!arg_use_cgns) {
index 3b370c854de4d4fbb8863afc5db6047ce223e5c9..30f2de388e0c341fe105cb76d9e99fc2c55bdd5f 100644 (file)
@@ -1782,9 +1782,9 @@ static int install_info_add_auto(
         assert(name_or_path);
 
         if (path_is_absolute(name_or_path)) {
-                const char *pp;
-
-                pp = prefix_roota(lp->root_dir, name_or_path);
+                _cleanup_free_ char *pp = path_join(lp->root_dir, name_or_path);
+                if (!pp)
+                        return -ENOMEM;
 
                 return install_info_add(ctx, NULL, pp, lp->root_dir, /* auxiliary= */ false, ret);
         } else
index d19ffcea8c22bab19cfabd7f303389afb352f940..b19bad439569560a61244c5fbe126b41c38b7455 100644 (file)
@@ -458,11 +458,14 @@ static inline int run_test_table(void) {
 #else
 #define ASSERT_NOT_NULL(expr)                                                                                   \
         ({                                                                                                      \
-                if ((expr) == NULL) {                                                                           \
+                typeof(expr) _result = (expr);                                                                  \
+                if (_result == NULL) {                                                                          \
                         log_error("%s:%i: Assertion failed: expected \"%s\" to be not NULL",                    \
                                   PROJECT_FILE, __LINE__, #expr);                                               \
                         abort();                                                                                \
                 }                                                                                               \
+                                                                                                                \
+                _result;                                                                                        \
         })
 #endif
 
index 0319a6f5f8882585fb968ea95dc235ef4c3f97dc..2652633f372cc2568b2a78b26b92f6f4c346b5a5 100644 (file)
@@ -163,14 +163,15 @@ static int pin_choice(
 
         struct stat st;
         if (fstat(inode_fd, &st) < 0)
-                return log_debug_errno(errno, "Failed to stat discovered inode '%s': %m", prefix_roota(toplevel_path, inode_path));
+                return log_debug_errno(errno, "Failed to stat discovered inode '%s%s': %m",
+                                       empty_to_root(toplevel_path), skip_leading_slash(inode_path));
 
         if (filter->type_mask != 0 &&
             !BIT_SET(filter->type_mask, IFTODT(st.st_mode)))
                 return log_debug_errno(
                                 SYNTHETIC_ERRNO(errno_from_mode(filter->type_mask, st.st_mode)),
-                                "Inode '%s' has wrong type, found '%s'.",
-                                prefix_roota(toplevel_path, inode_path),
+                                "Inode '%s/%s' has wrong type, found '%s'.",
+                                empty_to_root(toplevel_path), skip_leading_slash(inode_path),
                                 inode_type_to_string(st.st_mode));
 
         _cleanup_(pick_result_done) PickResult result = {
@@ -297,7 +298,8 @@ static int make_choice(
                         return 0;
                 }
                 if (r < 0)
-                        return log_debug_errno(r, "Failed to open '%s': %m", prefix_roota(toplevel_path, p));
+                        return log_debug_errno(r, "Failed to open '%s/%s': %m",
+                                               empty_to_root(toplevel_path), skip_leading_slash(p));
 
                 return pin_choice(
                                 toplevel_path,
@@ -318,11 +320,13 @@ static int make_choice(
         /* Convert O_PATH to a regular directory fd */
         dir_fd = fd_reopen(inode_fd, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
         if (dir_fd < 0)
-                return log_debug_errno(dir_fd, "Failed to reopen '%s' as directory: %m", prefix_roota(toplevel_path, inode_path));
+                return log_debug_errno(dir_fd, "Failed to reopen '%s/%s' as directory: %m",
+                                       empty_to_root(toplevel_path), skip_leading_slash(inode_path));
 
         r = readdir_all(dir_fd, 0, &de);
         if (r < 0)
-                return log_debug_errno(r, "Failed to read directory '%s': %m", prefix_roota(toplevel_path, inode_path));
+                return log_debug_errno(r, "Failed to read directory '%s/%s': %m",
+                                       empty_to_root(toplevel_path), skip_leading_slash(inode_path));
 
         if (filter->architecture < 0) {
                 architectures = local_architectures;
@@ -466,7 +470,8 @@ static int make_choice(
 
         object_fd = openat(dir_fd, best_filename, O_CLOEXEC|O_PATH);
         if (object_fd < 0)
-                return log_debug_errno(errno, "Failed to open '%s': %m", prefix_roota(toplevel_path, p));
+                return log_debug_errno(errno, "Failed to open '%s/%s': %m",
+                                       empty_to_root(toplevel_path), skip_leading_slash(inode_path));
 
         return pin_choice(
                         toplevel_path,
index bef806015e30908a15afc9ca6b5c5dab37670504..3d36b4ff64a358fcbad0def45dc0e1fa7704e7f1 100644 (file)
@@ -944,11 +944,21 @@ static int write_files(Context *c) {
         _cleanup_(unlink_and_freep) char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL;
         int r;
 
-        const char
-                *passwd_path = prefix_roota(arg_root, "/etc/passwd"),
-                *shadow_path = prefix_roota(arg_root, "/etc/shadow"),
-                *group_path = prefix_roota(arg_root, "/etc/group"),
-                *gshadow_path = prefix_roota(arg_root, "/etc/gshadow");
+        _cleanup_free_ char *passwd_path = path_join(arg_root, "/etc/passwd");
+        if (!passwd_path)
+                return log_oom();
+
+        _cleanup_free_ char *shadow_path = path_join(arg_root, "/etc/shadow");
+        if (!shadow_path)
+                return log_oom();
+
+        _cleanup_free_ char *group_path = path_join(arg_root, "/etc/group");
+        if (!group_path)
+                return log_oom();
+
+        _cleanup_free_ char *gshadow_path = path_join(arg_root, "/etc/gshadow");
+        if (!gshadow_path)
+                return log_oom();
 
         assert(c);
 
index a15b880049c30c99ff2058ff8f90964608d10b22..363a7beeafd1ce4448bf532a94b5652724c21fff 100644 (file)
@@ -54,10 +54,10 @@ TEST(cg_create) {
         _cleanup_free_ char *here = NULL;
         ASSERT_OK(cg_pid_get_path_shifted(0, NULL, &here));
 
-        const char *test_a = prefix_roota(here, "/test-a"),
-                   *test_b = prefix_roota(here, "/test-b"),
-                   *test_c = prefix_roota(here, "/test-b/test-c"),
-                   *test_d = prefix_roota(here, "/test-b/test-d");
+        _cleanup_free_ char *test_a = ASSERT_NOT_NULL(path_join(here, "/test-a")),
+                            *test_b = ASSERT_NOT_NULL(path_join(here, "/test-b")),
+                            *test_c = ASSERT_NOT_NULL(path_join(here, "/test-b/test-c")),
+                            *test_d = ASSERT_NOT_NULL(path_join(here, "/test-b/test-d"));
         char *path;
 
         log_info("Paths for test:\n%s\n%s", test_a, test_b);
index dd6b30079a991f9c8bf0db474632385e8d42ce3d..b748809eb1533e96e0f2051f5be4f2981faa9120 100644 (file)
@@ -11,7 +11,7 @@
 
 int main(int argc, char *argv[]) {
         _cleanup_(rm_rf_physical_and_freep) char *p = NULL;
-        const char *f;
+        _cleanup_free_ char *f = NULL;
         struct stat st;
 
         test_setup_logging(LOG_DEBUG);
@@ -21,33 +21,38 @@ int main(int argc, char *argv[]) {
 
         ASSERT_OK(mkdtemp_malloc("/tmp/test-dev-setupXXXXXX", &p));
 
-        f = prefix_roota(p, "/run/systemd");
+        f = ASSERT_NOT_NULL(path_join(p, "/run/systemd"));
         ASSERT_OK(mkdir_p(f, 0755));
 
         ASSERT_OK(make_inaccessible_nodes(f, 1, 1));
         ASSERT_OK(make_inaccessible_nodes(f, 1, 1)); /* 2nd call should be a clean NOP */
 
-        f = prefix_roota(p, "/run/systemd/inaccessible/reg");
+        free(f);
+        f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/reg"));
         ASSERT_OK_ERRNO(stat(f, &st));
         ASSERT_TRUE(S_ISREG(st.st_mode));
         ASSERT_EQ(st.st_mode & 07777, 0000U);
 
-        f = prefix_roota(p, "/run/systemd/inaccessible/dir");
+        free(f);
+        f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/dir"));
         ASSERT_OK_ERRNO(stat(f, &st));
         ASSERT_TRUE(S_ISDIR(st.st_mode));
         ASSERT_EQ(st.st_mode & 07777, 0000U);
 
-        f = prefix_roota(p, "/run/systemd/inaccessible/fifo");
+        free(f);
+        f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/fifo"));
         ASSERT_OK_ERRNO(stat(f, &st));
         ASSERT_TRUE(S_ISFIFO(st.st_mode));
         ASSERT_EQ(st.st_mode & 07777, 0000U);
 
-        f = prefix_roota(p, "/run/systemd/inaccessible/sock");
+        free(f);
+        f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/sock"));
         ASSERT_OK_ERRNO(stat(f, &st));
         ASSERT_TRUE(S_ISSOCK(st.st_mode));
         ASSERT_EQ(st.st_mode & 07777, 0000U);
 
-        f = prefix_roota(p, "/run/systemd/inaccessible/chr");
+        free(f);
+        f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/chr"));
         if (stat(f, &st) < 0)
                 ASSERT_EQ(errno, ENOENT);
         else {
@@ -55,7 +60,8 @@ int main(int argc, char *argv[]) {
                 ASSERT_EQ(st.st_mode & 07777, 0000U);
         }
 
-        f = prefix_roota(p, "/run/systemd/inaccessible/blk");
+        free(f);
+        f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/blk"));
         if (stat(f, &st) < 0)
                 ASSERT_EQ(errno, ENOENT);
         else {
index e02bd8c857553b4340b698060f6f1b605cd4f49a..e11599e1859efa061acd62855c4df70f71f0ef76 100644 (file)
@@ -758,12 +758,11 @@ TEST(path_startswith) {
 
 static void test_prefix_root_one(const char *r, const char *p, const char *expected) {
         _cleanup_free_ char *s = NULL;
-        const char *t;
 
         assert_se(s = path_join(r, p));
         assert_se(path_equal(s, expected));
 
-        t = prefix_roota(r, p);
+        _cleanup_free_ char *t = path_join(r, p);
         assert_se(t);
         assert_se(path_equal(t, expected));
 }
index 8ac320469a2e5485a47bfc7d20e614a04ef80b2a..9d0d568a4b2f4a3bee90be8da0ef8e60cf7882cc 100644 (file)
@@ -2416,11 +2416,13 @@ static int create_symlink(Context *c, Item *i) {
                 r = chase(i->argument, arg_root, CHASE_SAFE|CHASE_PREFIX_ROOT|CHASE_NOFOLLOW, /* ret_path = */ NULL, /* ret_fd = */ NULL);
                 if (r == -ENOENT) {
                         /* Silently skip over lines where the source file is missing. */
-                        log_info("Symlink source path '%s' does not exist, skipping line.", prefix_roota(arg_root, i->argument));
+                        log_info("Symlink source path '%s/%s' does not exist, skipping line.",
+                                 empty_to_root(arg_root), skip_leading_slash(i->argument));
                         return 0;
                 }
                 if (r < 0)
-                        return log_error_errno(r, "Failed to check if symlink source path '%s' exists: %m", prefix_roota(arg_root, i->argument));
+                        return log_error_errno(r, "Failed to check if symlink source path '%s/%s' exists: %m",
+                                               empty_to_root(arg_root), skip_leading_slash(i->argument));
         }
 
         r = path_extract_filename(i->path, &bn);