Clean up fd_renumber
This commit is contained in:
1
build.rs
1
build.rs
@@ -134,6 +134,7 @@ cfg_if::cfg_if! {
|
||||
"big_random_buf" => false,
|
||||
"sched_yield" => false,
|
||||
"file_pread_pwrite" => false,
|
||||
"renumber" => false,
|
||||
_ => true,
|
||||
}
|
||||
} else {
|
||||
|
||||
BIN
misc_testsuite/renumber.wasm
Executable file
BIN
misc_testsuite/renumber.wasm
Executable file
Binary file not shown.
@@ -152,6 +152,10 @@ impl WasiCtx {
|
||||
.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(
|
||||
&self,
|
||||
fd: host::__wasi_fd_t,
|
||||
|
||||
@@ -13,6 +13,36 @@ pub enum Descriptor {
|
||||
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)]
|
||||
pub struct FdObject {
|
||||
pub file_type: host::__wasi_filetype_t,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
use super::return_enc_errno;
|
||||
use crate::ctx::WasiCtx;
|
||||
use crate::fdentry::Descriptor;
|
||||
use crate::fdentry::{Descriptor, FdEntry};
|
||||
use crate::memory::*;
|
||||
use crate::sys::{errno_from_host, host_impl, hostcalls_impl};
|
||||
use crate::{host, wasm32};
|
||||
@@ -244,12 +244,38 @@ pub fn fd_renumber(
|
||||
let from = dec_fd(from);
|
||||
let to = dec_fd(to);
|
||||
|
||||
let ret = match hostcalls_impl::fd_renumber(wasi_ctx, from, to) {
|
||||
Ok(()) => host::__WASI_ESUCCESS,
|
||||
Err(e) => e,
|
||||
if !wasi_ctx.contains_fd_entry(from) || !wasi_ctx.contains_fd_entry(to) {
|
||||
return return_enc_errno(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 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]
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
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(
|
||||
fd_entry: &FdEntry,
|
||||
offset: host::__wasi_filedelta_t,
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
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(
|
||||
fd_entry: &FdEntry,
|
||||
offset: host::__wasi_filedelta_t,
|
||||
|
||||
Reference in New Issue
Block a user