dot_or_dot_dot(de->d_name);
}
-int readdir_all(int dir_fd,
- RecurseDirFlags flags,
- DirectoryEntries **ret) {
-
+int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret) {
_cleanup_free_ DirectoryEntries *de = NULL;
- struct dirent *entry;
DirectoryEntries *nde;
- size_t add, sz, j;
int r;
assert(dir_fd >= 0);
nde = realloc(de, bs);
if (!nde)
return -ENOMEM;
-
de = nde;
}
de->n_entries = 0;
+ struct dirent *entry;
FOREACH_DIRENT_IN_BUFFER(entry, de->buffer, de->buffer_size) {
if (ignore_dirent(entry, flags))
continue;
de->n_entries++;
}
+ size_t sz, j;
+
sz = ALIGN(offsetof(DirectoryEntries, buffer) + de->buffer_size);
- add = sizeof(struct dirent*) * de->n_entries;
- if (add > SIZE_MAX - add)
+ if (!INC_SAFE(&sz, sizeof(struct dirent*) * de->n_entries))
return -ENOMEM;
- nde = realloc(de, sz + add);
+ nde = realloc(de, sz);
if (!nde)
return -ENOMEM;
-
de = nde;
+
de->entries = (struct dirent**) ((uint8_t*) de + ALIGN(offsetof(DirectoryEntries, buffer) + de->buffer_size));
j = 0;
#include "stat-util.h"
#include "macro.h"
+typedef enum RecurseDirFlags {
+ /* Interpreted by readdir_all() */
+ RECURSE_DIR_SORT = 1 << 0, /* sort file directory entries before processing them */
+ RECURSE_DIR_IGNORE_DOT = 1 << 1, /* ignore all dot files ("." and ".." are always ignored) */
+ RECURSE_DIR_ENSURE_TYPE = 1 << 2, /* guarantees that 'd_type' field of 'de' is not DT_UNKNOWN */
+
+ /* Interpreted by recurse_dir() */
+ RECURSE_DIR_SAME_MOUNT = 1 << 3, /* skips over subdirectories that are submounts */
+ RECURSE_DIR_INODE_FD = 1 << 4, /* passes an opened inode fd (O_DIRECTORY fd in case of dirs, O_PATH otherwise) */
+ RECURSE_DIR_TOPLEVEL = 1 << 5, /* call RECURSE_DIR_ENTER/RECURSE_DIR_LEAVE once for top-level dir, too, with dir_fd=-1 and NULL dirent */
+} RecurseDirFlags;
+
+typedef struct DirectoryEntries {
+ size_t n_entries;
+ struct dirent **entries;
+ size_t buffer_size;
+ struct dirent buffer[];
+} DirectoryEntries;
+
+int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret);
+int readdir_all_at(int fd, const char *path, RecurseDirFlags flags, DirectoryEntries **ret);
+
typedef enum RecurseDirEvent {
RECURSE_DIR_ENTER, /* only for dir inodes */
RECURSE_DIR_LEAVE, /* only for dir inodes */
const struct statx *sx, /* statx data (only if statx_mask was non-zero) */
void *userdata);
-typedef enum RecurseDirFlags {
- /* Interpreted by readdir_all() */
- RECURSE_DIR_SORT = 1 << 0, /* sort file directory entries before processing them */
- RECURSE_DIR_IGNORE_DOT = 1 << 1, /* ignore all dot files ("." and ".." are always ignored) */
- RECURSE_DIR_ENSURE_TYPE = 1 << 2, /* guarantees that 'd_type' field of 'de' is not DT_UNKNOWN */
-
- /* Interpreted by recurse_dir() */
- RECURSE_DIR_SAME_MOUNT = 1 << 3, /* skips over subdirectories that are submounts */
- RECURSE_DIR_INODE_FD = 1 << 4, /* passes an opened inode fd (O_DIRECTORY fd in case of dirs, O_PATH otherwise) */
- RECURSE_DIR_TOPLEVEL = 1 << 5, /* call RECURSE_DIR_ENTER/RECURSE_DIR_LEAVE once for top-level dir, too, with dir_fd=-1 and NULL dirent */
-} RecurseDirFlags;
-
-typedef struct DirectoryEntries {
- size_t n_entries;
- struct dirent** entries;
- size_t buffer_size;
- struct dirent buffer[];
-} 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);