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)
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.
return r;
}
- *var = strv_join(ans, ":");
- if (!*var)
+ joined = strv_join(ans, ":");
+ if (!joined)
return -ENOMEM;
+ *ret = TAKE_PTR(joined);
return 0;
}
}
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)
}
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;
/* 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");
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);
}
/* 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;
}
/* 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)
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 */
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)
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);
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);
} 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);
#include <sys/sendfile.h>
-/* 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 <libgen.h>
-#undef basename
-
#include "sd-daemon.h"
#include "alloc-util.h"
#include <sys/mman.h>
#include <sys/prctl.h>
-/* 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 <libgen.h>
-#undef basename
-
#include "alloc-util.h"
#include "bus-internal.h"
#include "bus-kernel.h"
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);
_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)
#include <sys/mount.h>
#include <sys/wait.h>
-/* 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 <libgen.h>
-#undef basename
-
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-get-properties.h"
}
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;
bool copy_from;
pid_t child;
uid_t uid_shift;
- char *t;
int r;
assert(message);
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)
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;
}
* 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));
}
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);
}
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) ||
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);
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);
* 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;
}
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);
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;
}
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)
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);
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"
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);