Merge pull request #1855 from ueno/wip/dueno/null

wasi-common: don't rely on platform dependent "NUL" device
This commit is contained in:
Pat Hickey
2020-06-11 09:45:23 -07:00
committed by GitHub
6 changed files with 67 additions and 38 deletions

View File

@@ -2,7 +2,7 @@ use crate::entry::{Entry, EntryHandle};
use crate::fdpool::FdPool;
use crate::handle::Handle;
use crate::sys::osdir::OsDir;
use crate::sys::osother::{OsOther, OsOtherExt};
use crate::sys::stdio::NullDevice;
use crate::sys::stdio::{Stderr, StderrExt, Stdin, StdinExt, Stdout, StdoutExt};
use crate::virtfs::{VirtualDir, VirtualDirEntry};
use crate::wasi::types;
@@ -136,9 +136,9 @@ pub struct WasiCtxBuilder {
impl WasiCtxBuilder {
/// Builder for a new `WasiCtx`.
pub fn new() -> Self {
let stdin = Some(PendingEntry::Thunk(OsOther::from_null));
let stdout = Some(PendingEntry::Thunk(OsOther::from_null));
let stderr = Some(PendingEntry::Thunk(OsOther::from_null));
let stdin = Some(PendingEntry::Handle(Box::new(NullDevice::new())));
let stdout = Some(PendingEntry::Handle(Box::new(NullDevice::new())));
let stderr = Some(PendingEntry::Handle(Box::new(NullDevice::new())));
Self {
stdin,

View File

@@ -39,6 +39,6 @@ pub use ctx::{WasiCtx, WasiCtxBuilder, WasiCtxBuilderError};
pub use handle::{Handle, HandleRights};
pub use sys::osdir::OsDir;
pub use sys::osfile::OsFile;
pub use sys::osother::{OsOther, OsOtherExt};
pub use sys::osother::OsOther;
pub use sys::preopen_dir;
pub use virtfs::{FileContents, VirtualDirEntry};

View File

@@ -10,13 +10,6 @@ use std::fs::File;
use std::io::{self, Read, Write};
use std::ops::Deref;
/// Extra methods for `OsOther` that are only available when configured for
/// some operating systems.
pub trait OsOtherExt {
/// Create `OsOther` as `dyn Handle` from null device.
fn from_null() -> io::Result<Box<dyn Handle>>;
}
/// `OsOther` is something of a catch-all for everything not covered with the specific handle
/// types (`OsFile`, `OsDir`, `Stdio`). It currently encapsulates handles such as OS pipes,
/// sockets, streams, etc. As such, when redirecting stdio within `WasiCtxBuilder`, the redirected

View File

@@ -20,9 +20,10 @@ use super::{fd, AsFile};
use crate::handle::{Handle, HandleRights};
use crate::sandboxed_tty_writer::SandboxedTTYWriter;
use crate::wasi::types::{self, Filetype};
use crate::wasi::Result;
use crate::wasi::{Errno, Result, RightsExt};
use std::any::Any;
use std::cell::Cell;
use std::convert::TryInto;
use std::io::{self, Read, Write};
pub(crate) trait StdinExt: Sized {
@@ -174,3 +175,59 @@ impl Handle for Stderr {
Ok(nwritten)
}
}
#[derive(Debug, Clone)]
pub(crate) struct NullDevice {
pub(crate) rights: Cell<HandleRights>,
pub(crate) fd_flags: Cell<types::Fdflags>,
}
impl NullDevice {
pub(crate) fn new() -> Self {
let rights = HandleRights::new(
types::Rights::character_device_base(),
types::Rights::character_device_inheriting(),
);
let rights = Cell::new(rights);
let fd_flags = types::Fdflags::empty();
let fd_flags = Cell::new(fd_flags);
Self { rights, fd_flags }
}
}
impl Handle for NullDevice {
fn as_any(&self) -> &dyn Any {
self
}
fn try_clone(&self) -> io::Result<Box<dyn Handle>> {
Ok(Box::new(self.clone()))
}
fn get_file_type(&self) -> types::Filetype {
types::Filetype::CharacterDevice
}
fn get_rights(&self) -> HandleRights {
self.rights.get()
}
fn set_rights(&self, rights: HandleRights) {
self.rights.set(rights)
}
// FdOps
fn fdstat_get(&self) -> Result<types::Fdflags> {
Ok(self.fd_flags.get())
}
fn fdstat_set_flags(&self, fdflags: types::Fdflags) -> Result<()> {
self.fd_flags.set(fdflags);
Ok(())
}
fn read_vectored(&self, _iovs: &mut [io::IoSliceMut]) -> Result<usize> {
Ok(0)
}
fn write_vectored(&self, iovs: &[io::IoSlice]) -> Result<usize> {
let mut total_len = 0u32;
for iov in iovs {
let len: types::Size = iov.len().try_into()?;
total_len = total_len.checked_add(len).ok_or(Errno::Overflow)?;
}
Ok(total_len as usize)
}
}

View File

@@ -1,10 +1,9 @@
use super::oshandle::RawOsHandle;
use super::{get_file_type, get_rights};
use crate::handle::Handle;
use crate::sys::osother::{OsOther, OsOtherExt};
use crate::sys::osother::OsOther;
use crate::wasi::types;
use std::convert::TryFrom;
use std::fs::{File, OpenOptions};
use std::fs::File;
use std::io;
use std::os::unix::prelude::{FromRawFd, IntoRawFd};
@@ -21,14 +20,3 @@ impl TryFrom<File> for OsOther {
Ok(Self::new(file_type, rights, handle))
}
}
impl OsOtherExt for OsOther {
fn from_null() -> io::Result<Box<dyn Handle>> {
let file = OpenOptions::new()
.read(true)
.write(true)
.open("/dev/null")?;
let file = Self::try_from(file)?;
Ok(Box::new(file))
}
}

View File

@@ -1,10 +1,9 @@
use super::oshandle::RawOsHandle;
use super::{get_file_type, get_rights};
use crate::handle::Handle;
use crate::sys::osother::{OsOther, OsOtherExt};
use crate::sys::osother::OsOther;
use crate::wasi::types;
use std::convert::TryFrom;
use std::fs::{File, OpenOptions};
use std::fs::File;
use std::io;
use std::os::windows::prelude::{FromRawHandle, IntoRawHandle};
@@ -21,11 +20,3 @@ impl TryFrom<File> for OsOther {
Ok(Self::new(file_type, rights, handle))
}
}
impl OsOtherExt for OsOther {
fn from_null() -> io::Result<Box<dyn Handle>> {
let file = OpenOptions::new().read(true).write(true).open("NUL")?;
let file = Self::try_from(file)?;
Ok(Box::new(file))
}
}