MCPcopy Create free account
hub / github.com/bytecodealliance/rustix / read

Method read

src/backend/linux_raw/fs/dir.rs:128–236  ·  view source on GitHub ↗

`readdir(self)`, where `None` means the end of the directory.

(&mut self)

Source from the content-addressed store, hash-verified

126
127 /// `readdir(self)`, where `None` means the end of the directory.
128 pub fn read(&mut self) -> Option<io::Result<DirEntry>> {
129 // If we've seen errors, don't continue to try to read anything
130 // further.
131 if self.any_errors {
132 return None;
133 }
134
135 // If a rewind was requested, seek to the beginning.
136 if self.rewind {
137 self.rewind = false;
138 match io::retry_on_intr(|| {
139 crate::backend::fs::syscalls::_seek(self.fd.as_fd(), 0, SEEK_SET)
140 }) {
141 Ok(_) => (),
142 Err(err) => {
143 self.any_errors = true;
144 return Some(Err(err));
145 }
146 }
147 }
148
149 // Compute linux_dirent64 field offsets.
150 let z = linux_dirent64 {
151 d_ino: 0_u64,
152 d_off: 0_i64,
153 d_type: 0_u8,
154 d_reclen: 0_u16,
155 d_name: Default::default(),
156 };
157 let base = as_ptr(&z) as usize;
158 let offsetof_d_reclen = (as_ptr(&z.d_reclen) as usize) - base;
159 let offsetof_d_name = (as_ptr(&z.d_name) as usize) - base;
160 let offsetof_d_ino = (as_ptr(&z.d_ino) as usize) - base;
161 let offsetof_d_off = (as_ptr(&z.d_off) as usize) - base;
162 let offsetof_d_type = (as_ptr(&z.d_type) as usize) - base;
163
164 // Test if we need more entries, and if so, read more.
165 if self.buf.len() - self.pos < size_of::<linux_dirent64>() {
166 match self.read_more()? {
167 Ok(()) => (),
168 Err(err) => return Some(Err(err)),
169 }
170 }
171
172 // We successfully read an entry. Extract the fields.
173 let pos = self.pos;
174
175 // Do an unaligned u16 load.
176 let d_reclen = u16::from_ne_bytes([
177 self.buf[pos + offsetof_d_reclen],
178 self.buf[pos + offsetof_d_reclen + 1],
179 ]);
180 assert!(self.buf.len() - pos >= d_reclen as usize);
181 self.pos += d_reclen as usize;
182
183 // Read the NUL-terminated name from the `d_name` field. Without
184 // `unsafe`, we need to scan for the NUL twice: once to obtain a size
185 // for the slice, and then once within `CStr::from_bytes_with_nul`.

Callers 1

tcgetattr_fallbackFunction · 0.45

Calls 6

retry_on_intrFunction · 0.85
_seekFunction · 0.85
as_ptrFunction · 0.85
read_moreMethod · 0.80
as_fdMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected