Rust ReadDir Iterator
About
The std::fs::read_dir returns a ReadDir struct, which is an Iterator,
wrapped in a Result. The Result value resolves to an error in the following
conditions:
- The process doesn't have permission to read the directory.
- The directory doesn't exist.
- The path is not a directory.
This is understandable. What's annoying is that each item returned by the iterator is of also Result type.
Consequently, I investigated the Iterator implementation ReadDir to see when
would an Err occur.
Learning
Rust
The Iterator implementation of ReadDir eventually invokes a system call:
readdir_r.
System call
The readdir_r system call accepts a pointer to a dirent struct and will
mutate it. It's return type is int, which communicats a potential error.
When I investigated the potential errors, I understood that it's not a
deterministic set. In fact, any error from sys/errno.h may be returned so it's
implementation dependant.
Luckily man pages (man 3 readdir_r) hint that the returned value may be any
values documented for the getdirentries(2) system call.
ERRORS
getdirentries() will fail if:
[EBADF] fd is not a valid file descriptor open for reading.
[EFAULT] Either buf or basep point outside the allocated address space.
[EIO] An I/O error occurred while reading from or writing to the file system.
The manual pages from BSD are also friendly and hint that it may return any
error that getdents returns:
ERRORS
The getdirentries() system call will fail if:
[EBADF] The fd argument is not a valid file descriptor open
for reading.
[EFAULT] Either buf or non-NULL basep point outside the allo-
cated address space.
[EINVAL] The file referenced by fd is not a directory, or
nbytes is too small for returning a directory entry
or block of entries, or the current position pointer
is invalid.
[EIO] An I/O error occurred while reading from or writing
to the file system.
[EINTEGRITY] Corrupted data was detected while reading from the
file system.
[ENOENT] Directory unlinked but still open.Overall, these errors seem very edge casey. I think I'll just handle the errors with a log and skip for my code.
Iteration state
The Iterator for ReadDir does not use Rust code to keep a state of the
iteration. Instead, it uses a directory stream that's incremented by subsequent
readdir_r calls.