diff options
| author | Ralf Jung <post@ralfj.de> | 2024-05-26 16:31:38 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-05-26 17:20:28 +0200 |
| commit | 350f5c88dbe97605d9f4e0cac037a0b9751d06ef (patch) | |
| tree | 8b08111c63c2a01897dcf2854c88781fdc770f02 | |
| parent | 331bb3f10d755f4c7fdf29b21d7a957a76f76c1a (diff) | |
| download | rust-350f5c88dbe97605d9f4e0cac037a0b9751d06ef.tar.gz rust-350f5c88dbe97605d9f4e0cac037a0b9751d06ef.zip | |
unix/fs: a bit of cleanup in macos_fbsd_readdir_r
| -rw-r--r-- | src/tools/miri/src/shims/unix/fs.rs | 68 |
1 files changed, 33 insertions, 35 deletions
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 82bc49536b0..5b0c1b2bafe 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -990,7 +990,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // The name is written with write_os_str_to_c_str, while the rest of the // dirent struct is written using write_int_fields. - // For reference: + // For reference, on macOS this looks like: // pub struct dirent { // pub d_ino: u64, // pub d_seekoff: u64, @@ -1025,40 +1025,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let file_type = this.file_type_to_d_type(dir_entry.file_type())?; - // macOS offset field is d_seekoff - if this.projectable_has_field(&entry_place, "d_seekoff") { - this.write_int_fields_named( - &[ - ("d_ino", ino.into()), - ("d_seekoff", 0), - ("d_reclen", 0), - ("d_namlen", file_name_len.into()), - ("d_type", file_type.into()), - ], - &entry_place, - )?; - } else if this.projectable_has_field(&entry_place, "d_off") { - // freebsd 12 and onwards had added the d_off field - this.write_int_fields_named( - &[ - ("d_fileno", ino.into()), - ("d_off", 0), - ("d_reclen", 0), - ("d_type", file_type.into()), - ("d_namlen", file_name_len.into()), - ], - &entry_place, - )?; - } else { - this.write_int_fields_named( - &[ - ("d_fileno", ino.into()), - ("d_reclen", 0), - ("d_type", file_type.into()), - ("d_namlen", file_name_len.into()), - ], - &entry_place, - )?; + // Common fields. + this.write_int_fields_named( + &[ + ("d_reclen", 0), + ("d_namlen", file_name_len.into()), + ("d_type", file_type.into()), + ], + &entry_place, + )?; + // Special fields. + match &*this.tcx.sess.target.os { + "macos" => { + #[rustfmt::skip] + this.write_int_fields_named( + &[ + ("d_ino", ino.into()), + ("d_seekoff", 0), + ], + &entry_place, + )?; + } + "freebsd" => { + this.write_int(ino, &this.project_field_named(&entry_place, "d_fileno")?)?; + // `d_off` only exists on FreeBSD 12+, but we support v11 as well. + // `libc` uses a build script to determine which version of the API to use, + // and cross-builds always end up using v11. + // To support both v11 and v12+, we dynamically check whether the field exists. + if this.projectable_has_field(&entry_place, "d_off") { + this.write_int(0, &this.project_field_named(&entry_place, "d_off")?)?; + } + } + _ => unreachable!(), } let result_place = this.deref_pointer(result_op)?; |
