Add default impls for FileDescriptor methods

This commit is contained in:
Oli Scherer 2022-07-25 17:55:45 +00:00
parent b938529fb8
commit cd6b723bb6
3 changed files with 41 additions and 120 deletions

View File

@ -24,38 +24,56 @@ struct FileHandle {
} }
trait FileDescriptor: std::fmt::Debug { trait FileDescriptor: std::fmt::Debug {
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle>; fn name(&self) -> &'static str;
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> {
throw_unsup_format!("{} cannot be used as FileHandle", self.name());
}
fn read<'tcx>( fn read<'tcx>(
&mut self, &mut self,
communicate_allowed: bool, _communicate_allowed: bool,
bytes: &mut [u8], _bytes: &mut [u8],
) -> InterpResult<'tcx, io::Result<usize>>; ) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot read from {}", self.name());
}
fn write<'tcx>( fn write<'tcx>(
&self, &self,
communicate_allowed: bool, _communicate_allowed: bool,
bytes: &[u8], _bytes: &[u8],
) -> InterpResult<'tcx, io::Result<usize>>; ) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot write to {}", self.name());
}
fn seek<'tcx>( fn seek<'tcx>(
&mut self, &mut self,
communicate_allowed: bool, _communicate_allowed: bool,
offset: SeekFrom, _offset: SeekFrom,
) -> InterpResult<'tcx, io::Result<u64>>; ) -> InterpResult<'tcx, io::Result<u64>> {
throw_unsup_format!("cannot seek on {}", self.name());
}
fn close<'tcx>( fn close<'tcx>(
self: Box<Self>, self: Box<Self>,
_communicate_allowed: bool, _communicate_allowed: bool,
) -> InterpResult<'tcx, io::Result<i32>>; ) -> InterpResult<'tcx, io::Result<i32>> {
throw_unsup_format!("cannot close {}", self.name());
}
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>>; fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>>;
#[cfg(unix)] #[cfg(unix)]
fn as_unix_host_fd(&self) -> Option<i32>; fn as_unix_host_fd(&self) -> Option<i32> {
None
}
} }
impl FileDescriptor for FileHandle { impl FileDescriptor for FileHandle {
fn name(&self) -> &'static str {
"FILE"
}
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> { fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> {
Ok(self) Ok(self)
} }
@ -126,8 +144,8 @@ impl FileDescriptor for FileHandle {
} }
impl FileDescriptor for io::Stdin { impl FileDescriptor for io::Stdin {
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> { fn name(&self) -> &'static str {
throw_unsup_format!("stdin cannot be used as FileHandle"); "stdin"
} }
fn read<'tcx>( fn read<'tcx>(
@ -142,29 +160,6 @@ impl FileDescriptor for io::Stdin {
Ok(Read::read(self, bytes)) Ok(Read::read(self, bytes))
} }
fn write<'tcx>(
&self,
_communicate_allowed: bool,
_bytes: &[u8],
) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot write to stdin");
}
fn seek<'tcx>(
&mut self,
_communicate_allowed: bool,
_offset: SeekFrom,
) -> InterpResult<'tcx, io::Result<u64>> {
throw_unsup_format!("cannot seek on stdin");
}
fn close<'tcx>(
self: Box<Self>,
_communicate_allowed: bool,
) -> InterpResult<'tcx, io::Result<i32>> {
throw_unsup_format!("stdin cannot be closed");
}
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()))
} }
@ -176,16 +171,8 @@ impl FileDescriptor for io::Stdin {
} }
impl FileDescriptor for io::Stdout { impl FileDescriptor for io::Stdout {
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> { fn name(&self) -> &'static str {
throw_unsup_format!("stdout cannot be used as FileHandle"); "stdout"
}
fn read<'tcx>(
&mut self,
_communicate_allowed: bool,
_bytes: &mut [u8],
) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot read from stdout");
} }
fn write<'tcx>( fn write<'tcx>(
@ -205,21 +192,6 @@ impl FileDescriptor for io::Stdout {
Ok(result) Ok(result)
} }
fn seek<'tcx>(
&mut self,
_communicate_allowed: bool,
_offset: SeekFrom,
) -> InterpResult<'tcx, io::Result<u64>> {
throw_unsup_format!("cannot seek on stdout");
}
fn close<'tcx>(
self: Box<Self>,
_communicate_allowed: bool,
) -> InterpResult<'tcx, io::Result<i32>> {
throw_unsup_format!("stdout cannot be closed");
}
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()))
} }
@ -231,16 +203,8 @@ impl FileDescriptor for io::Stdout {
} }
impl FileDescriptor for io::Stderr { impl FileDescriptor for io::Stderr {
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> { fn name(&self) -> &'static str {
throw_unsup_format!("stderr cannot be used as FileHandle"); "stderr"
}
fn read<'tcx>(
&mut self,
_communicate_allowed: bool,
_bytes: &mut [u8],
) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot read from stderr");
} }
fn write<'tcx>( fn write<'tcx>(
@ -253,21 +217,6 @@ impl FileDescriptor for io::Stderr {
Ok(Write::write(&mut { self }, bytes)) Ok(Write::write(&mut { self }, bytes))
} }
fn seek<'tcx>(
&mut self,
_communicate_allowed: bool,
_offset: SeekFrom,
) -> InterpResult<'tcx, io::Result<u64>> {
throw_unsup_format!("cannot seek on stderr");
}
fn close<'tcx>(
self: Box<Self>,
_communicate_allowed: bool,
) -> InterpResult<'tcx, io::Result<i32>> {
throw_unsup_format!("stderr cannot be closed");
}
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()))
} }
@ -282,16 +231,8 @@ impl FileDescriptor for io::Stderr {
struct DummyOutput; struct DummyOutput;
impl FileDescriptor for DummyOutput { impl FileDescriptor for DummyOutput {
fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> { fn name(&self) -> &'static str {
throw_unsup_format!("stderr and stdout cannot be used as FileHandle"); "stderr and stdout"
}
fn read<'tcx>(
&mut self,
_communicate_allowed: bool,
_bytes: &mut [u8],
) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot read from stderr or stdout");
} }
fn write<'tcx>( fn write<'tcx>(
@ -303,29 +244,9 @@ impl FileDescriptor for DummyOutput {
Ok(Ok(bytes.len())) Ok(Ok(bytes.len()))
} }
fn seek<'tcx>(
&mut self,
_communicate_allowed: bool,
_offset: SeekFrom,
) -> InterpResult<'tcx, io::Result<u64>> {
throw_unsup_format!("cannot seek on stderr or stdout");
}
fn close<'tcx>(
self: Box<Self>,
_communicate_allowed: bool,
) -> InterpResult<'tcx, io::Result<i32>> {
throw_unsup_format!("stderr and stdout cannot be closed");
}
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)]

View File

@ -7,6 +7,6 @@
fn main() { fn main() {
unsafe { unsafe {
libc::close(1); //~ ERROR: stdout cannot be closed libc::close(1); //~ ERROR: cannot close stdout
} }
} }

View File

@ -1,8 +1,8 @@
error: unsupported operation: stdout cannot be closed error: unsupported operation: cannot close stdout
--> $DIR/close_stdout.rs:LL:CC --> $DIR/close_stdout.rs:LL:CC
| |
LL | libc::close(1); LL | libc::close(1);
| ^^^^^^^^^^^^^^ stdout cannot be closed | ^^^^^^^^^^^^^^ cannot close stdout
| |
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
= note: backtrace: = note: backtrace: