Skip to content

Commit

Permalink
Merge #732
Browse files Browse the repository at this point in the history
732: Remove fd_entry lookup on stdin,out,err for wasi::poll_oneoff r=MarkMcCaskey a=MarkMcCaskey



Co-authored-by: Mark McCaskey <mark@wasmer.io>
  • Loading branch information
bors[bot] and Mark McCaskey authored Aug 29, 2019
2 parents 5205ada + 7027d7b commit 569d038
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 46 deletions.
3 changes: 3 additions & 0 deletions lib/wasi-tests/wasitests/poll_oneoff.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
__wasi_event_t { userdata: 1193046, error: 0, type_: 1, u: __wasi_event_u { __wasi_event_fd_readwrite_t { nbytes: 2259, flags: 0 } } }
[__wasi_event_t { userdata: 1193046, error: 0, type_: 1, u: __wasi_event_u { __wasi_event_fd_readwrite_t { nbytes: 2259, flags: 0 } } }, __wasi_event_t { userdata: 1193046, error: 0, type_: 2, u: __wasi_event_u { __wasi_event_fd_readwrite_t { nbytes: 1234, flags: 0 } } }]
Stdin: OK
Stdout: OK
Stderr: OK
35 changes: 35 additions & 0 deletions lib/wasi-tests/wasitests/poll_oneoff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,46 @@ fn main() {
poll(fds.as_slice(), &[true, false], &[false, true]).expect("subsequent polls");
}
println!("{:?}", result);

/// stdin, stdout, stderr checking
let fds = vec![std::io::stdin().as_raw_fd()];
print!("Stdin: ");
println!(
"{}",
if poll(fds.as_slice(), &[true], &[false]).is_ok() {
"OK"
} else {
"ERROR"
}
);
let fds = vec![std::io::stdout().as_raw_fd()];
print!("Stdout: ");
println!(
"{}",
if poll(fds.as_slice(), &[false], &[true]).is_ok() {
"OK"
} else {
"ERROR"
}
);
let fds = vec![std::io::stderr().as_raw_fd()];
print!("Stderr: ");
println!(
"{}",
if poll(fds.as_slice(), &[false], &[true]).is_ok() {
"OK"
} else {
"ERROR"
}
);
}
#[cfg(not(target_os = "wasi"))]
{
println!("{}", "__wasi_event_t { userdata: 1193046, error: 0, type_: 1, u: __wasi_event_u { __wasi_event_fd_readwrite_t { nbytes: 2259, flags: 0 } } }");
println!("{}", "[__wasi_event_t { userdata: 1193046, error: 0, type_: 1, u: __wasi_event_u { __wasi_event_fd_readwrite_t { nbytes: 2259, flags: 0 } } }, __wasi_event_t { userdata: 1193046, error: 0, type_: 2, u: __wasi_event_u { __wasi_event_fd_readwrite_t { nbytes: 1234, flags: 0 } } }]");
println!("Stdin: OK");
println!("Stdout: OK");
println!("Stderr: OK");
}
}

Expand Down
Binary file modified lib/wasi-tests/wasitests/poll_oneoff.wasm
Binary file not shown.
82 changes: 42 additions & 40 deletions lib/wasi/src/state/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,26 +452,11 @@ impl WasiFile for HostFile {
std::fs::rename(&self.host_path, new_name).map_err(Into::into)
}

#[cfg(unix)]
fn bytes_available(&self) -> Result<usize, WasiFsError> {
use std::os::unix::io::AsRawFd;
let host_fd = self.inner.as_raw_fd();

let mut bytes_found = 0 as libc::c_int;
let result = unsafe { libc::ioctl(host_fd, libc::FIONREAD, &mut bytes_found) };

match result {
// success
0 => Ok(bytes_found.try_into().unwrap_or(0)),
libc::EBADF => Err(WasiFsError::InvalidFd),
libc::EFAULT => Err(WasiFsError::InvalidData),
libc::EINVAL => Err(WasiFsError::InvalidInput),
_ => Err(WasiFsError::IOError),
}
}
#[cfg(not(unix))]
fn bytes_available(&self) -> Result<usize, WasiFsError> {
unimplemented!("HostFile::bytes_available in WasiFile is not implemented for non-Unix-like targets yet");
// unwrap is safe because of get_raw_fd implementation
let host_fd = self.get_raw_fd().unwrap();

host_file_bytes_available(host_fd)
}

#[cfg(unix)]
Expand Down Expand Up @@ -514,6 +499,26 @@ impl From<io::Error> for WasiFsError {
}
}

