Clean up fd_renumber

This commit is contained in:
Jakub Konka
2019-07-18 21:21:17 +02:00
committed by Dan Gohman
parent 310ecb5b5b
commit 13823e2b39
7 changed files with 66 additions and 46 deletions

View File

@@ -134,6 +134,7 @@ cfg_if::cfg_if! {
"big_random_buf" => false, "big_random_buf" => false,
"sched_yield" => false, "sched_yield" => false,
"file_pread_pwrite" => false, "file_pread_pwrite" => false,
"renumber" => false,
_ => true, _ => true,
} }
} else { } else {

BIN
misc_testsuite/renumber.wasm Executable file

Binary file not shown.

View File

@@ -152,6 +152,10 @@ impl WasiCtx {
.and_then(|ctx| ctx.build()) .and_then(|ctx| ctx.build())
} }
pub fn contains_fd_entry(&self, fd: host::__wasi_fd_t) -> bool {
self.fds.contains_key(&fd)
}
pub fn get_fd_entry( pub fn get_fd_entry(
&self, &self,
fd: host::__wasi_fd_t, fd: host::__wasi_fd_t,

View File

@@ -13,6 +13,36 @@ pub enum Descriptor {
Stderr, Stderr,
} }
impl Descriptor {
pub fn is_file(&self) -> bool {
match self {
Descriptor::File(_) => true,
_ => false,
}
}
pub fn is_stdin(&self) -> bool {
match self {
Descriptor::Stdin => true,
_ => false,
}
}
pub fn is_stdout(&self) -> bool {
match self {
Descriptor::Stdout => true,
_ => false,
}
}
pub fn is_stderr(&self) -> bool {
match self {
Descriptor::Stderr => true,
_ => false,
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct FdObject { pub struct FdObject {
pub file_type: host::__wasi_filetype_t, pub file_type: host::__wasi_filetype_t,

View File

@@ -1,7 +1,7 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use super::return_enc_errno; use super::return_enc_errno;
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::fdentry::Descriptor; use crate::fdentry::{Descriptor, FdEntry};
use crate::memory::*; use crate::memory::*;
use crate::sys::{errno_from_host, host_impl, hostcalls_impl}; use crate::sys::{errno_from_host, host_impl, hostcalls_impl};
use crate::{host, wasm32}; use crate::{host, wasm32};
@@ -244,12 +244,38 @@ pub fn fd_renumber(
let from = dec_fd(from); let from = dec_fd(from);
let to = dec_fd(to); let to = dec_fd(to);
let ret = match hostcalls_impl::fd_renumber(wasi_ctx, from, to) { if !wasi_ctx.contains_fd_entry(from) || !wasi_ctx.contains_fd_entry(to) {
Ok(()) => host::__WASI_ESUCCESS, return return_enc_errno(host::__WASI_EBADF);
Err(e) => e, }
// Don't allow renumbering over a pre-opened resource.
// TODO: Eventually, we do want to permit this, once libpreopen in
// userspace is capable of removing entries from its tables as well.
if wasi_ctx.fds[&from].preopen_path.is_some() || wasi_ctx.fds[&to].preopen_path.is_some() {
return return_enc_errno(host::__WASI_ENOTSUP);
}
// check if stdio fds
// TODO should we renumber stdio fds?
if !wasi_ctx.fds[&from].fd_object.descriptor.is_file()
|| !wasi_ctx.fds[&to].fd_object.descriptor.is_file()
{
return return_enc_errno(host::__WASI_EBADF);
}
let fe_from_dup = if let Descriptor::File(f) = &*wasi_ctx.fds[&from].fd_object.descriptor {
match FdEntry::duplicate(f) {
Ok(fe) => fe,
Err(e) => return return_enc_errno(e),
}
} else {
return return_enc_errno(host::__WASI_EBADF);
}; };
return_enc_errno(ret) wasi_ctx.fds.insert(to, fe_from_dup);
wasi_ctx.fds.remove(&from);
return_enc_errno(host::__WASI_ESUCCESS)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]

View File

@@ -27,39 +27,6 @@ pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: host::__wasi_filesize_t
.map_err(|e| e.raw_os_error().map_or(host::__WASI_EIO, errno_from_host)) .map_err(|e| e.raw_os_error().map_or(host::__WASI_EIO, errno_from_host))
} }
pub(crate) fn fd_renumber(
wasi_ctx: &mut WasiCtx,
from: host::__wasi_fd_t,
to: host::__wasi_fd_t,
) -> Result<()> {
let fe_from = match wasi_ctx.fds.get(&from) {
Some(fe_from) => fe_from,
None => return Err(host::__WASI_EBADF),
};
let fe_to = match wasi_ctx.fds.get(&to) {
Some(fe_to) => fe_to,
None => return Err(host::__WASI_EBADF),
};
// Don't allow renumbering over a pre-opened resource.
// TODO: Eventually, we do want to permit this, once libpreopen in
// userspace is capable of removing entries from its tables as well.
if fe_from.preopen_path.is_some() || fe_to.preopen_path.is_some() {
return Err(host::__WASI_ENOTSUP);
}
let rawfd_from = fe_from.fd_object.descriptor.as_raw_fd();
let rawfd_to = fe_to.fd_object.descriptor.as_raw_fd();
if let Err(e) = nix::unistd::dup2(rawfd_from, rawfd_to) {
return Err(host_impl::errno_from_nix(e.as_errno().unwrap()));
}
let _ = wasi_ctx.fds.remove(&(rawfd_from as host::__wasi_fd_t));
Ok(())
}
pub(crate) fn fd_seek( pub(crate) fn fd_seek(
fd_entry: &FdEntry, fd_entry: &FdEntry,
offset: host::__wasi_filedelta_t, offset: host::__wasi_filedelta_t,

View File

@@ -46,14 +46,6 @@ pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: host::__wasi_filesize_t
.map_err(|err| err.raw_os_error().map_or(host::__WASI_EIO, errno_from_host)) .map_err(|err| err.raw_os_error().map_or(host::__WASI_EIO, errno_from_host))
} }
pub(crate) fn fd_renumber(
wasi_ctx: &mut WasiCtx,
from: host::__wasi_fd_t,
to: host::__wasi_fd_t,
) -> Result<()> {
unimplemented!("fd_renumber")
}
pub(crate) fn fd_seek( pub(crate) fn fd_seek(
fd_entry: &FdEntry, fd_entry: &FdEntry,
offset: host::__wasi_filedelta_t, offset: host::__wasi_filedelta_t,