Skip to content

getdents64 should be stateful #1589

Open
@mkroening

Description

@mkroening

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).

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions