Skip to content

Commit 5f54876

Browse files
readdir for freebsd and macos
1 parent 49757dd commit 5f54876

File tree

5 files changed

+70
-15
lines changed

5 files changed

+70
-15
lines changed

src/shims/unix/freebsd/foreign_items.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
159159
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
160160
this.write_scalar(result, dest)?;
161161
}
162-
162+
"readdir" | "readdir@FBSD_1.0" => {
163+
let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
164+
let result = this.readdir64("dirent", dirp)?;
165+
this.write_scalar(result, dest)?;
166+
}
163167
// Miscellaneous
164168
"__error" => {
165169
let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;

src/shims/unix/fs.rs

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -900,14 +900,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
900900
}
901901
}
902902

903-
fn linux_solarish_readdir64(
904-
&mut self,
905-
dirent_type: &str,
906-
dirp_op: &OpTy<'tcx>,
907-
) -> InterpResult<'tcx, Scalar> {
903+
fn readdir64(&mut self, dirent_type: &str, dirp_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
908904
let this = self.eval_context_mut();
909905

910-
if !matches!(&*this.tcx.sess.target.os, "linux" | "solaris" | "illumos") {
906+
if !matches!(
907+
&*this.tcx.sess.target.os,
908+
"linux" | "solaris" | "illumos" | "macos" | "freebsd"
909+
) {
911910
panic!("`linux_solaris_readdir64` should not be called on {}", this.tcx.sess.target.os);
912911
}
913912

@@ -947,6 +946,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
947946
// pub d_reclen: c_ushort,
948947
// pub d_name: [c_char; 3],
949948
// }
949+
//
950+
// On FreeBSD:
951+
// pub struct dirent{
952+
// pub d_fileno: uint32_t,
953+
// pub d_reclen: uint16_t,
954+
// pub d_type: uint8_t,
955+
// pub d_namlen: uint8_t,
956+
// pub d_name: [c_char; 256]
957+
// }
958+
//
959+
// On Macos:
960+
// pub struct dirent {
961+
// pub d_ino: u64,
962+
// pub d_seekoff: u64,
963+
// pub d_reclen: u16,
964+
// pub d_namlen: u16,
965+
// pub d_type: u8,
966+
// pub d_name: [c_char; 1024],
967+
// }
950968

951969
let mut name = dir_entry.file_name(); // not a Path as there are no separators!
952970
name.push("\0"); // Add a NUL terminator
@@ -966,6 +984,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
966984
AllocInit::Uninit,
967985
)?;
968986
let entry: Pointer = entry.into();
987+
let entry_place = &this.ptr_to_mplace(entry, dirent_layout);
969988

970989
// If the host is a Unix system, fill in the inode number with its real value.
971990
// If not, use 0 as a fallback value.
@@ -974,15 +993,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
974993
#[cfg(not(unix))]
975994
let ino = 0u64;
976995

977-
let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
996+
// Write common fields
997+
let ino_name =
998+
if this.tcx.sess.target.os == "freebsd" { "d_fileno" } else { "d_ino " };
978999
this.write_int_fields_named(
979-
&[("d_ino", ino.into()), ("d_off", 0), ("d_reclen", size.into())],
980-
&this.ptr_to_mplace(entry, dirent_layout),
1000+
&[(ino_name, ino.into()), ("d_reclen", size.into())],
1001+
entry_place,
9811002
)?;
9821003

983-
if let Some(d_type) = this
984-
.try_project_field_named(&this.ptr_to_mplace(entry, dirent_layout), "d_type")?
985-
{
1004+
// Hanlde os specific fields
1005+
match &*this.tcx.sess.target.os {
1006+
"macos" => {
1007+
this.write_int_fields_named(
1008+
&[
1009+
("d_seekoff", 0),
1010+
("d_namlen", (name_len - 1).into()), // Zero Byte not included
1011+
],
1012+
entry_place,
1013+
)?;
1014+
}
1015+
"freebsd" => {
1016+
this.write_int_fields_named(
1017+
&[
1018+
("d_off", 0),
1019+
("d_namlen", (name_len - 1).into()), // Zero Byte not included
1020+
],
1021+
entry_place,
1022+
)?;
1023+
}
1024+
"linux" | "solaris" | "illumos" => {
1025+
this.write_int_fields_named(&[("d_off", 0)], entry_place)?;
1026+
}
1027+
_ => unreachable!(),
1028+
}
1029+
1030+
let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
1031+
if let Some(d_type) = this.try_project_field_named(entry_place, "d_type")? {
9861032
this.write_int(file_type, &d_type)?;
9871033
}
9881034

src/shims/unix/linux/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3838
// File related shims
3939
"readdir64" => {
4040
let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
41-
let result = this.linux_solarish_readdir64("dirent64", dirp)?;
41+
let result = this.readdir64("dirent64", dirp)?;
4242
this.write_scalar(result, dest)?;
4343
}
4444
"sync_file_range" => {

src/shims/unix/macos/foreign_items.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
7272
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
7373
this.write_scalar(result, dest)?;
7474
}
75+
"readdir" | "readdir$INODE64" => {
76+
let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
77+
let result = this.readdir64("dirent", dirp)?;
78+
this.write_scalar(result, dest)?;
79+
}
7580
"realpath$DARWIN_EXTSN" => {
7681
let [path, resolved_path] =
7782
this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;

src/shims/unix/solarish/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
106106
}
107107
"readdir" => {
108108
let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
109-
let result = this.linux_solarish_readdir64("dirent", dirp)?;
109+
let result = this.readdir64("dirent", dirp)?;
110110
this.write_scalar(result, dest)?;
111111
}
112112

0 commit comments

Comments
 (0)