diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-08-22 12:34:34 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-08-23 15:10:15 +0200 |
commit | 45519d13a4f2a3c3585e672595762ca621abe65e (patch) | |
tree | 8680b032714ce1b7f823049d1e71b6ecb4b7e308 /src/basic/mkdir.c | |
parent | Merge pull request #24412 from keszybz/man-similarly (diff) | |
download | systemd-45519d13a4f2a3c3585e672595762ca621abe65e.tar.xz systemd-45519d13a4f2a3c3585e672595762ca621abe65e.zip |
tree-wide: port things dirname_malloc() → path_extract_directory()
Diffstat (limited to 'src/basic/mkdir.c')
-rw-r--r-- | src/basic/mkdir.c | 41 |
1 files changed, 22 insertions, 19 deletions
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) |