From 0776da7e225995a5dbd51cd140bb3e4dc7c313bc Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 28 Aug 2019 16:14:14 -0700 Subject: [PATCH 1/3] Remove fd_entry lookup on stdin,out,err for wasi::poll_oneoff --- lib/wasi/src/syscalls/mod.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index d1c44ca2797..1ac27c89be2 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -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) From fba6dbff782db9e1b5d9adf46d3198b9be627153 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 29 Aug 2019 10:42:38 -0700 Subject: [PATCH 2/3] Add tests for stdin, stdout, stderr; implement bytes_available too --- lib/wasi-tests/wasitests/poll_oneoff.out | 3 ++ lib/wasi-tests/wasitests/poll_oneoff.rs | 35 +++++++++++++++ lib/wasi-tests/wasitests/poll_oneoff.wasm | Bin 85356 -> 89845 bytes lib/wasi/src/state/types.rs | 50 ++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/lib/wasi-tests/wasitests/poll_oneoff.out b/lib/wasi-tests/wasitests/poll_oneoff.out index ea8f6542388..055f45f4708 100644 --- a/lib/wasi-tests/wasitests/poll_oneoff.out +++ b/lib/wasi-tests/wasitests/poll_oneoff.out @@ -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 diff --git a/lib/wasi-tests/wasitests/poll_oneoff.rs b/lib/wasi-tests/wasitests/poll_oneoff.rs index 255f5e91ed3..6170e5fb576 100644 --- a/lib/wasi-tests/wasitests/poll_oneoff.rs +++ b/lib/wasi-tests/wasitests/poll_oneoff.rs @@ -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"); } } diff --git a/lib/wasi-tests/wasitests/poll_oneoff.wasm b/lib/wasi-tests/wasitests/poll_oneoff.wasm index c74bcb072f231910a1b15c72b6a50757953b6cd1..950345d0bde02b4da3a72feafa821d0bd9c642e0 100755 GIT binary patch delta 24195 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 foj`aLMWUr2rqKr;xVX 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 Result { + use std::os::unix::io::AsRawFd; + let host_fd = self.0.as_raw_fd(); + + let mut bytes_found = 0 as libc::c_int; + // TODO: check that this makes sense + 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 { + unimplemented!( + "Stdout::bytes_available in WasiFile is not implemented for non-Unix-like targets yet" + ); + } + #[cfg(unix)] fn get_raw_fd(&self) -> Option { use std::os::unix::io::AsRawFd; @@ -658,6 +683,31 @@ impl WasiFile for Stderr { 0 } + #[cfg(unix)] + fn bytes_available(&self) -> Result { + use std::os::unix::io::AsRawFd; + let host_fd = self.0.as_raw_fd(); + + let mut bytes_found = 0 as libc::c_int; + // TODO: check that this makes sense + 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 { + unimplemented!( + "Stderr::bytes_available in WasiFile is not implemented for non-Unix-like targets yet" + ); + } + #[cfg(unix)] fn get_raw_fd(&self) -> Option { use std::os::unix::io::AsRawFd; From 7027d7b2c8e0a26ac3fc4184d24cd868ea7c13b0 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 29 Aug 2019 10:48:53 -0700 Subject: [PATCH 3/3] Improve code reuse in polling, reduce `cfg` usage too --- lib/wasi/src/state/types.rs | 120 +++++++++++------------------------- 1 file changed, 36 insertions(+), 84 deletions(-) diff --git a/lib/wasi/src/state/types.rs b/lib/wasi/src/state/types.rs index 3422b0feef8..85b84a811b0 100644 --- a/lib/wasi/src/state/types.rs +++ b/lib/wasi/src/state/types.rs @@ -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 { - 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 { - 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)] @@ -514,6 +499,26 @@ impl From for WasiFsError { } } +#[cfg(unix)] +fn host_file_bytes_available(host_fd: i32) -> Result { + 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 { + 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 { @@ -579,29 +584,11 @@ impl WasiFile for Stdout { 0 } - #[cfg(unix)] - fn bytes_available(&self) -> Result { - use std::os::unix::io::AsRawFd; - let host_fd = self.0.as_raw_fd(); - - let mut bytes_found = 0 as libc::c_int; - // TODO: check that this makes sense - 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 { - unimplemented!( - "Stdout::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)] @@ -683,29 +670,11 @@ impl WasiFile for Stderr { 0 } - #[cfg(unix)] fn bytes_available(&self) -> Result { - use std::os::unix::io::AsRawFd; - let host_fd = self.0.as_raw_fd(); - - let mut bytes_found = 0 as libc::c_int; - // TODO: check that this makes sense - 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 { - unimplemented!( - "Stderr::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)] @@ -787,28 +756,11 @@ impl WasiFile for Stdin { 0 } - #[cfg(unix)] - fn bytes_available(&self) -> Result { - 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 { - 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)]