mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Update ReadDir::next in std::sys::pal::unix::fs to use &raw const (*ptr).field
instead of ptr.offset(...).cast()
.
Also, the macro is only called three times, and all with the same local variable entry_ptr, so just use the local variable directly, and rename the macro to entry_field_ptr.
This commit is contained in:
parent
dd333ca66f
commit
58d6301cad
@ -709,7 +709,7 @@ impl Iterator for ReadDir {
|
|||||||
// thread safety for readdir() as long an individual DIR* is not accessed
|
// thread safety for readdir() as long an individual DIR* is not accessed
|
||||||
// concurrently, which is sufficient for Rust.
|
// concurrently, which is sufficient for Rust.
|
||||||
super::os::set_errno(0);
|
super::os::set_errno(0);
|
||||||
let entry_ptr = readdir64(self.inner.dirp.0);
|
let entry_ptr: *const dirent64 = readdir64(self.inner.dirp.0);
|
||||||
if entry_ptr.is_null() {
|
if entry_ptr.is_null() {
|
||||||
// We either encountered an error, or reached the end. Either way,
|
// We either encountered an error, or reached the end. Either way,
|
||||||
// the next call to next() should return None.
|
// the next call to next() should return None.
|
||||||
@ -735,29 +735,19 @@ impl Iterator for ReadDir {
|
|||||||
// contents were "simply" partially initialized data.
|
// contents were "simply" partially initialized data.
|
||||||
//
|
//
|
||||||
// Like for uninitialized contents, converting entry_ptr to `&dirent64`
|
// Like for uninitialized contents, converting entry_ptr to `&dirent64`
|
||||||
// would not be legal. However, unique to dirent64 is that we don't even
|
// would not be legal. However, we can use `&raw const (*entry_ptr).d_name`
|
||||||
// get to use `&raw const (*entry_ptr).d_name` because that operation
|
// to refer the fields individually, because that operation is equivalent
|
||||||
// requires the full extent of *entry_ptr to be in bounds of the same
|
// to `byte_offset` and thus does not require the full extent of `*entry_ptr`
|
||||||
// allocation, which is not necessarily the case here.
|
// to be in bounds of the same allocation, only the offset of the field
|
||||||
//
|
// being referenced.
|
||||||
// Instead we must access fields individually through their offsets.
|
macro_rules! entry_field_ptr {
|
||||||
macro_rules! offset_ptr {
|
($field:ident) => {
|
||||||
($entry_ptr:expr, $field:ident) => {{
|
&raw const (*entry_ptr).$field
|
||||||
const OFFSET: isize = mem::offset_of!(dirent64, $field) as isize;
|
};
|
||||||
if true {
|
|
||||||
// Cast to the same type determined by the else branch.
|
|
||||||
$entry_ptr.byte_offset(OFFSET).cast::<_>()
|
|
||||||
} else {
|
|
||||||
#[allow(deref_nullptr)]
|
|
||||||
{
|
|
||||||
&raw const (*ptr::null::<dirent64>()).$field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// d_name is guaranteed to be null-terminated.
|
// d_name is guaranteed to be null-terminated.
|
||||||
let name = CStr::from_ptr(offset_ptr!(entry_ptr, d_name).cast());
|
let name = CStr::from_ptr(entry_field_ptr!(d_name).cast());
|
||||||
let name_bytes = name.to_bytes();
|
let name_bytes = name.to_bytes();
|
||||||
if name_bytes == b"." || name_bytes == b".." {
|
if name_bytes == b"." || name_bytes == b".." {
|
||||||
continue;
|
continue;
|
||||||
@ -765,14 +755,14 @@ impl Iterator for ReadDir {
|
|||||||
|
|
||||||
#[cfg(not(target_os = "vita"))]
|
#[cfg(not(target_os = "vita"))]
|
||||||
let entry = dirent64_min {
|
let entry = dirent64_min {
|
||||||
d_ino: *offset_ptr!(entry_ptr, d_ino) as u64,
|
d_ino: *entry_field_ptr!(d_ino) as u64,
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
target_os = "illumos",
|
target_os = "illumos",
|
||||||
target_os = "aix",
|
target_os = "aix",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
)))]
|
)))]
|
||||||
d_type: *offset_ptr!(entry_ptr, d_type) as u8,
|
d_type: *entry_field_ptr!(d_type) as u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(target_os = "vita")]
|
#[cfg(target_os = "vita")]
|
||||||
|
Loading…
Reference in New Issue
Block a user