Pass through isatty if the host is also unix
This commit is contained in:
parent
86911fd8f6
commit
2f84cb34c1
@ -440,12 +440,8 @@ fn emulate_foreign_item_by_name(
|
|||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
"isatty" => {
|
"isatty" => {
|
||||||
let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
this.read_scalar(fd)?.to_i32()?;
|
let result = this.isatty(fd)?;
|
||||||
// "returns 1 if fd is an open file descriptor referring to a terminal; otherwise 0 is returned, and errno is set to indicate the error"
|
this.write_scalar(Scalar::from_i32(result), dest)?;
|
||||||
// FIXME: we just say nothing is a terminal.
|
|
||||||
let enotty = this.eval_libc("ENOTTY")?;
|
|
||||||
this.set_last_error(enotty)?;
|
|
||||||
this.write_null(dest)?;
|
|
||||||
}
|
}
|
||||||
"pthread_atfork" => {
|
"pthread_atfork" => {
|
||||||
let [prepare, parent, child] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [prepare, parent, child] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
|
@ -50,6 +50,9 @@ fn close<'tcx>(
|
|||||||
) -> InterpResult<'tcx, io::Result<i32>>;
|
) -> InterpResult<'tcx, io::Result<i32>>;
|
||||||
|
|
||||||
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>>;
|
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>>;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn as_unix_host_fd(&self) -> Option<i32>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileDescriptor for FileHandle {
|
impl FileDescriptor for FileHandle {
|
||||||
@ -114,6 +117,12 @@ fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
|||||||
let duplicated = self.file.try_clone()?;
|
let duplicated = self.file.try_clone()?;
|
||||||
Ok(Box::new(FileHandle { file: duplicated, writable: self.writable }))
|
Ok(Box::new(FileHandle { file: duplicated, writable: self.writable }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn as_unix_host_fd(&self) -> Option<i32> {
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
Some(self.file.as_raw_fd())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileDescriptor for io::Stdin {
|
impl FileDescriptor for io::Stdin {
|
||||||
@ -159,6 +168,11 @@ fn close<'tcx>(
|
|||||||
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
||||||
Ok(Box::new(io::stdin()))
|
Ok(Box::new(io::stdin()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn as_unix_host_fd(&self) -> Option<i32> {
|
||||||
|
Some(libc::STDIN_FILENO)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileDescriptor for io::Stdout {
|
impl FileDescriptor for io::Stdout {
|
||||||
@ -209,6 +223,11 @@ fn close<'tcx>(
|
|||||||
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
||||||
Ok(Box::new(io::stdout()))
|
Ok(Box::new(io::stdout()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn as_unix_host_fd(&self) -> Option<i32> {
|
||||||
|
Some(libc::STDOUT_FILENO)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileDescriptor for io::Stderr {
|
impl FileDescriptor for io::Stderr {
|
||||||
@ -252,6 +271,11 @@ fn close<'tcx>(
|
|||||||
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
||||||
Ok(Box::new(io::stderr()))
|
Ok(Box::new(io::stderr()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn as_unix_host_fd(&self) -> Option<i32> {
|
||||||
|
Some(libc::STDERR_FILENO)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -297,6 +321,11 @@ fn close<'tcx>(
|
|||||||
fn dup<'tcx>(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
fn dup<'tcx>(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
|
||||||
Ok(Box::new(DummyOutput))
|
Ok(Box::new(DummyOutput))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn as_unix_host_fd(&self) -> Option<i32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -1660,6 +1689,38 @@ fn readlink(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(not(unix), allow(unused))]
|
||||||
|
fn isatty(&mut self, miri_fd: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
|
||||||
|
let this = self.eval_context_mut();
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
let miri_fd = this.read_scalar(miri_fd)?.to_i32()?;
|
||||||
|
if let Some(host_fd) =
|
||||||
|
this.machine.file_handler.handles.get(&miri_fd).and_then(|fd| fd.as_unix_host_fd())
|
||||||
|
{
|
||||||
|
// "returns 1 if fd is an open file descriptor referring to a terminal;
|
||||||
|
// otherwise 0 is returned, and errno is set to indicate the error"
|
||||||
|
// SAFETY: isatty has no preconditions
|
||||||
|
let is_tty = unsafe { libc::isatty(host_fd) };
|
||||||
|
if is_tty == 0 {
|
||||||
|
let errno = std::io::Error::last_os_error()
|
||||||
|
.raw_os_error()
|
||||||
|
.map(Scalar::from_i32)
|
||||||
|
.unwrap();
|
||||||
|
this.set_last_error(errno)?;
|
||||||
|
}
|
||||||
|
return Ok(is_tty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We are attemping to use a Unix interface on a non-Unix platform, or we are on a Unix
|
||||||
|
// platform and the passed file descriptor is not open.
|
||||||
|
// FIXME: It should be possible to emulate this at least on Windows by using
|
||||||
|
// GetConsoleMode.
|
||||||
|
let enotty = this.eval_libc("ENOTTY")?;
|
||||||
|
this.set_last_error(enotty)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts the number of seconds and nanoseconds elapsed between `time` and the unix epoch when
|
/// Extracts the number of seconds and nanoseconds elapsed between `time` and the unix epoch when
|
||||||
|
Loading…
Reference in New Issue
Block a user