Auto merge of #3632 - RalfJung:readdir, r=RalfJung · rust-lang/rust@8e861c6

@@ -990,7 +990,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

990990

// The name is written with write_os_str_to_c_str, while the rest of the

991991

// dirent struct is written using write_int_fields.

992992993-

// For reference:

993+

// For reference, on macOS this looks like:

994994

// pub struct dirent {

995995

// pub d_ino: u64,

996996

// pub d_seekoff: u64,

@@ -1025,40 +1025,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

1025102510261026

let file_type = this.file_type_to_d_type(dir_entry.file_type())?;

102710271028-

// macOS offset field is d_seekoff

1029-

if this.projectable_has_field(&entry_place, "d_seekoff") {

1030-

this.write_int_fields_named(

1031-

&[

1032-

("d_ino", ino.into()),

1033-

("d_seekoff", 0),

1034-

("d_reclen", 0),

1035-

("d_namlen", file_name_len.into()),

1036-

("d_type", file_type.into()),

1037-

],

1038-

&entry_place,

1039-

)?;

1040-

} else if this.projectable_has_field(&entry_place, "d_off") {

1041-

// freebsd 12 and onwards had added the d_off field

1042-

this.write_int_fields_named(

1043-

&[

1044-

("d_fileno", ino.into()),

1045-

("d_off", 0),

1046-

("d_reclen", 0),

1047-

("d_type", file_type.into()),

1048-

("d_namlen", file_name_len.into()),

1049-

],

1050-

&entry_place,

1051-

)?;

1052-

} else {

1053-

this.write_int_fields_named(

1054-

&[

1055-

("d_fileno", ino.into()),

1056-

("d_reclen", 0),

1057-

("d_type", file_type.into()),

1058-

("d_namlen", file_name_len.into()),

1059-

],

1060-

&entry_place,

1061-

)?;

1028+

// Common fields.

1029+

this.write_int_fields_named(

1030+

&[

1031+

("d_reclen", 0),

1032+

("d_namlen", file_name_len.into()),

1033+

("d_type", file_type.into()),

1034+

],

1035+

&entry_place,

1036+

)?;

1037+

// Special fields.

1038+

match &*this.tcx.sess.target.os {

1039+

"macos" => {

1040+

#[rustfmt::skip]

1041+

this.write_int_fields_named(

1042+

&[

1043+

("d_ino", ino.into()),

1044+

("d_seekoff", 0),

1045+

],

1046+

&entry_place,

1047+

)?;

1048+

}

1049+

"freebsd" => {

1050+

this.write_int(ino, &this.project_field_named(&entry_place, "d_fileno")?)?;

1051+

// `d_off` only exists on FreeBSD 12+, but we support v11 as well.

1052+

// `libc` uses a build script to determine which version of the API to use,

1053+

// and cross-builds always end up using v11.

1054+

// To support both v11 and v12+, we dynamically check whether the field exists.

1055+

if this.projectable_has_field(&entry_place, "d_off") {

1056+

this.write_int(0, &this.project_field_named(&entry_place, "d_off")?)?;

1057+

}

1058+

}

1059+

_ => unreachable!(),

10621060

}

1063106110641062

let result_place = this.deref_pointer(result_op)?;