diff --git a/lib/wasi/src/state/types.rs b/lib/wasi/src/state/types.rs index 3422b0feef8..9ca7c58e55a 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)]