assert_cc(sizeof_field(struct dirent, d_type) == sizeof_field(struct dirent64, d_type));
assert_cc(offsetof(struct dirent, d_name) == offsetof(struct dirent64, d_name));
assert_cc(sizeof_field(struct dirent, d_name) == sizeof_field(struct dirent64, d_name));
+
+#define FOREACH_DIRENT_IN_BUFFER(de, buf, sz) \
+ for (void *_end = (uint8_t*) ({ (de) = (buf); }) + (sz); \
+ (uint8_t*) (de) < (uint8_t*) _end; \
+ (de) = (struct dirent*) ((uint8_t*) (de) + (de)->d_reclen))
DirectoryEntries **ret) {
_cleanup_free_ DirectoryEntries *de = NULL;
+ struct dirent *entry;
DirectoryEntries *nde;
size_t add, sz, j;
bs = MIN(MALLOC_SIZEOF_SAFE(de) - offsetof(DirectoryEntries, buffer), (size_t) SSIZE_MAX);
assert(bs > de->buffer_size);
- n = getdents64(dir_fd, de->buffer + de->buffer_size, bs - de->buffer_size);
+ n = getdents64(dir_fd, (uint8_t*) de->buffer + de->buffer_size, bs - de->buffer_size);
if (n < 0)
return -errno;
if (n == 0)
}
de->n_entries = 0;
- for (struct dirent *entry = (struct dirent*) de->buffer;
- (uint8_t*) entry < de->buffer + de->buffer_size;
- entry = (struct dirent*) ((uint8_t*) entry + entry->d_reclen)) {
-
+ FOREACH_DIRENT_IN_BUFFER(entry, de->buffer, de->buffer_size) {
if (ignore_dirent(entry, flags))
continue;
de->entries = (struct dirent**) ((uint8_t*) de + ALIGN(offsetof(DirectoryEntries, buffer) + de->buffer_size));
j = 0;
- for (struct dirent *entry = (struct dirent*) de->buffer;
- (uint8_t*) entry < de->buffer + de->buffer_size;
- entry = (struct dirent*) ((uint8_t*) entry + entry->d_reclen)) {
-
+ FOREACH_DIRENT_IN_BUFFER(entry, de->buffer, de->buffer_size) {
if (ignore_dirent(entry, flags))
continue;
size_t n_entries;
struct dirent** entries;
size_t buffer_size;
- uint8_t buffer[] _alignas_(struct dirent);
+ struct dirent buffer[];
} DirectoryEntries;
int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret);