Commit Graph
33 Commits
Author SHA1 Message Date
Lennart Poettering 90d285ade7 recurse-dir: optionally, only enumerate dentries of a specific type
At various places we filter directory enumerations by inode type. Let's
add explicit support for that, so that the "struct dirent" array we
return already suppresses them.

This shortens code and makes things more robust.
2026-06-22 14:40:16 +02:00
Luca Boccassi 8fa088b886 recurse-dir: add assert for MALLOC_SIZEOF_SAFE lower bound
Coverity flags MALLOC_SIZEOF_SAFE(de) - offsetof(DirectoryEntries,
buffer) as a potential underflow when MALLOC_SIZEOF_SAFE returns 0.
After a successful malloc the return value is at least as large as
the requested size, but Coverity cannot trace this. Add an assert
to establish the lower bound.

CID#1548020

Follow-up for 6393b847f4
2026-04-07 23:59:16 +01:00
Michael Vogt 18e70eec2f basic: make check-pointer-deref clean
Add the needed assert changes to make the code clean
for the new check-pointer-deref script.

Note that for `_cmp()` functions its a bit of a question
if we want `assert()` or `POINTER_MAY_BE_NULL()` here. The
former is more correct but it adds a (small) runtime hit. If
we use POINTER_MAY_BE_NULL() it is compiled out but strictly
speaking it is wrong (so at least we would need a comment).
2026-03-31 18:30:40 +02:00
Luca Boccassi 4b25c74c20 recurse-dir: add assert_cc for DIRENT_SIZE_MAX allocation
Coverity flags offsetof(DirectoryEntries, buffer) + DIRENT_SIZE_MAX * 8
as a potential overflow. All operands are compile-time constants, so add
an assert_cc() to prove this at build time.

CID#1548020

Follow-up for 6393b847f4
2026-03-28 20:24:22 +00:00
Mike Yuan 537045ec2f recurse-dir: remove stale comment
Follow-up for 6393b847f4
2026-01-19 03:06:30 +01:00
Lennart Poettering b6aa78f707 recursedir: introduce new RECURSE_DIR_UNLINK callback return value
This introduces RECURSE_DIR_UNLINK + RECURSE_DIR_UNLINK_GRACEFUL as new
return values for recurse_dir() callbacks. If either is returned the
inode currently processed will be removed and iteration continues with
the next item.

This is useful to have in the recurse_dir() mechanism itself (rather
than implement in the callback itself), due to ordering: we want to pin
the inodes via an fd while calling the callbacks, but we have to close
it before removal of the inodes. By moving this into the recurse_dir()
infra, we can implement this easily.
2025-12-21 07:04:42 +01:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Mike Yuan ba010e14f2 recurse-dir: switch to FOREACH_ARRAY 2025-07-09 10:13:59 +02:00
Mike Yuan 8d4b2689ca recurse-dir: use -EBADF as placeholder for invalid fd
As per our coding style.
2025-07-09 10:13:59 +02:00
Yu Watanabe 43aacae83a dirent-util: use getdents64() as is
This partially reverts e86a492ff0.

The function getdents64() was introduced in glibc-2.30, and our baseline
on glibc is 2.31. Hence, we can assume the function always exists.
The posix_getdents() wrapper was introduced for compatibility with musl.
However, even the latest release of musl does not provide posix_getdents()
yet. Also, even with musl, by defining _LARGEFILE64_SOURCE, we can get
getdents64() and struct dirent64. Hence, the wrapper is anyway not
necessary.
2025-06-18 10:45:49 +02:00
Daan De Meyer 0c15577abe basic + fundamental: Clean up includes
Split out of #37344.
2025-05-25 10:06:07 +02:00
Daan De Meyer 93a1f7921a basic: Stop including log.h in macro.h
Now that the necessary functions from log.h have been moved to macro.h,
we can stop including log.h in macro.h. This requires modifying source
files all over the tree to include log.h instead.
2025-04-18 14:19:15 +02:00
Yu Watanabe e86a492ff0 dirent-util: introduce simple wrapper of posix_getdents()
glibc exports getdents64 syscall as is, but musl exports it as
posix_getdents(). Let's introduce a simple wrapper of posix_getdents().

Note, our baseline for glibc is 2.31. Hence, we can assume getdents64()
always defined when building with glibc.
2025-03-04 04:23:57 +09:00
Yu Watanabe d5ddc0e0d3 stat-util: drop statx_fallback()
Now both our required baseline of glibc and kernel support statx.
2025-03-01 00:33:32 +09:00
Yu Watanabe 4424e6c811 tree-wide: drop workarounds for statx()
struct statx in glibc header was introduced in glibc-2.28
(fd70af45528d59a00eb3190ef6706cb299488fcd), but at that time,
sys/stat.h conflicts with linux/stat.h. Since glibc-2.30
(5dad6ffbb2b76215cfcd38c3001778536ada8e8a), sys/stat.h includes
linux/stat.h if exists.

