Follow-up to reviews from RalfJung

1. Fix 'fn convert_path_separator' in src/shims/os_str.rs
2. Fix 'fn set_last_error_from_io_error' in src/helpers.rs
3. Minor comment fix for 'fn SetCurrentDirectoryW' in src/shims/env.rs
This commit is contained in:
JOE1994 2020-03-29 09:46:13 -04:00
parent 1141b21e50
commit fe9ecb50d1
3 changed files with 19 additions and 14 deletions

View File

@ -414,6 +414,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
use std::io::ErrorKind::*;
let this = self.eval_context_mut();
let target = &this.tcx.sess.target.target;
let target_os = &target.target_os;
let last_error = if target.options.target_family == Some("unix".to_owned()) {
this.eval_libc(match e.kind() {
ConnectionRefused => "ECONNREFUSED",
@ -434,15 +435,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
throw_unsup_format!("io error {} cannot be transformed into a raw os error", e)
}
})?
} else {
} else if target_os == "windows" {
// FIXME: we have to finish implementing the Windows equivalent of this.
this.eval_windows(match e.kind() {
NotFound => "ERROR_FILE_NOT_FOUND",
_ => throw_unsup_format!(
"setting the last OS error from an io::Error is yet unsupported for {}.",
target.target_os
)
_ => throw_unsup_format!("io error {} cannot be transformed into a raw os error", e)
})?
} else {
throw_unsup_format!("setting the last OS error from an io::Error is unsupported for {}.", target_os)
};
this.set_last_error(last_error)
}

View File

@ -357,7 +357,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn SetCurrentDirectoryW (
&mut self,
path_op: OpTy<'tcx, Tag> // LPCTSTR
) -> InterpResult<'tcx, i32> { // Returns BOOL(i32 in Windows)
) -> InterpResult<'tcx, i32> { // Returns BOOL (i32 in Windows)
let this = self.eval_context_mut();
this.assert_target_os("windows", "SetCurrentDirectoryW");

View File

@ -179,7 +179,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_ref();
let os_str: &'a OsStr = this.read_os_str_from_c_str(scalar)?;
Ok(match convert_path_separator(os_str, &this.tcx.sess.target.target.target_os) {
Ok(match convert_path_separator(os_str, &this.tcx.sess.target.target.target_os, false) {
Cow::Borrowed(x) => Cow::Borrowed(Path::new(x)),
Cow::Owned(y) => Cow::Owned(PathBuf::from(y)),
})
@ -190,7 +190,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_ref();
let os_str: OsString = this.read_os_str_from_wide_str(scalar)?;
Ok(PathBuf::from(&convert_path_separator(&os_str, &this.tcx.sess.target.target.target_os)))
Ok(PathBuf::from(&convert_path_separator(&os_str, &this.tcx.sess.target.target.target_os, false)))
}
/// Write a Path to the machine memory (as a null-terminated sequence of bytes),
@ -202,7 +202,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
size: u64,
) -> InterpResult<'tcx, (bool, u64)> {
let this = self.eval_context_mut();
let os_str = convert_path_separator(path.as_os_str(), &this.tcx.sess.target.target.target_os);
let os_str = convert_path_separator(path.as_os_str(), &this.tcx.sess.target.target.target_os, true);
this.write_os_str_to_c_str(&os_str, scalar, size)
}
@ -215,35 +215,40 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
size: u64,
) -> InterpResult<'tcx, (bool, u64)> {
let this = self.eval_context_mut();
let os_str = convert_path_separator(path.as_os_str(), &this.tcx.sess.target.target.target_os);
let os_str = convert_path_separator(path.as_os_str(), &this.tcx.sess.target.target.target_os, true);
this.write_os_str_to_wide_str(&os_str, scalar, size)
}
}
/// Perform path separator conversion if needed.
/// if direction == true, Convert from 'host' to 'target'.
/// if direction == false, Convert from 'target' to 'host'.
fn convert_path_separator<'a>(
os_str: &'a OsStr,
target_os: &str,
direction: bool,
) -> Cow<'a, OsStr> {
#[cfg(windows)]
return if target_os == "windows" {
// Windows-on-Windows, all fine.
Cow::Borrowed(os_str)
} else {
// Unix target, Windows host. Need to convert host '\\' to target '/'.
// Unix target, Windows host.
let (from, to) = if direction { ('\\', '/') } else { ('/', '\\') };
let converted = os_str
.encode_wide()
.map(|wchar| if wchar == '\\' as u16 { '/' as u16 } else { wchar })
.map(|wchar| if wchar == from as u16 { to as u16 } else { wchar })
.collect::<Vec<_>>();
Cow::Owned(OsString::from_wide(&converted))
};
#[cfg(unix)]
return if target_os == "windows" {
// Windows target, Unix host. Need to convert host '/' to target '\'.
// Windows target, Unix host.
let (from, to) = if direction { ('/', '\\') } else { ('\\', '/') };
let converted = os_str
.as_bytes()
.iter()
.map(|&wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar })
.map(|&wchar| if wchar == from as u8 { to as u8 } else { wchar })
.collect::<Vec<_>>();
Cow::Owned(OsString::from_vec(converted))
} else {