Skip to content

Commit 725d6bf

Browse files
committed
Move error up, early return
1 parent d6da4ab commit 725d6bf

File tree

1 file changed

+98
-95
lines changed

1 file changed

+98
-95
lines changed

src/shims/fs.rs

Lines changed: 98 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -871,60 +871,62 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
871871
let entry_ptr = this.force_ptr(this.read_scalar(entry_op)?.not_undef()?)?;
872872
let dirent64_layout = this.libc_ty_layout("dirent64")?;
873873

874-
if let Some(dir_iter) = this.machine.dir_handler.streams.get_mut(&dirp) {
875-
match dir_iter.next() {
876-
Some(Ok(dir_entry)) => {
877-
// Write into entry, write pointer to result, return 0 on success.
878-
// The name is written with write_os_str_to_c_str, while the rest of the
879-
// dirent64 struct is written using write_packed_immediates.
880-
881-
let name_offset = dirent64_layout.details.fields.offset(4);
882-
let name_ptr = entry_ptr.offset(name_offset, this)?;
883-
884-
let name_fits = this.write_os_str_to_c_str(&dir_entry.file_name(), Scalar::Ptr(name_ptr), 256)?;
885-
if !name_fits {
886-
panic!("A directory entry had a name too large to fit in libc::dirent64");
887-
}
874+
let dir_iter = this.machine.dir_handler.streams.get_mut(&dirp).ok_or_else(|| {
875+
err_unsup_format!("The DIR pointer passed to readdir64_r did not come from opendir")
876+
})?;
877+
match dir_iter.next() {
878+
Some(Ok(dir_entry)) => {
879+
// Write into entry, write pointer to result, return 0 on success.
880+
// The name is written with write_os_str_to_c_str, while the rest of the
881+
// dirent64 struct is written using write_packed_immediates.
882+
883+
let name_offset = dirent64_layout.details.fields.offset(4);
884+
let name_ptr = entry_ptr.offset(name_offset, this)?;
885+
886+
let file_name = dir_entry.file_name();
887+
let name_fits = this.write_os_str_to_c_str(&file_name, Scalar::Ptr(name_ptr), 256)?;
888+
if !name_fits {
889+
panic!("A directory entry had a name too large to fit in libc::dirent64");
890+
}
888891

889-
let entry_place = this.deref_operand(entry_op)?;
890-
let ino64_t_layout = this.libc_ty_layout("ino64_t")?;
891-
let off64_t_layout = this.libc_ty_layout("off64_t")?;
892-
let c_ushort_layout = this.libc_ty_layout("c_ushort")?;
893-
let c_uchar_layout = this.libc_ty_layout("c_uchar")?;
892+
let entry_place = this.deref_operand(entry_op)?;
893+
let ino64_t_layout = this.libc_ty_layout("ino64_t")?;
894+
let off64_t_layout = this.libc_ty_layout("off64_t")?;
895+
let c_ushort_layout = this.libc_ty_layout("c_ushort")?;
896+
let c_uchar_layout = this.libc_ty_layout("c_uchar")?;
894897

895-
#[cfg(unix)]
896-
let ino = std::os::unix::fs::DirEntryExt::ino(&dir_entry);
897-
#[cfg(not(unix))]
898-
let ino = 0;
898+
#[cfg(unix)]
899+
let ino = std::os::unix::fs::DirEntryExt::ino(&dir_entry);
900+
#[cfg(not(unix))]
901+
let ino = 0;
899902

900-
let file_type = this.file_type_to_d_type(dir_entry.file_type())? as u128;
903+
let file_type = this.file_type_to_d_type(dir_entry.file_type())? as u128;
901904

902-
let imms = [
903-
immty_from_uint_checked(ino, ino64_t_layout)?, // d_ino
904-
immty_from_uint_checked(0u128, off64_t_layout)?, // d_off
905-
immty_from_uint_checked(0u128, c_ushort_layout)?, // d_reclen
906-
immty_from_uint_checked(file_type, c_uchar_layout)?, // d_type
907-
];
908-
this.write_packed_immediates(entry_place, &imms)?;
905+
let imms = [
906+
immty_from_uint_checked(ino, ino64_t_layout)?, // d_ino
907+
immty_from_uint_checked(0u128, off64_t_layout)?, // d_off
908+
immty_from_uint_checked(0u128, c_ushort_layout)?, // d_reclen
909+
immty_from_uint_checked(file_type, c_uchar_layout)?, // d_type
910+
];
911+
this.write_packed_immediates(entry_place, &imms)?;
909912

910-
let result_place = this.deref_operand(result_op)?;
911-
this.write_scalar(this.read_scalar(entry_op)?, result_place.into())?;
913+
let result_place = this.deref_operand(result_op)?;
914+
this.write_scalar(this.read_scalar(entry_op)?, result_place.into())?;
912915

913-
Ok(0)
914-
}
916+
Ok(0)
917+
}
918+
None => {
919+
// end of stream: return 0, assign *result=NULL
920+
this.write_null(this.deref_operand(result_op)?.into())?;
921+
Ok(0)
922+
}
923+
Some(Err(e)) => match e.raw_os_error() {
924+
// return positive error number on error
925+
Some(error) => Ok(error),
915926
None => {
916-
// end of stream: return 0, assign *result=NULL
917-
this.write_null(this.deref_operand(result_op)?.into())?;
918-
Ok(0)
919-
}
920-
Some(Err(e)) => match e.raw_os_error() {
921-
// return positive error number on error
922-
Some(error) => Ok(error),
923-
None => throw_unsup_format!("The error {} couldn't be converted to a return value", e),
927+
throw_unsup_format!("The error {} couldn't be converted to a return value", e)
924928
}
925-
}
926-
} else {
927-
throw_unsup_format!("The DIR pointer passed to readdir64_r did not come from opendir")
929+
},
928930
}
929931
}
930932

