Description
Currently, Hermit's getdents64
is not stateful. This means that when reading a directory, the caller needs to provide a buffer that is large enough to hold all directory members. A buffer that can only hold a few members returns EINVAL
.
Instead, getdents64
should be stateful. This means that when reading a directory, it is fine if the caller provides a buffer that can only hold a few members of the directory. getdents64
is then called again and again to return the next members until it returns 0 (end of directory). Only if the buffer is too small to hold the next member, EINVAL
is returned.
This issue shows itself in newlib, which allocates a buffer of size 512 and then calls getdents64
until it returns 0 (end of directory). Currently, this loops endlessly, since we always start from the beginning of the directory and never return 0.
The issue has been worked around in rust-std by growing the buffer until it is big enough to hold all directory members. This is not ideal for performance, since we eagerly copy all the directory members instead of copying lazily while iterating over ReadDir
. This is also not ideal for memory consumption, since the buffer we allocate can grow arbitrarily large instead of staying constant.
The state should be exposed by and resettable via lseek
(which is used in newlib's seekdir
and rewinddir
).