#[cfg(unix)]
fn host_file_bytes_available(host_fd: i32) -> Result<usize, WasiFsError> {
let mut bytes_found = 0 as libc::c_int;
let result = unsafe { libc::ioctl(host_fd, libc::FIONREAD, &mut bytes_found) };

match result {
// success
0 => Ok(bytes_found.try_into().unwrap_or(0)),
libc::EBADF => Err(WasiFsError::InvalidFd),
libc::EFAULT => Err(WasiFsError::InvalidData),
libc::EINVAL => Err(WasiFsError::InvalidInput),
_ => Err(WasiFsError::IOError),
}
}

#[cfg(not(unix))]
fn host_file_bytes_available(_raw_fd: i32) -> Result<usize, WasiFsError> {
unimplemented!("host_file_bytes_available not yet implemented for non-Unix-like targets. This probably means the program tried to use wasi::poll_oneoff")
}

#[derive(Debug)]
pub struct Stdout(pub std::io::Stdout);
impl Read for Stdout {
Expand Down Expand Up @@ -579,6 +584,13 @@ impl WasiFile for Stdout {
0
}

fn bytes_available(&self) -> Result<usize, WasiFsError> {
// unwrap is safe because of get_raw_fd implementation
let host_fd = self.get_raw_fd().unwrap();

host_file_bytes_available(host_fd)
}

#[cfg(unix)]
fn get_raw_fd(&self) -> Option<i32> {
use std::os::unix::io::AsRawFd;
Expand Down Expand Up @@ -658,6 +670,13 @@ impl WasiFile for Stderr {
0
}

fn bytes_available(&self) -> Result<usize, WasiFsError> {
// unwrap is safe because of get_raw_fd implementation
let host_fd = self.get_raw_fd().unwrap();

host_file_bytes_available(host_fd)
}

#[cfg(unix)]
fn get_raw_fd(&self) -> Option<i32> {
use std::os::unix::io::AsRawFd;
Expand Down Expand Up @@ -737,28 +756,11 @@ impl WasiFile for Stdin {
0
}

#[cfg(unix)]
fn bytes_available(&self) -> Result<usize, WasiFsError> {
use std::os::unix::io::AsRawFd;
let host_fd = self.0.as_raw_fd();

let mut bytes_found = 0 as libc::c_int;
let result = unsafe { libc::ioctl(host_fd, libc::FIONREAD, &mut bytes_found) };

match result {
// success
0 => Ok(bytes_found.try_into().unwrap_or(0)),
libc::EBADF => Err(WasiFsError::InvalidFd),
libc::EFAULT => Err(WasiFsError::InvalidData),
libc::EINVAL => Err(WasiFsError::InvalidInput),
_ => Err(WasiFsError::IOError),
}
}
#[cfg(not(unix))]
fn bytes_available(&self) -> Result<usize, WasiFsError> {
unimplemented!(
"Stdin::bytes_available in WasiFile is not implemented for non-Unix-like targets yet"
);
// unwrap is safe because of get_raw_fd implementation
let host_fd = self.get_raw_fd().unwrap();

host_file_bytes_available(host_fd)
}

#[cfg(unix)]
Expand Down
23 changes: 17 additions & 6 deletions lib/wasi/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2267,17 +2267,28 @@ pub fn poll_oneoff(

let fd = match s.event_type {
EventType::Read(__wasi_subscription_fs_readwrite_t { fd }) => {
let fd_entry = wasi_try!(state.fs.get_fd(fd));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_READ) {
return __WASI_EACCES;
match fd {
__WASI_STDIN_FILENO | __WASI_STDOUT_FILENO | __WASI_STDERR_FILENO => (),
_ => {
let fd_entry = wasi_try!(state.fs.get_fd(fd));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_READ) {
return __WASI_EACCES;
}
}
}
in_events.push(peb.add(PollEvent::PollIn).build());
Some(fd)
}
EventType::Write(__wasi_subscription_fs_readwrite_t { fd }) => {
let fd_entry = wasi_try!(state.fs.get_fd(fd));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_WRITE) {
return __WASI_EACCES;
match fd {
__WASI_STDIN_FILENO | __WASI_STDOUT_FILENO | __WASI_STDERR_FILENO => (),
_ => {
let fd_entry = wasi_try!(state.fs.get_fd(fd));

if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_WRITE) {
return __WASI_EACCES;
}
}
}
in_events.push(peb.add(PollEvent::PollOut).build());
Some(fd)
Expand Down

0 comments on commit 569d038

Please sign in to comment.