@@ -943,64 +945,65 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
943945
let entry_ptr = this.force_ptr(this.read_scalar(entry_op)?.not_undef()?)?;
944946
let dirent_layout = this.libc_ty_layout("dirent")?;
945947

946-
if let Some(dir_iter) = this.machine.dir_handler.streams.get_mut(&dirp) {
947-
match dir_iter.next() {
948-
Some(Ok(dir_entry)) => {
949-
// Write into entry, write pointer to result, return 0 on success.
950-
// The name is written with write_os_str_to_c_str, while the rest of the
951-
// dirent struct is written using write_packed_Immediates.
952-
953-
let name_offset = dirent_layout.details.fields.offset(5);
954-
let name_ptr = entry_ptr.offset(name_offset, this)?;
948+
let dir_iter = this.machine.dir_handler.streams.get_mut(&dirp).ok_or_else(|| {
949+
err_unsup_format!("The DIR pointer passed to readdir_r did not come from opendir")
950+
})?;
951+
match dir_iter.next() {
952+
Some(Ok(dir_entry)) => {
953+
// Write into entry, write pointer to result, return 0 on success.
954+
// The name is written with write_os_str_to_c_str, while the rest of the
955+
// dirent struct is written using write_packed_Immediates.
956+
957+
let name_offset = dirent_layout.details.fields.offset(5);
958+
let name_ptr = entry_ptr.offset(name_offset, this)?;
959+
960+
let file_name = dir_entry.file_name();
961+
let name_fits = this.write_os_str_to_c_str(&file_name, Scalar::Ptr(name_ptr), 1024)?;
962+
if !name_fits {
963+
panic!("A directory entry had a name too large to fit in libc::dirent");
964+
}
955965

956-
let file_name = dir_entry.file_name();
957-
let name_fits = this.write_os_str_to_c_str(&file_name, Scalar::Ptr(name_ptr), 1024)?;
958-
if !name_fits {
959-
panic!("A directory entry had a name too large to fit in libc::dirent");
960-
}
966+
let entry_place = this.deref_operand(entry_op)?;
967+
let ino_t_layout = this.libc_ty_layout("ino_t")?;
968+
let off_t_layout = this.libc_ty_layout("off_t")?;
969+
let c_ushort_layout = this.libc_ty_layout("c_ushort")?;
970+
let c_uchar_layout = this.libc_ty_layout("c_uchar")?;
961971

962-
let entry_place = this.deref_operand(entry_op)?;
963-
let ino_t_layout = this.libc_ty_layout("ino_t")?;
964-
let off_t_layout = this.libc_ty_layout("off_t")?;
965-
let c_ushort_layout = this.libc_ty_layout("c_ushort")?;
966-
let c_uchar_layout = this.libc_ty_layout("c_uchar")?;
972+
#[cfg(unix)]
973+
let ino = std::os::unix::fs::DirEntryExt::ino(&dir_entry);
974+
#[cfg(not(unix))]
975+
let ino = 0;
967976

968-
#[cfg(unix)]
969-
let ino = std::os::unix::fs::DirEntryExt::ino(&dir_entry);
970-
#[cfg(not(unix))]
971-
let ino = 0;
977+
let file_name_len = this.os_str_length_as_c_str(&file_name)? as u128;
972978

973-
let file_name_len = this.os_str_length_as_c_str(&file_name)? as u128;
979+
let file_type = this.file_type_to_d_type(dir_entry.file_type())? as u128;
974980

975-
let file_type = this.file_type_to_d_type(dir_entry.file_type())? as u128;
981+
let imms = [
982+
immty_from_uint_checked(ino, ino_t_layout)?, // d_ino
983+
immty_from_uint_checked(0u128, off_t_layout)?, // d_seekoff
984+
immty_from_uint_checked(0u128, c_ushort_layout)?, // d_reclen
985+
immty_from_uint_checked(file_name_len, c_ushort_layout)?, // d_namlen
986+
immty_from_uint_checked(file_type, c_uchar_layout)?, // d_type
987+
];
988+
this.write_packed_immediates(entry_place, &imms)?;
976989

977-
let imms = [
978-
immty_from_uint_checked(ino, ino_t_layout)?, // d_ino
979-
immty_from_uint_checked(0u128, off_t_layout)?, // d_seekoff
980-
immty_from_uint_checked(0u128, c_ushort_layout)?, // d_reclen
981-
immty_from_uint_checked(file_name_len, c_ushort_layout)?, // d_namlen
982-
immty_from_uint_checked(file_type, c_uchar_layout)?, // d_type
983-
];
984-
this.write_packed_immediates(entry_place, &imms)?;
990+
let result_place = this.deref_operand(result_op)?;
991+
this.write_scalar(this.read_scalar(entry_op)?, result_place.into())?;
985992

986-
let result_place = this.deref_operand(result_op)?;
987-
this.write_scalar(this.read_scalar(entry_op)?, result_place.into())?;
988-
989-
Ok(0)
990-
}
993+
Ok(0)
994+
}
995+
None => {
996+
// end of stream: return 0, assign *result=NULL
997+
this.write_null(this.deref_operand(result_op)?.into())?;
998+
Ok(0)
999+
}
1000+
Some(Err(e)) => match e.raw_os_error() {
1001+
// return positive error number on error
1002+
Some(error) => Ok(error),
9911003
None => {
992-
// end of stream: return 0, assign *result=NULL
993-
this.write_null(this.deref_operand(result_op)?.into())?;
994-
Ok(0)
1004+
throw_unsup_format!("The error {} couldn't be converted to a return value", e)
9951005
}
996-
Some(Err(e)) => match e.raw_os_error() {
997-
// return positive error number on error
998-
Some(error) => Ok(error),
999-
None => throw_unsup_format!("The error {} couldn't be converted to a return value", e),
1000-
}
1001-
}
1002-
} else {
1003-
throw_unsup_format!("The DIR pointer passed to readdir_r did not come from opendir")
1006+
},
10041007
}
10051008
}
10061009

0 commit comments

Comments
 (0)