recurse-dir: add new readdir_all_at() helper
authorLennart Poettering <lennart@poettering.net>
Wed, 22 Nov 2023 09:55:20 +0000 (10:55 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 6 Dec 2023 21:12:48 +0000 (22:12 +0100)
This new helper combines open() with readdir_all() to simplify a few
callers.

src/basic/recurse-dir.c
src/basic/recurse-dir.h
src/core/import-creds.c
src/shared/mkfs-util.c

index 5e98b7a5d8d66102cb345f194fee33688acfa01e..1f505d5750055e655a48fb555607288f70f1bbc5 100644 (file)
@@ -4,6 +4,7 @@
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "missing_syscall.h"
 #include "mountpoint-util.h"
 #include "recurse-dir.h"
@@ -132,6 +133,18 @@ int readdir_all(int dir_fd,
         return 0;
 }
 
+int readdir_all_at(int fd, const char *path, RecurseDirFlags flags, DirectoryEntries **ret) {
+        _cleanup_close_ int dir_fd = -EBADF;
+
+        assert(fd >= 0 || fd == AT_FDCWD);
+
+        dir_fd = xopenat(fd, path, O_DIRECTORY|O_CLOEXEC, /* xopen_flags= */ 0, /* mode= */ 0);
+        if (dir_fd < 0)
+                return dir_fd;
+
+        return readdir_all(dir_fd, flags, ret);
+}
+
 int recurse_dir(
                 int dir_fd,
                 const char *path,
index 9f6a7adb95b4b7b94b88c2eff80ac0e513cb3f22..aaeae950fe5a87d03af4c376581c6cc56809bf80 100644 (file)
@@ -76,6 +76,7 @@ typedef struct DirectoryEntries {
 } DirectoryEntries;
 
 int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret);
+int readdir_all_at(int fd, const char *path, RecurseDirFlags flags, DirectoryEntries **ret);
 
 int recurse_dir(int dir_fd, const char *path, unsigned statx_mask, unsigned n_depth_max, RecurseDirFlags flags, recurse_dir_func_t func, void *userdata);
 int recurse_dir_at(int atfd, const char *path, unsigned statx_mask, unsigned n_depth_max, RecurseDirFlags flags, recurse_dir_func_t func, void *userdata);
index 48f31609231e761a93328f2e90df948ca921024f..e53deb639ec422bc1d11abef07b896395d31b1df 100644 (file)
@@ -815,7 +815,6 @@ static int setenv_notify_socket(void) {
 
 static int report_credentials_per_func(const char *title, int (*get_directory_func)(const char **ret)) {
         _cleanup_free_ DirectoryEntries *de = NULL;
-        _cleanup_close_ int dir_fd = -EBADF;
         _cleanup_free_ char *ll = NULL;
         const char *d = NULL;
         int r, c = 0;
@@ -831,11 +830,7 @@ static int report_credentials_per_func(const char *title, int (*get_directory_fu
                 return log_warning_errno(r, "Failed to determine %s directory: %m", title);
         }
 
-        dir_fd = open(d, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
-        if (dir_fd < 0)
-                return log_warning_errno(errno, "Failed to open credentials directory %s: %m", d);
-
-        r = readdir_all(dir_fd, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT, &de);
+        r = readdir_all_at(AT_FDCWD, d, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT, &de);
         if (r < 0)
                 return log_warning_errno(r, "Failed to enumerate credentials directory %s: %m", d);
 
index 4e58b6e871ec4fc5e61a466f23aa608218a2fe17..19b119b4afaa18e7ebcd9c75e8ebe6dc33c8f8eb 100644 (file)
@@ -104,7 +104,6 @@ static int mangle_fat_label(const char *s, char **ret) {
 static int do_mcopy(const char *node, const char *root) {
         _cleanup_free_ char *mcopy = NULL;
         _cleanup_strv_free_ char **argv = NULL;
-        _cleanup_close_ int rfd = -EBADF;
         _cleanup_free_ DirectoryEntries *de = NULL;
         int r;
 
@@ -128,11 +127,7 @@ static int do_mcopy(const char *node, const char *root) {
         /* mcopy copies the top level directory instead of everything in it so we have to pass all
          * the subdirectories to mcopy instead to end up with the correct directory structure. */
 
-        rfd = open(root, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
-        if (rfd < 0)
-                return log_error_errno(errno, "Failed to open directory '%s': %m", root);
-
-        r = readdir_all(rfd, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE, &de);
+        r = readdir_all_at(AT_FDCWD, root, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE, &de);
         if (r < 0)
                 return log_error_errno(r, "Failed to read '%s' contents: %m", root);