diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-10-23 00:28:24 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-10-25 21:51:37 +0200 |
commit | a4e70ef7ba3b5e2c050cce5ed2bbf58807505596 (patch) | |
tree | f48de09715f7a30cf786a9b7a3b4c5e9e555bba9 | |
parent | ca664db25860d7fcd581380e24ad74f510c1f40f (diff) | |
download | systemd-a4e70ef7ba3b5e2c050cce5ed2bbf58807505596.tar.gz |
dirent-util: add FOREACH macro for iterating through getdents64() buffers
We already have a similar loop twice, let's make it easier to read via
an iteration macro.
(The new macro is a bit more careful even, as it verifies the full
dirent fits into the remaining buffer when returning it)
-rw-r--r-- | src/basic/dirent-util.h | 5 | ||||
-rw-r--r-- | src/basic/recurse-dir.c | 13 | ||||
-rw-r--r-- | src/basic/recurse-dir.h | 2 |
3 files changed, 10 insertions, 10 deletions
diff --git a/src/basic/dirent-util.h b/src/basic/dirent-util.h index 73e78102a5..768cc1de61 100644 --- a/src/basic/dirent-util.h +++ b/src/basic/dirent-util.h @@ -51,3 +51,8 @@ assert_cc(offsetof(struct dirent, d_type) == offsetof(struct dirent64, d_type)); 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)) diff --git a/src/basic/recurse-dir.c b/src/basic/recurse-dir.c index adc855955a..dbada82431 100644 --- a/src/basic/recurse-dir.c +++ b/src/basic/recurse-dir.c @@ -30,6 +30,7 @@ int readdir_all(int dir_fd, DirectoryEntries **ret) { _cleanup_free_ DirectoryEntries *de = NULL; + struct dirent *entry; DirectoryEntries *nde; size_t add, sz, j; @@ -53,7 +54,7 @@ int readdir_all(int dir_fd, 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) @@ -77,10 +78,7 @@ int readdir_all(int dir_fd, } 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; @@ -100,10 +98,7 @@ int readdir_all(int dir_fd, 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; diff --git a/src/basic/recurse-dir.h b/src/basic/recurse-dir.h index 93b00f0d97..779c91e905 100644 --- a/src/basic/recurse-dir.h +++ b/src/basic/recurse-dir.h @@ -71,7 +71,7 @@ typedef struct DirectoryEntries { 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); |