From 45519d13a4f2a3c3585e672595762ca621abe65e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Aug 2022 12:34:34 +0200 Subject: tree-wide: port things dirname_malloc() → path_extract_directory() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/analyze/analyze-verify-util.c | 27 ++++++++++------ src/basic/mkdir.c | 41 ++++++++++++------------ src/boot/bless-boot.c | 14 +++------ src/core/automount.c | 7 +++-- src/core/execute.c | 6 ++-- src/core/mount.c | 6 ++-- src/core/unit.c | 6 ++-- src/dissect/dissect.c | 6 ++-- src/home/homed-home.c | 6 ++-- src/home/homework-luks.c | 14 ++++++--- src/import/export-raw.c | 6 ---- src/libsystemd/sd-bus/bus-kernel.c | 6 ---- src/libsystemd/sd-bus/test-bus-watch-bind.c | 3 +- src/libsystemd/sd-journal/sd-journal.c | 6 ++-- src/machine/machine-dbus.c | 24 ++++++--------- src/shared/find-esp.c | 6 ++-- src/shared/install.c | 48 ++++++++++++++++------------- src/systemctl/systemctl-edit.c | 6 ++-- src/systemctl/systemctl-show.c | 8 ++--- src/test/test-bpf-devices.c | 2 +- 20 files changed, 123 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/src/analyze/analyze-verify-util.c b/src/analyze/analyze-verify-util.c index 531144ba57..c309c07516 100644 --- a/src/analyze/analyze-verify-util.c +++ b/src/analyze/analyze-verify-util.c @@ -61,9 +61,9 @@ int verify_prepare_filename(const char *filename, char **ret) { return r; } - dir = dirname_malloc(abspath); - if (!dir) - return -ENOMEM; + r = path_extract_directory(abspath, &dir); + if (r < 0) + return r; c = path_join(dir, with_instance ?: name); if (!c) @@ -73,24 +73,30 @@ int verify_prepare_filename(const char *filename, char **ret) { return 0; } -int verify_generate_path(char **var, char **filenames) { +int verify_generate_path(char **ret, char **filenames) { _cleanup_strv_free_ char **ans = NULL; + _cleanup_free_ char *joined = NULL; const char *old; int r; STRV_FOREACH(filename, filenames) { + _cleanup_free_ char *a = NULL; char *t; - t = dirname_malloc(*filename); - if (!t) - return -ENOMEM; + r = path_make_absolute_cwd(*filename, &a); + if (r < 0) + return r; + + r = path_extract_directory(a, &t); + if (r < 0) + return r; r = strv_consume(&ans, t); if (r < 0) return r; } - assert_se(strv_uniq(ans)); + strv_uniq(ans); /* First, prepend our directories. Second, if some path was specified, use that, and * otherwise use the defaults. Any duplicates will be filtered out in path-lookup.c. @@ -106,10 +112,11 @@ int verify_generate_path(char **var, char **filenames) { return r; } - *var = strv_join(ans, ":"); - if (!*var) + joined = strv_join(ans, ":"); + if (!joined) return -ENOMEM; + *ret = TAKE_PTR(joined); return 0; } diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index d2c6b96a38..8e4849b792 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -191,34 +191,37 @@ int mkdir_p_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, g } int mkdir_p_root(const char *root, const char *p, uid_t uid, gid_t gid, mode_t m) { - _cleanup_free_ char *pp = NULL; + _cleanup_free_ char *pp = NULL, *bn = NULL; _cleanup_close_ int dfd = -1; - const char *bn; int r; - pp = dirname_malloc(p); - if (!pp) - return -ENOMEM; - - /* Not top-level? */ - if (!(path_equal(pp, "/") || isempty(pp) || path_equal(pp, "."))) { - - /* Recurse up */ + r = path_extract_directory(p, &pp); + if (r == -EDESTADDRREQ) { + /* only fname is passed, no prefix to operate on */ + dfd = open(".", O_RDONLY|O_CLOEXEC|O_DIRECTORY); + if (dfd < 0) + return -errno; + } else if (r == -EADDRNOTAVAIL) + /* only root dir or "." was passed, i.e. there is no parent to extract, in that case there's nothing to do. */ + return 0; + else if (r < 0) + return r; + else { + /* Extracting the parent dir worked, hence we aren't top-level? Recurse up first. */ r = mkdir_p_root(root, pp, uid, gid, m); if (r < 0) return r; + + dfd = chase_symlinks_and_open(pp, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_DIRECTORY, NULL); + if (dfd < 0) + return dfd; } - bn = basename(p); - if (path_equal(bn, "/") || isempty(bn) || path_equal(bn, ".")) + r = path_extract_filename(p, &bn); + if (r == -EADDRNOTAVAIL) /* Already top-level */ return 0; - - if (!filename_is_valid(bn)) - return -EINVAL; - - dfd = chase_symlinks_and_open(pp, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_DIRECTORY, NULL); - if (dfd < 0) - return dfd; + if (r < 0) + return r; if (mkdirat(dfd, bn, m) < 0) { if (errno == EEXIST) diff --git a/src/boot/bless-boot.c b/src/boot/bless-boot.c index 315a1a37ed..a0f347bddf 100644 --- a/src/boot/bless-boot.c +++ b/src/boot/bless-boot.c @@ -399,7 +399,7 @@ static int verb_status(int argc, char *argv[], void *userdata) { } static int verb_set(int argc, char *argv[], void *userdata) { - _cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL, *parent = NULL; + _cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL; const char *target, *source1, *source2; uint64_t done; int r; @@ -463,22 +463,18 @@ static int verb_set(int argc, char *argv[], void *userdata) { /* We found none of the snippets here, try the next directory */ continue; - } else if (r < 0) + } + if (r < 0) return log_error_errno(r, "Failed to rename '%s' to '%s': %m", source2, target); - else - log_debug("Successfully renamed '%s' to '%s'.", source2, target); + log_debug("Successfully renamed '%s' to '%s'.", source2, target); } else if (r < 0) return log_error_errno(r, "Failed to rename '%s' to '%s': %m", source1, target); else log_debug("Successfully renamed '%s' to '%s'.", source1, target); /* First, fsync() the directory these files are located in */ - parent = dirname_malloc(target); - if (!parent) - return log_oom(); - - r = fsync_path_at(fd, skip_slash(parent)); + r = fsync_parent_at(fd, skip_slash(target)); if (r < 0) log_debug_errno(errno, "Failed to synchronize image directory, ignoring: %m"); diff --git a/src/core/automount.c b/src/core/automount.c index 5adec9e966..39c716fb81 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -134,12 +134,13 @@ static int automount_add_trigger_dependencies(Automount *a) { static int automount_add_mount_dependencies(Automount *a) { _cleanup_free_ char *parent = NULL; + int r; assert(a); - parent = dirname_malloc(a->where); - if (!parent) - return -ENOMEM; + r = path_extract_directory(a->where, &parent); + if (r < 0) + return r; return unit_require_mounts_for(UNIT(a), parent, UNIT_DEPENDENCY_IMPLICIT); } diff --git a/src/core/execute.c b/src/core/execute.c index e68d231739..0ce18159bd 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3104,9 +3104,9 @@ static int setup_credentials_internal( /* If we do not have our own mount put used the plain directory fallback, then we need to * open access to the top-level credential directory and the per-service directory now */ - parent = dirname_malloc(final); - if (!parent) - return -ENOMEM; + r = path_extract_directory(final, &parent); + if (r < 0) + return r; if (chmod(parent, 0755) < 0) return -errno; } diff --git a/src/core/mount.c b/src/core/mount.c index 9dd9fe1293..52acd4345b 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -303,9 +303,9 @@ static int mount_add_mount_dependencies(Mount *m) { /* Adds in links to other mount points that might lie further up in the hierarchy */ - parent = dirname_malloc(m->where); - if (!parent) - return -ENOMEM; + r = path_extract_directory(m->where, &parent); + if (r < 0) + return r; r = unit_require_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT); if (r < 0) diff --git a/src/core/unit.c b/src/core/unit.c index 0798c29c9d..6242f045b4 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -594,12 +594,10 @@ static void unit_remove_transient(Unit *u) { STRV_FOREACH(i, u->dropin_paths) { _cleanup_free_ char *p = NULL, *pp = NULL; - p = dirname_malloc(*i); /* Get the drop-in directory from the drop-in file */ - if (!p) + if (path_extract_directory(*i, &p) < 0) /* Get the drop-in directory from the drop-in file */ continue; - pp = dirname_malloc(p); /* Get the config directory from the drop-in directory */ - if (!pp) + if (path_extract_directory(p, &pp) < 0) /* Get the config directory from the drop-in directory */ continue; /* Only drop transient drop-ins */ diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index d9f3fab835..4ae24e7153 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -791,9 +791,9 @@ static int action_copy(DissectedImage *m, LoopDevice *d) { assert(arg_action == ACTION_COPY_TO); - dn = dirname_malloc(arg_target); - if (!dn) - return log_oom(); + r = path_extract_directory(arg_target, &dn); + if (r < 0) + return log_error_errno(r, "Failed to extract directory name from target path '%s': %m", arg_target); r = chase_symlinks(dn, mounted_dir, CHASE_PREFIX_ROOT|CHASE_WARN, NULL, &dfd); if (r < 0) diff --git a/src/home/homed-home.c b/src/home/homed-home.c index 1d8ededcae..8a389f7216 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -2176,9 +2176,9 @@ static int home_get_disk_status_luks( disk_size = st.st_size; stat_used = st.st_blocks * 512; - parent = dirname_malloc(ip); - if (!parent) - return log_oom(); + r = path_extract_directory(ip, &parent); + if (r < 0) + return log_error_errno(r, "Failed to extract parent directory from image path '%s': %m", ip); if (statfs(parent, &sfs) < 0) log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", parent); diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 5f3e79a67a..c83292df7d 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -1989,10 +1989,11 @@ static int wait_for_devlink(const char *path) { return log_error_errno(errno, "Failed to allocate inotify fd: %m"); } - dn = dirname_malloc(path); + r = path_extract_directory(path, &dn); + if (r < 0) + return log_error_errno(r, "Failed to extract directory from device node path '%s': %m", path); for (;;) { - if (!dn) - return log_oom(); + _cleanup_free_ char *ndn = NULL; log_info("Watching %s", dn); @@ -2002,10 +2003,13 @@ static int wait_for_devlink(const char *path) { } else break; - if (empty_or_root(dn)) + r = path_extract_directory(dn, &ndn); + if (r == -EADDRNOTAVAIL) /* Arrived at the top? */ break; + if (r < 0) + return log_error_errno(r, "Failed to extract directory from device node path '%s': %m", dn); - dn = dirname_malloc(dn); + free_and_replace(dn, ndn); } w = now(CLOCK_MONOTONIC); diff --git a/src/import/export-raw.c b/src/import/export-raw.c index 6617a9c9b6..a3ff6a3934 100644 --- a/src/import/export-raw.c +++ b/src/import/export-raw.c @@ -2,12 +2,6 @@ #include -/* When we include libgen.h because we need dirname() we immediately - * undefine basename() since libgen.h defines it as a macro to the POSIX - * version which is really broken. We prefer GNU basename(). */ -#include -#undef basename - #include "sd-daemon.h" #include "alloc-util.h" diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index cba1ab2953..b553f15396 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -9,12 +9,6 @@ #include #include -/* When we include libgen.h because we need dirname() we immediately - * undefine basename() since libgen.h defines it as a macro to the POSIX - * version which is really broken. We prefer GNU basename(). */ -#include -#undef basename - #include "alloc-util.h" #include "bus-internal.h" #include "bus-kernel.h" diff --git a/src/libsystemd/sd-bus/test-bus-watch-bind.c b/src/libsystemd/sd-bus/test-bus-watch-bind.c index fdc8772f84..6e522ae54b 100644 --- a/src/libsystemd/sd-bus/test-bus-watch-bind.c +++ b/src/libsystemd/sd-bus/test-bus-watch-bind.c @@ -53,8 +53,7 @@ static void* thread_server(void *p) { assert_se(mkdir_parents(path, 0755) >= 0); (void) usleep(100 * USEC_PER_MSEC); - d = dirname_malloc(path); - assert_se(d); + assert_se(path_extract_directory(path, &d) >= 0); assert_se(asprintf(&suffixed, "%s.%" PRIx64, d, random_u64()) >= 0); assert_se(rename(d, suffixed) >= 0); (void) usleep(100 * USEC_PER_MSEC); diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c index 2a46f11d8a..77d03ec95f 100644 --- a/src/libsystemd/sd-journal/sd-journal.c +++ b/src/libsystemd/sd-journal/sd-journal.c @@ -1858,9 +1858,9 @@ static int add_current_paths(sd_journal *j) { _cleanup_free_ char *dir = NULL; int r; - dir = dirname_malloc(f->path); - if (!dir) - return -ENOMEM; + r = path_extract_directory(f->path, &dir); + if (r < 0) + return r; r = add_directory(j, dir, NULL); if (r < 0) diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index bd203b37dd..87d04c3d58 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -4,12 +4,6 @@ #include #include -/* When we include libgen.h because we need dirname() we immediately - * undefine basename() since libgen.h defines it as a macro to the POSIX - * version which is really broken. We prefer GNU basename(). */ -#include -#undef basename - #include "alloc-util.h" #include "bus-common-errors.h" #include "bus-get-properties.h" @@ -902,7 +896,8 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu } int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) { - const char *src, *dest, *host_path, *container_path, *host_basename, *container_basename, *container_dirname; + _cleanup_free_ char *host_basename = NULL, *container_basename = NULL; + const char *src, *dest, *host_path, *container_path; _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 }; CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS; _cleanup_close_ int hostfd = -1; @@ -910,7 +905,6 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro bool copy_from; pid_t child; uid_t uid_shift; - char *t; int r; assert(message); @@ -984,11 +978,13 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro container_path = dest; } - host_basename = basename(host_path); + r = path_extract_filename(host_path, &host_basename); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to extract file name of '%s' path: %m", host_path); - container_basename = basename(container_path); - t = strdupa_safe(container_path); - container_dirname = dirname(t); + r = path_extract_filename(container_path, &container_basename); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to extract file name of '%s' path: %m", container_path); hostfd = open_parent(host_path, O_CLOEXEC, 0); if (hostfd < 0) @@ -1019,9 +1015,9 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro goto child_fail; } - containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY); + containerfd = open_parent(container_path, O_CLOEXEC, 0); if (containerfd < 0) { - r = log_error_errno(errno, "Failed to open destination directory: %m"); + r = log_error_errno(containerfd, "Failed to open destination directory: %m"); goto child_fail; } diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c index 14c1ce0b45..8a20fa7e47 100644 --- a/src/shared/find-esp.c +++ b/src/shared/find-esp.c @@ -280,9 +280,9 @@ static int verify_fsroot_dir( * directly instead. It's not as good, due to symlinks and such, but we can't do * anything better here. */ - parent = dirname_malloc(path); - if (!parent) - return log_oom(); + r = path_extract_filename(path, &parent); + if (r < 0) + return log_error_errno(r, "Failed to extract parent path from '%s': %m", path); r = RET_NERRNO(stat(parent, &st2)); } diff --git a/src/shared/install.c b/src/shared/install.c index 5ae39f6a04..1a0a536080 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -102,12 +102,13 @@ DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type, UnitFileType); static int in_search_path(const LookupPaths *lp, const char *path) { _cleanup_free_ char *parent = NULL; + int r; assert(path); - parent = dirname_malloc(path); - if (!parent) - return -ENOMEM; + r = path_extract_directory(path, &parent); + if (r < 0) + return r; return path_strv_contains(lp->search_path, parent); } @@ -135,13 +136,14 @@ static const char* skip_root(const char *root_dir, const char *path) { static int path_is_generator(const LookupPaths *lp, const char *path) { _cleanup_free_ char *parent = NULL; + int r; assert(lp); assert(path); - parent = dirname_malloc(path); - if (!parent) - return -ENOMEM; + r = path_extract_directory(path, &parent); + if (r < 0) + return r; return path_equal_ptr(parent, lp->generator) || path_equal_ptr(parent, lp->generator_early) || @@ -150,26 +152,28 @@ static int path_is_generator(const LookupPaths *lp, const char *path) { static int path_is_transient(const LookupPaths *lp, const char *path) { _cleanup_free_ char *parent = NULL; + int r; assert(lp); assert(path); - parent = dirname_malloc(path); - if (!parent) - return -ENOMEM; + r = path_extract_directory(path, &parent); + if (r < 0) + return r; return path_equal_ptr(parent, lp->transient); } static int path_is_control(const LookupPaths *lp, const char *path) { _cleanup_free_ char *parent = NULL; + int r; assert(lp); assert(path); - parent = dirname_malloc(path); - if (!parent) - return -ENOMEM; + r = path_extract_directory(path, &parent); + if (r < 0) + return r; return path_equal_ptr(parent, lp->persistent_control) || path_equal_ptr(parent, lp->runtime_control); @@ -177,6 +181,7 @@ static int path_is_control(const LookupPaths *lp, const char *path) { static int path_is_config(const LookupPaths *lp, const char *path, bool check_parent) { _cleanup_free_ char *parent = NULL; + int r; assert(lp); assert(path); @@ -185,9 +190,9 @@ static int path_is_config(const LookupPaths *lp, const char *path, bool check_pa * them we couldn't discern configuration from transient or generated units */ if (check_parent) { - parent = dirname_malloc(path); - if (!parent) - return -ENOMEM; + r = path_extract_directory(path, &parent); + if (r < 0) + return r; path = parent; } @@ -199,6 +204,7 @@ static int path_is_config(const LookupPaths *lp, const char *path, bool check_pa static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_parent) { _cleanup_free_ char *parent = NULL; const char *rpath; + int r; assert(lp); assert(path); @@ -211,9 +217,9 @@ static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_p return true; if (check_parent) { - parent = dirname_malloc(path); - if (!parent) - return -ENOMEM; + r = path_extract_directory(path, &parent); + if (r < 0) + return r; path = parent; } @@ -1793,9 +1799,9 @@ int unit_file_verify_alias( path_alias ++; /* skip over slash */ - dir = dirname_malloc(dst); - if (!dir) - return log_oom(); + r = path_extract_directory(dst, &dir); + if (r < 0) + return log_error_errno(r, "Failed to extract parent directory from '%s': %m", dst); p = endswith(dir, ".wants"); if (!p) diff --git a/src/systemctl/systemctl-edit.c b/src/systemctl/systemctl-edit.c index 446dfd7dd6..a363d7a494 100644 --- a/src/systemctl/systemctl-edit.c +++ b/src/systemctl/systemctl-edit.c @@ -579,9 +579,9 @@ end: if (!arg_full) { _cleanup_free_ char *dir = NULL; - dir = dirname_malloc(*original); - if (!dir) - return log_oom(); + r = path_extract_directory(*original, &dir); + if (r < 0) + return log_error_errno(r, "Failed to extract directory from '%s': %m", *original); /* No need to check if the dir is empty, rmdir does nothing if it is not the case. */ (void) rmdir(dir); diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index 36a0748c14..beeffda316 100644 --- a/src/systemctl/systemctl-show.c +++ b/src/systemctl/systemctl-show.c @@ -393,10 +393,10 @@ static void print_status_info( dir = mfree(dir); - dir = dirname_malloc(*dropin); - if (!dir) { - log_oom(); - return; + r = path_extract_directory(*dropin, &dir); + if (r < 0) { + log_error_errno(r, "Failed to extract directory of '%s': %m", *dropin); + break; } printf("%s\n" diff --git a/src/test/test-bpf-devices.c b/src/test/test-bpf-devices.c index 587591cf04..e175483734 100644 --- a/src/test/test-bpf-devices.c +++ b/src/test/test-bpf-devices.c @@ -295,7 +295,7 @@ int main(int argc, char *argv[]) { test_policy_empty(false, cgroup, &prog); test_policy_empty(true, cgroup, &prog); - assert_se(parent = dirname_malloc(cgroup)); + assert_se(path_extract_directory(cgroup, &parent) >= 0); assert_se(cg_mask_supported(&supported) >= 0); r = cg_attach_everywhere(supported, parent, 0, NULL, NULL); -- cgit v1.2.3