Since now our baseline of glibc is 2.31. Hence, we can drop workarounds
for struct statx by importing linux/stat.h from newer kernel (v6.14-rc4).
2025-03-01 00:33:28 +09:00
Yu Watanabe 91421f8379 recurse-dir: fix wrong assertion and error code in log
Fixes a bug in b5a07e524e (v250).
2025-02-28 23:37:52 +09:00
Mike Yuan 7ce2c1bb5f mountpoint-util: rename fd_is_mount_point() to is_mount_point_at()
fd_* functions in our codebase usually mean fd-specific operations,
while this one actually takes openat()-style params. Rename it
accordingly hence.
2025-01-22 01:37:31 +01:00
Mike Yuan 90761f7f68 basic/recurse-dir: modernize readdir_all() 2024-12-30 23:52:19 +01:00
Yu Watanabe f769518c9a tree-wide: drop doubled empty lines 2024-10-07 09:51:37 +02:00
Yu Watanabe e40b11be04 fs-util: rename xopenat() -> xopanat_full() 2024-02-16 00:25:37 +09:00
Lennart Poettering 4d56442755 recurse-dir: add new readdir_all_at() helper
This new helper combines open() with readdir_all() to simplify a few
callers.
2023-12-06 22:12:48 +01:00
Zbigniew Jędrzejewski-Szmek 254d1313ae tree-wide: use -EBADF for fd initialization
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.

Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state

Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.

In some places, initialization is dropped if unnecessary.
2022-12-19 15:00:57 +01:00
Daan De Meyer a0a4c57818 recurse-dir: Handle RECURSE_DIR_ENSURE_TYPE in readdir_all() 2022-11-24 14:02:19 +01:00
Lennart Poettering b21ec07b54 recurse-dir: optionally, call callback when entering/leaving toplevel dir, too
So far recurse_dir() will call the callback whenever we enter a
directory, and then pass the struct dirent for that directory, and an fd
for the directory the dirent is part of (i.e. the parent of the
directory we call things for). For the top-level dir the function is
invoked for we will not call the callback however, because we have no
dirent for that, and not fd for the directory the top-level dir is part
of. Let's add a flag to call it anyway, and in that case pass a NULL
dirent and -1 as directory fd.

This is useful when we want to treat the top-level dir the same as any
dir further down.

This is done opt-in since the callback must be ablet to handle a NULL
dirent and a -1 directory fd.
2022-11-09 18:55:58 +01:00
Lennart Poettering 739d9cae40 recurse-dir: use fd_reopen() at one more place
Inspired by 83b94cf10e
2022-09-21 00:55:23 +09:00
Lennart Poettering aa3cc58a9f recurse-dir: give callers of recurse_dir_at() control over path prefix
One of the niceties of recurse_dir()/recurse_dir_at() is that the path
argument is decoration, it's not used for actually accessing the fs in
anyway. That's very handy in environments where chroots and relative
paths are used, as we can path in any path we like and the recursion
function will suffix with whatever it discovers but will not try to make
sense of the prefix you pass.

This works great, except that the recurse_dir_at() wrapper broke that:
it adjusted the path if NULL to "." simply for the sake of making
openat() on the top work. Let's make this adjustment more local and do
it only for the openat() itself, and otherwise pass the path through the
way we got it. This means: if a caller really wants the paths that are
concatenated to start with a "." it can just pass that. This way the
caller gets full control back of the path prefix. Win!

Note that all current users of recurse_dir_at() don't pass NULL as
second arg, hence this check is without any real effect for now. It's
preparation for future uses however.
2021-11-24 09:34:10 +01:00
Lennart Poettering 0dbce03c37 tree-wide: explicitly unpoison getdents64() memory
Apparently memory sanitizer doesn't grok getdents64() properly. Let's
address that by explicitly marken memory initialized by getdents64() as
unpoisoned.
2021-10-25 21:51:37 +02:00
Lennart Poettering a4e70ef7ba 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)
2021-10-25 21:51:37 +02:00
Lennart Poettering ca664db258 dirent-util: move getdents64() related definitions to common header
We want to reuse getdents64() wherever necessary, let's hence move
definitions useful for that into public code.
2021-10-25 21:50:20 +02:00
Dimitri Papadopoulos ba669952b2 Typos found by codespell 2021-10-20 22:20:18 +09:00
Lennart Poettering 6393b847f4 recuse-dir: rework to use getdents64() instead of readdir()
Let's use the underlying Linux API directly, instead of
opendir()/readdir(). This makes it possible for us to do a single memory
allocation for all directory entries in common cases, instead of one for
each entry.
2021-10-11 14:31:34 +02:00
Lennart Poettering ba24ef86e7 dirent-util: get rid of stat_mode_to_dirent_type()
Apparently glibc already has a helper for this. (Not in the man pages
for Linux, but FreeBSD does document these cryptic helpers, and its
exported by glibc. That should be good enough for us.)
2021-10-07 23:13:03 +02:00
Lennart Poettering b5a07e524e basic: add new recurse_dir() tool as replacement for nftw()
libc nftw() shows its age a bit, let's replace it with a more moden
infra that is built around openat(), O_PATH, statx(). This makes the
interface less prone to races and cleans up the API a bit adding
substantially more functionality.
2021-10-07 11:58:26 +02:00