From 06302fb97cf6433b6c6e6b52de47b66b72d04dc6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 25 Nov 2019 07:21:49 -0800 Subject: [PATCH 1/8] Don't dup file descriptors in fd_renumber. --- crates/wasi-common/src/fdentry.rs | 35 ------------------- crates/wasi-common/src/hostcalls_impl/fs.rs | 26 +++++--------- .../wasi-common/src/old/snapshot_0/fdentry.rs | 35 ------------------- .../src/old/snapshot_0/hostcalls_impl/fs.rs | 26 +++++--------- 4 files changed, 18 insertions(+), 104 deletions(-) diff --git a/crates/wasi-common/src/fdentry.rs b/crates/wasi-common/src/fdentry.rs index 948a8ee459f6..af7561891bab 100644 --- a/crates/wasi-common/src/fdentry.rs +++ b/crates/wasi-common/src/fdentry.rs @@ -26,37 +26,6 @@ impl Descriptor { _ => Err(Error::EBADF), } } - - pub(crate) fn is_file(&self) -> bool { - match self { - Self::OsFile(_) => true, - _ => false, - } - } - - #[allow(unused)] - pub(crate) fn is_stdin(&self) -> bool { - match self { - Self::Stdin => true, - _ => false, - } - } - - #[allow(unused)] - pub(crate) fn is_stdout(&self) -> bool { - match self { - Self::Stdout => true, - _ => false, - } - } - - #[allow(unused)] - pub(crate) fn is_stderr(&self) -> bool { - match self { - Self::Stderr => true, - _ => false, - } - } } /// An abstraction struct serving as a wrapper for a host `Descriptor` object which requires @@ -90,10 +59,6 @@ impl FdEntry { ) } - pub(crate) fn duplicate(file: &fs::File) -> Result { - Self::from(file.try_clone()?) - } - pub(crate) fn duplicate_stdin() -> Result { unsafe { determine_type_and_access_rights(&io::stdin()) }.map( |(file_type, rights_base, rights_inheriting)| Self { diff --git a/crates/wasi-common/src/hostcalls_impl/fs.rs b/crates/wasi-common/src/hostcalls_impl/fs.rs index 0d910a34bf4e..e252d6ed6119 100644 --- a/crates/wasi-common/src/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/hostcalls_impl/fs.rs @@ -180,33 +180,25 @@ pub(crate) unsafe fn fd_renumber( ) -> Result<()> { trace!("fd_renumber(from={:?}, to={:?})", from, to); - if !wasi_ctx.contains_fd_entry(from) || !wasi_ctx.contains_fd_entry(to) { + if !wasi_ctx.contains_fd_entry(from) { return Err(Error::EBADF); } - let from_fe = wasi_ctx.get_fd_entry(from)?; - let to_fe = wasi_ctx.get_fd_entry(to)?; - // 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 from_fe.preopen_path.is_some() || to_fe.preopen_path.is_some() { + let from_fe = wasi_ctx.get_fd_entry(from)?; + if from_fe.preopen_path.is_some() { return Err(Error::ENOTSUP); } - - // check if stdio fds - // TODO should we renumber stdio fds? - if !from_fe.as_descriptor(0, 0)?.is_file() || !to_fe.as_descriptor(0, 0)?.is_file() { - return Err(Error::EBADF); + if let Ok(to_fe) = wasi_ctx.get_fd_entry(to) { + if to_fe.preopen_path.is_some() { + return Err(Error::ENOTSUP); + } } - let fe_from_dup = from_fe - .as_descriptor(0, 0)? - .as_file() - .and_then(|file| FdEntry::duplicate(file))?; - - wasi_ctx.insert_fd_entry_at(to, fe_from_dup); - wasi_ctx.remove_fd_entry(from)?; + let fe = wasi_ctx.remove_fd_entry(from)?; + wasi_ctx.insert_fd_entry_at(to, fe); Ok(()) } diff --git a/crates/wasi-common/src/old/snapshot_0/fdentry.rs b/crates/wasi-common/src/old/snapshot_0/fdentry.rs index 25cda13dc01d..0386b02b6c07 100644 --- a/crates/wasi-common/src/old/snapshot_0/fdentry.rs +++ b/crates/wasi-common/src/old/snapshot_0/fdentry.rs @@ -26,37 +26,6 @@ impl Descriptor { _ => Err(Error::EBADF), } } - - pub(crate) fn is_file(&self) -> bool { - match self { - Self::OsFile(_) => true, - _ => false, - } - } - - #[allow(unused)] - pub(crate) fn is_stdin(&self) -> bool { - match self { - Self::Stdin => true, - _ => false, - } - } - - #[allow(unused)] - pub(crate) fn is_stdout(&self) -> bool { - match self { - Self::Stdout => true, - _ => false, - } - } - - #[allow(unused)] - pub(crate) fn is_stderr(&self) -> bool { - match self { - Self::Stderr => true, - _ => false, - } - } } /// An abstraction struct serving as a wrapper for a host `Descriptor` object which requires @@ -90,10 +59,6 @@ impl FdEntry { ) } - pub(crate) fn duplicate(file: &fs::File) -> Result { - Self::from(file.try_clone()?) - } - pub(crate) fn duplicate_stdin() -> Result { unsafe { determine_type_and_access_rights(&io::stdin()) }.map( |(file_type, rights_base, rights_inheriting)| Self { diff --git a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs index 4dd4d1c57966..59ade77feed0 100644 --- a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs @@ -180,33 +180,25 @@ pub(crate) unsafe fn fd_renumber( ) -> Result<()> { trace!("fd_renumber(from={:?}, to={:?})", from, to); - if !wasi_ctx.contains_fd_entry(from) || !wasi_ctx.contains_fd_entry(to) { + if !wasi_ctx.contains_fd_entry(from) { return Err(Error::EBADF); } - let from_fe = wasi_ctx.get_fd_entry(from)?; - let to_fe = wasi_ctx.get_fd_entry(to)?; - // 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 from_fe.preopen_path.is_some() || to_fe.preopen_path.is_some() { + let from_fe = wasi_ctx.get_fd_entry(from)?; + if from_fe.preopen_path.is_some() { return Err(Error::ENOTSUP); } - - // check if stdio fds - // TODO should we renumber stdio fds? - if !from_fe.as_descriptor(0, 0)?.is_file() || !to_fe.as_descriptor(0, 0)?.is_file() { - return Err(Error::EBADF); + if let Ok(to_fe) = wasi_ctx.get_fd_entry(to) { + if to_fe.preopen_path.is_some() { + return Err(Error::ENOTSUP); + } } - let fe_from_dup = from_fe - .as_descriptor(0, 0)? - .as_file() - .and_then(|file| FdEntry::duplicate(file))?; - - wasi_ctx.insert_fd_entry_at(to, fe_from_dup); - wasi_ctx.remove_fd_entry(from)?; + let fe = wasi_ctx.remove_fd_entry(from)?; + wasi_ctx.insert_fd_entry_at(to, fe); Ok(()) } From 5c6f9c08793c220fbdd7c31e9b295b31c65fe45f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 25 Nov 2019 06:25:57 -0800 Subject: [PATCH 2/8] Support fd_fdstat_get on stdin/stdout/stderr. Add a routine for obtaining an `OsFile` containing a file descriptor for stdin/stdout/stderr so that we can do fd_fdstat_get on them. --- crates/wasi-common/src/fdentry.rs | 15 ++++++-- crates/wasi-common/src/hostcalls_impl/fs.rs | 35 ++++++++++--------- .../src/hostcalls_impl/fs_helpers.rs | 2 +- .../wasi-common/src/old/snapshot_0/fdentry.rs | 17 +++++++-- .../src/old/snapshot_0/hostcalls_impl/fs.rs | 35 ++++++++++--------- .../snapshot_0/hostcalls_impl/fs_helpers.rs | 2 +- .../old/snapshot_0/sys/unix/fdentry_impl.rs | 6 ++++ .../snapshot_0/sys/windows/fdentry_impl.rs | 7 ++++ .../wasi-common/src/sys/unix/fdentry_impl.rs | 6 ++++ .../src/sys/windows/fdentry_impl.rs | 7 ++++ 10 files changed, 92 insertions(+), 40 deletions(-) diff --git a/crates/wasi-common/src/fdentry.rs b/crates/wasi-common/src/fdentry.rs index af7561891bab..adf78e1c82b9 100644 --- a/crates/wasi-common/src/fdentry.rs +++ b/crates/wasi-common/src/fdentry.rs @@ -1,6 +1,7 @@ use crate::sys::dev_null; -use crate::sys::fdentry_impl::{determine_type_and_access_rights, OsFile}; +use crate::sys::fdentry_impl::{descriptor_as_osfile, determine_type_and_access_rights, OsFile}; use crate::{wasi, Error, Result}; +use std::mem::ManuallyDrop; use std::path::PathBuf; use std::{fs, io}; @@ -13,19 +14,27 @@ pub(crate) enum Descriptor { } impl Descriptor { - pub(crate) fn as_file(&self) -> Result<&OsFile> { + /// Return a reference to the actual `OsFile`, allowing operations which + /// require an actual file and not just a stream or socket file descriptor. + pub(crate) fn as_actual_file(&self) -> Result<&OsFile> { match self { Self::OsFile(file) => Ok(file), _ => Err(Error::EBADF), } } - pub(crate) fn as_file_mut(&mut self) -> Result<&mut OsFile> { + /// Like `as_actual_file`, but return a mutable reference. + pub(crate) fn as_actual_file_mut(&mut self) -> Result<&mut OsFile> { match self { Self::OsFile(file) => Ok(file), _ => Err(Error::EBADF), } } + + /// Return an `OsFile`, which may be a stream or socket file descriptor. + pub(crate) fn as_file(&self) -> ManuallyDrop { + descriptor_as_osfile(self) + } } /// An abstraction struct serving as a wrapper for a host `Descriptor` object which requires diff --git a/crates/wasi-common/src/hostcalls_impl/fs.rs b/crates/wasi-common/src/hostcalls_impl/fs.rs index e252d6ed6119..7ccf36020567 100644 --- a/crates/wasi-common/src/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/hostcalls_impl/fs.rs @@ -36,7 +36,7 @@ pub(crate) unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> R let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_DATASYNC, 0)? - .as_file()?; + .as_actual_file()?; fd.sync_data().map_err(Into::into) } @@ -62,7 +62,7 @@ pub(crate) unsafe fn fd_pread( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_READ | wasi::__WASI_RIGHTS_FD_SEEK, 0)? - .as_file()?; + .as_actual_file()?; let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?; @@ -114,7 +114,7 @@ pub(crate) unsafe fn fd_pwrite( wasi::__WASI_RIGHTS_FD_WRITE | wasi::__WASI_RIGHTS_FD_SEEK, 0, )? - .as_file()?; + .as_actual_file()?; let iovs = dec_ciovec_slice(memory, iovs_ptr, iovs_len)?; if offset > i64::max_value() as u64 { @@ -227,7 +227,7 @@ pub(crate) unsafe fn fd_seek( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(rights, 0)? - .as_file_mut()?; + .as_actual_file_mut()?; let pos = match whence { wasi::__WASI_WHENCE_CUR => SeekFrom::Current(offset), @@ -253,7 +253,7 @@ pub(crate) unsafe fn fd_tell( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_TELL, 0)? - .as_file_mut()?; + .as_actual_file_mut()?; let host_offset = fd.seek(SeekFrom::Current(0))?; @@ -271,9 +271,9 @@ pub(crate) unsafe fn fd_fdstat_get( trace!("fd_fdstat_get(fd={:?}, fdstat_ptr={:#x?})", fd, fdstat_ptr); let mut fdstat = dec_fdstat_byref(memory, fdstat_ptr)?; - let wasi_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; + let host_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); - let fs_flags = hostcalls_impl::fd_fdstat_get(wasi_fd)?; + let fs_flags = hostcalls_impl::fd_fdstat_get(&host_fd)?; let fe = wasi_ctx.get_fd_entry(fd)?; fdstat.fs_filetype = fe.file_type; @@ -293,9 +293,9 @@ pub(crate) unsafe fn fd_fdstat_set_flags( ) -> Result<()> { trace!("fd_fdstat_set_flags(fd={:?}, fdflags={:#x?})", fd, fdflags); - let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; + let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); - hostcalls_impl::fd_fdstat_set_flags(fd, fdflags) + hostcalls_impl::fd_fdstat_set_flags(&fd, fdflags) } pub(crate) unsafe fn fd_fdstat_set_rights( @@ -329,7 +329,7 @@ pub(crate) unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> Resul let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_SYNC, 0)? - .as_file()?; + .as_actual_file()?; fd.sync_all().map_err(Into::into) } @@ -393,7 +393,7 @@ pub(crate) unsafe fn fd_advise( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ADVISE, 0)? - .as_file()?; + .as_actual_file()?; hostcalls_impl::fd_advise(fd, advice, offset, len) } @@ -409,7 +409,7 @@ pub(crate) unsafe fn fd_allocate( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ALLOCATE, 0)? - .as_file()?; + .as_actual_file()?; let metadata = fd.metadata()?; @@ -672,7 +672,10 @@ pub(crate) unsafe fn fd_filestat_get( filestat_ptr ); - let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; + let fd = wasi_ctx + .get_fd_entry(fd)? + .as_descriptor(0, 0)? + .as_actual_file()?; let host_filestat = hostcalls_impl::fd_filestat_get_impl(fd)?; @@ -699,7 +702,7 @@ pub(crate) unsafe fn fd_filestat_set_times( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_TIMES, 0)? - .as_file()?; + .as_actual_file()?; fd_filestat_set_times_impl(fd, st_atim, st_mtim, fst_flags) } @@ -750,7 +753,7 @@ pub(crate) unsafe fn fd_filestat_set_size( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_SIZE, 0)? - .as_file()?; + .as_actual_file()?; // This check will be unnecessary when rust-lang/rust#63326 is fixed if st_size > i64::max_value() as u64 { @@ -1012,7 +1015,7 @@ pub(crate) unsafe fn fd_readdir( let file = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READDIR, 0)? - .as_file_mut()?; + .as_actual_file()?; let mut host_buf = dec_slice_of_mut_u8(memory, buf, buf_len)?; trace!(" | (buf,buf_len)={:?}", host_buf); diff --git a/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs b/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs index 5fd939b16730..8a59681c47d9 100644 --- a/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs +++ b/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs @@ -46,7 +46,7 @@ pub(crate) fn path_get( let dirfd = fe .as_descriptor(rights_base, rights_inheriting)? - .as_file()? + .as_actual_file()? .try_clone()?; // Stack of directory file descriptors. Index 0 always corresponds with the directory provided diff --git a/crates/wasi-common/src/old/snapshot_0/fdentry.rs b/crates/wasi-common/src/old/snapshot_0/fdentry.rs index 0386b02b6c07..25e5e962f6c1 100644 --- a/crates/wasi-common/src/old/snapshot_0/fdentry.rs +++ b/crates/wasi-common/src/old/snapshot_0/fdentry.rs @@ -1,6 +1,9 @@ use crate::old::snapshot_0::sys::dev_null; -use crate::old::snapshot_0::sys::fdentry_impl::{determine_type_and_access_rights, OsFile}; +use crate::old::snapshot_0::sys::fdentry_impl::{ + descriptor_as_osfile, determine_type_and_access_rights, OsFile, +}; use crate::old::snapshot_0::{wasi, Error, Result}; +use std::mem::ManuallyDrop; use std::path::PathBuf; use std::{fs, io}; @@ -13,19 +16,27 @@ pub(crate) enum Descriptor { } impl Descriptor { - pub(crate) fn as_file(&self) -> Result<&OsFile> { + /// Return a reference to the actual `OsFile`, allowing operations which + /// require an actual file and not just a stream or socket file descriptor. + pub(crate) fn as_actual_file(&self) -> Result<&OsFile> { match self { Self::OsFile(file) => Ok(file), _ => Err(Error::EBADF), } } - pub(crate) fn as_file_mut(&mut self) -> Result<&mut OsFile> { + /// Like `as_actual_file`, but return a mutable reference. + pub(crate) fn as_actual_file_mut(&mut self) -> Result<&mut OsFile> { match self { Self::OsFile(file) => Ok(file), _ => Err(Error::EBADF), } } + + /// Return an `OsFile`, which may be a stream or socket file descriptor. + pub(crate) fn as_file(&self) -> ManuallyDrop { + descriptor_as_osfile(self) + } } /// An abstraction struct serving as a wrapper for a host `Descriptor` object which requires diff --git a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs index 59ade77feed0..999fb9c9b10f 100644 --- a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs @@ -36,7 +36,7 @@ pub(crate) unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> R let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_DATASYNC, 0)? - .as_file()?; + .as_actual_file()?; fd.sync_data().map_err(Into::into) } @@ -62,7 +62,7 @@ pub(crate) unsafe fn fd_pread( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_READ | wasi::__WASI_RIGHTS_FD_SEEK, 0)? - .as_file()?; + .as_actual_file()?; let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?; @@ -114,7 +114,7 @@ pub(crate) unsafe fn fd_pwrite( wasi::__WASI_RIGHTS_FD_WRITE | wasi::__WASI_RIGHTS_FD_SEEK, 0, )? - .as_file()?; + .as_actual_file()?; let iovs = dec_ciovec_slice(memory, iovs_ptr, iovs_len)?; if offset > i64::max_value() as u64 { @@ -227,7 +227,7 @@ pub(crate) unsafe fn fd_seek( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(rights, 0)? - .as_file_mut()?; + .as_actual_file_mut()?; let pos = match whence { wasi::__WASI_WHENCE_CUR => SeekFrom::Current(offset), @@ -253,7 +253,7 @@ pub(crate) unsafe fn fd_tell( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_TELL, 0)? - .as_file_mut()?; + .as_actual_file_mut()?; let host_offset = fd.seek(SeekFrom::Current(0))?; @@ -271,9 +271,9 @@ pub(crate) unsafe fn fd_fdstat_get( trace!("fd_fdstat_get(fd={:?}, fdstat_ptr={:#x?})", fd, fdstat_ptr); let mut fdstat = dec_fdstat_byref(memory, fdstat_ptr)?; - let wasi_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; + let host_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); - let fs_flags = hostcalls_impl::fd_fdstat_get(wasi_fd)?; + let fs_flags = hostcalls_impl::fd_fdstat_get(&host_fd)?; let fe = wasi_ctx.get_fd_entry(fd)?; fdstat.fs_filetype = fe.file_type; @@ -293,9 +293,9 @@ pub(crate) unsafe fn fd_fdstat_set_flags( ) -> Result<()> { trace!("fd_fdstat_set_flags(fd={:?}, fdflags={:#x?})", fd, fdflags); - let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; + let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); - hostcalls_impl::fd_fdstat_set_flags(fd, fdflags) + hostcalls_impl::fd_fdstat_set_flags(&fd, fdflags) } pub(crate) unsafe fn fd_fdstat_set_rights( @@ -329,7 +329,7 @@ pub(crate) unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> Resul let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_SYNC, 0)? - .as_file()?; + .as_actual_file()?; fd.sync_all().map_err(Into::into) } @@ -393,7 +393,7 @@ pub(crate) unsafe fn fd_advise( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ADVISE, 0)? - .as_file()?; + .as_actual_file()?; hostcalls_impl::fd_advise(fd, advice, offset, len) } @@ -409,7 +409,7 @@ pub(crate) unsafe fn fd_allocate( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ALLOCATE, 0)? - .as_file()?; + .as_actual_file()?; let metadata = fd.metadata()?; @@ -593,7 +593,7 @@ pub(crate) unsafe fn fd_readdir( let file = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READDIR, 0)? - .as_file_mut()?; + .as_actual_file_mut()?; let host_buf = dec_slice_of_mut_u8(memory, buf, buf_len)?; trace!(" | (buf,buf_len)={:?}", host_buf); @@ -707,7 +707,10 @@ pub(crate) unsafe fn fd_filestat_get( filestat_ptr ); - let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; + let fd = wasi_ctx + .get_fd_entry(fd)? + .as_descriptor(0, 0)? + .as_actual_file()?; let host_filestat = hostcalls_impl::fd_filestat_get_impl(fd)?; @@ -734,7 +737,7 @@ pub(crate) unsafe fn fd_filestat_set_times( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_TIMES, 0)? - .as_file()?; + .as_actual_file()?; fd_filestat_set_times_impl(fd, st_atim, st_mtim, fst_flags) } @@ -785,7 +788,7 @@ pub(crate) unsafe fn fd_filestat_set_size( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_SIZE, 0)? - .as_file()?; + .as_actual_file()?; // This check will be unnecessary when rust-lang/rust#63326 is fixed if st_size > i64::max_value() as u64 { diff --git a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs index 3a26bfc54b0f..4ba2f3ed0875 100644 --- a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs +++ b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs @@ -46,7 +46,7 @@ pub(crate) fn path_get( let dirfd = fe .as_descriptor(rights_base, rights_inheriting)? - .as_file()? + .as_actual_file()? .try_clone()?; // Stack of directory file descriptors. Index 0 always corresponds with the directory provided diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs index b63a850df530..57aebfa78f1b 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs @@ -1,6 +1,8 @@ use crate::old::snapshot_0::fdentry::Descriptor; use crate::old::snapshot_0::{wasi, Error, Result}; +use std::fs::File; use std::io; +use std::mem::ManuallyDrop; use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, RawFd}; cfg_if::cfg_if! { @@ -31,6 +33,10 @@ impl AsRawFd for Descriptor { } } +pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsFile::from(unsafe { File::from_raw_fd(desc.as_raw_fd()) })) +} + /// This function is unsafe because it operates on a raw file descriptor. pub(crate) unsafe fn determine_type_and_access_rights( fd: &Fd, diff --git a/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs index e903e1a34b1f..40597dffea5b 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs @@ -2,6 +2,7 @@ use crate::old::snapshot_0::fdentry::Descriptor; use crate::old::snapshot_0::{wasi, Error, Result}; use std::fs::File; use std::io; +use std::mem::ManuallyDrop; use std::ops::{Deref, DerefMut}; use std::os::windows::prelude::{AsRawHandle, FromRawHandle, RawHandle}; @@ -45,6 +46,12 @@ impl AsRawHandle for Descriptor { } } +pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsFile::from(unsafe { + File::from_raw_handle(desc.as_raw_handle()) + })) +} + /// This function is unsafe because it operates on a raw file handle. pub(crate) unsafe fn determine_type_and_access_rights( handle: &Handle, diff --git a/crates/wasi-common/src/sys/unix/fdentry_impl.rs b/crates/wasi-common/src/sys/unix/fdentry_impl.rs index fcbe499999a7..fba32329f263 100644 --- a/crates/wasi-common/src/sys/unix/fdentry_impl.rs +++ b/crates/wasi-common/src/sys/unix/fdentry_impl.rs @@ -1,6 +1,8 @@ use crate::fdentry::Descriptor; use crate::{wasi, Error, Result}; +use std::fs::File; use std::io; +use std::mem::ManuallyDrop; use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, RawFd}; cfg_if::cfg_if! { @@ -31,6 +33,10 @@ impl AsRawFd for Descriptor { } } +pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsFile::from(unsafe { File::from_raw_fd(desc.as_raw_fd()) })) +} + /// This function is unsafe because it operates on a raw file descriptor. pub(crate) unsafe fn determine_type_and_access_rights( fd: &Fd, diff --git a/crates/wasi-common/src/sys/windows/fdentry_impl.rs b/crates/wasi-common/src/sys/windows/fdentry_impl.rs index 18cf9914fe65..ee6a06d7e64c 100644 --- a/crates/wasi-common/src/sys/windows/fdentry_impl.rs +++ b/crates/wasi-common/src/sys/windows/fdentry_impl.rs @@ -2,6 +2,7 @@ use crate::fdentry::Descriptor; use crate::{wasi, Error, Result}; use std::fs::File; use std::io; +use std::mem::ManuallyDrop; use std::ops::{Deref, DerefMut}; use std::os::windows::prelude::{AsRawHandle, FromRawHandle, RawHandle}; @@ -45,6 +46,12 @@ impl AsRawHandle for Descriptor { } } +pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsFile::from(unsafe { + File::from_raw_handle(desc.as_raw_handle()) + })) +} + /// This function is unsafe because it operates on a raw file handle. pub(crate) unsafe fn determine_type_and_access_rights( handle: &Handle, From 3120af90c4e7693fa5cd7e4789bc6c58c302a8d6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 25 Nov 2019 06:42:51 -0800 Subject: [PATCH 3/8] Add a testcase for fd_fdstat_get etc. on stdin etc. --- .../test-programs/wasi-tests/src/bin/stdio.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 crates/test-programs/wasi-tests/src/bin/stdio.rs diff --git a/crates/test-programs/wasi-tests/src/bin/stdio.rs b/crates/test-programs/wasi-tests/src/bin/stdio.rs new file mode 100644 index 000000000000..1ef15114de08 --- /dev/null +++ b/crates/test-programs/wasi-tests/src/bin/stdio.rs @@ -0,0 +1,31 @@ +use libc; +use std::mem::MaybeUninit; +use std::{env, process}; +use wasi::wasi_unstable; +use wasi_tests::wasi_wrappers::wasi_fd_fdstat_get; + +unsafe fn test_stdio() { + for fd in &[ + wasi_unstable::STDIN_FD, + wasi_unstable::STDOUT_FD, + wasi_unstable::STDERR_FD, + ] { + let mut fdstat: wasi_unstable::FdStat = MaybeUninit::zeroed().assume_init(); + let status = wasi_fd_fdstat_get(*fd, &mut fdstat); + assert_eq!( + status, + wasi_unstable::raw::__WASI_ESUCCESS, + "fd_fdstat_get on stdio" + ); + + assert!( + wasi_unstable::fd_renumber(*fd, *fd + 100).is_ok(), + "renumbering stdio", + ); + } +} + +fn main() { + // Run the tests. + unsafe { test_stdio() } +} From e7288e98cc51787a0266ff01cdf236f5ae62f287 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 26 Nov 2019 11:15:57 +0100 Subject: [PATCH 4/8] Fix compilation on macOS --- crates/wasi-common/src/hostcalls_impl/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wasi-common/src/hostcalls_impl/fs.rs b/crates/wasi-common/src/hostcalls_impl/fs.rs index 7ccf36020567..dbedad80d255 100644 --- a/crates/wasi-common/src/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/hostcalls_impl/fs.rs @@ -1015,7 +1015,7 @@ pub(crate) unsafe fn fd_readdir( let file = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READDIR, 0)? - .as_actual_file()?; + .as_actual_file_mut()?; let mut host_buf = dec_slice_of_mut_u8(memory, buf, buf_len)?; trace!(" | (buf,buf_len)={:?}", host_buf); From fbb81ec88c9b4cf3d332d506c36faf2c007944ab Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 27 Nov 2019 14:02:31 +0100 Subject: [PATCH 5/8] Rename OsFile to OsHandle This commits renames `OsFile` to `OsHandle` which seems to make more sense semantically as it is permitted to hold a valid OS handle to OS entities other than simply file/dir (e.g., socket, stream, etc.). As such, this commit also renames methods on `Descriptor` struct from `as_actual_file` to `as_file` as this in reality does pertain ops on FS entities such as files/dirs, and `as_file` to `as_os_handle` as in this case it can be anything, from file, through a socket, to a stream. --- crates/wasi-common/src/fdentry.rs | 29 +++++++------ crates/wasi-common/src/hostcalls_impl/fs.rs | 41 ++++++++++--------- .../src/hostcalls_impl/fs_helpers.rs | 2 +- .../wasi-common/src/old/snapshot_0/fdentry.rs | 27 ++++++------ .../src/old/snapshot_0/hostcalls_impl/fs.rs | 41 ++++++++++--------- .../snapshot_0/hostcalls_impl/fs_helpers.rs | 2 +- .../snapshot_0/sys/unix/bsd/hostcalls_impl.rs | 12 +++--- .../src/old/snapshot_0/sys/unix/bsd/mod.rs | 2 +- .../sys/unix/bsd/{osfile.rs => oshandle.rs} | 10 ++--- .../old/snapshot_0/sys/unix/fdentry_impl.rs | 12 +++--- .../src/old/snapshot_0/sys/unix/linux/mod.rs | 2 +- .../sys/unix/linux/{osfile.rs => oshandle.rs} | 10 ++--- .../snapshot_0/sys/windows/fdentry_impl.rs | 16 ++++---- .../sys/windows/hostcalls_impl/fs.rs | 6 +-- .../src/sys/unix/bsd/hostcalls_impl.rs | 10 ++--- crates/wasi-common/src/sys/unix/bsd/mod.rs | 2 +- .../sys/unix/bsd/{osfile.rs => oshandle.rs} | 12 +++--- .../wasi-common/src/sys/unix/fdentry_impl.rs | 12 +++--- crates/wasi-common/src/sys/unix/linux/mod.rs | 2 +- .../sys/unix/linux/{osfile.rs => oshandle.rs} | 10 ++--- .../src/sys/windows/fdentry_impl.rs | 16 ++++---- .../src/sys/windows/hostcalls_impl/fs.rs | 2 +- 22 files changed, 146 insertions(+), 132 deletions(-) rename crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/{osfile.rs => oshandle.rs} (85%) rename crates/wasi-common/src/old/snapshot_0/sys/unix/linux/{osfile.rs => oshandle.rs} (72%) rename crates/wasi-common/src/sys/unix/bsd/{osfile.rs => oshandle.rs} (84%) rename crates/wasi-common/src/sys/unix/linux/{osfile.rs => oshandle.rs} (72%) diff --git a/crates/wasi-common/src/fdentry.rs b/crates/wasi-common/src/fdentry.rs index adf78e1c82b9..930e43ae82bc 100644 --- a/crates/wasi-common/src/fdentry.rs +++ b/crates/wasi-common/src/fdentry.rs @@ -1,5 +1,7 @@ use crate::sys::dev_null; -use crate::sys::fdentry_impl::{descriptor_as_osfile, determine_type_and_access_rights, OsFile}; +use crate::sys::fdentry_impl::{ + descriptor_as_oshandle, determine_type_and_access_rights, OsHandle, +}; use crate::{wasi, Error, Result}; use std::mem::ManuallyDrop; use std::path::PathBuf; @@ -7,33 +9,34 @@ use std::{fs, io}; #[derive(Debug)] pub(crate) enum Descriptor { - OsFile(OsFile), + OsHandle(OsHandle), Stdin, Stdout, Stderr, } impl Descriptor { - /// Return a reference to the actual `OsFile`, allowing operations which - /// require an actual file and not just a stream or socket file descriptor. - pub(crate) fn as_actual_file(&self) -> Result<&OsFile> { + /// Return a reference to the `OsHandle` treating it as an actual file/dir, and + /// allowing operations which require an actual file and not just a stream or + /// socket file descriptor. + pub(crate) fn as_file(&self) -> Result<&OsHandle> { match self { - Self::OsFile(file) => Ok(file), + Self::OsHandle(file) => Ok(file), _ => Err(Error::EBADF), } } - /// Like `as_actual_file`, but return a mutable reference. - pub(crate) fn as_actual_file_mut(&mut self) -> Result<&mut OsFile> { + /// Like `as_file`, but return a mutable reference. + pub(crate) fn as_file_mut(&mut self) -> Result<&mut OsHandle> { match self { - Self::OsFile(file) => Ok(file), + Self::OsHandle(file) => Ok(file), _ => Err(Error::EBADF), } } - /// Return an `OsFile`, which may be a stream or socket file descriptor. - pub(crate) fn as_file(&self) -> ManuallyDrop { - descriptor_as_osfile(self) + /// Return an `OsHandle`, which may be a stream or socket file descriptor. + pub(crate) fn as_os_handle(&self) -> ManuallyDrop { + descriptor_as_oshandle(self) } } @@ -60,7 +63,7 @@ impl FdEntry { unsafe { determine_type_and_access_rights(&file) }.map( |(file_type, rights_base, rights_inheriting)| Self { file_type, - descriptor: Descriptor::OsFile(OsFile::from(file)), + descriptor: Descriptor::OsHandle(OsHandle::from(file)), rights_base, rights_inheriting, preopen_path: None, diff --git a/crates/wasi-common/src/hostcalls_impl/fs.rs b/crates/wasi-common/src/hostcalls_impl/fs.rs index dbedad80d255..e543355efb79 100644 --- a/crates/wasi-common/src/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/hostcalls_impl/fs.rs @@ -36,7 +36,7 @@ pub(crate) unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> R let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_DATASYNC, 0)? - .as_actual_file()?; + .as_file()?; fd.sync_data().map_err(Into::into) } @@ -62,7 +62,7 @@ pub(crate) unsafe fn fd_pread( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_READ | wasi::__WASI_RIGHTS_FD_SEEK, 0)? - .as_actual_file()?; + .as_file()?; let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?; @@ -114,7 +114,7 @@ pub(crate) unsafe fn fd_pwrite( wasi::__WASI_RIGHTS_FD_WRITE | wasi::__WASI_RIGHTS_FD_SEEK, 0, )? - .as_actual_file()?; + .as_file()?; let iovs = dec_ciovec_slice(memory, iovs_ptr, iovs_len)?; if offset > i64::max_value() as u64 { @@ -161,7 +161,7 @@ pub(crate) unsafe fn fd_read( .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READ, 0)? { - Descriptor::OsFile(file) => file.read_vectored(&mut iovs), + Descriptor::OsHandle(file) => file.read_vectored(&mut iovs), Descriptor::Stdin => io::stdin().lock().read_vectored(&mut iovs), _ => return Err(Error::EBADF), }; @@ -227,7 +227,7 @@ pub(crate) unsafe fn fd_seek( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(rights, 0)? - .as_actual_file_mut()?; + .as_file_mut()?; let pos = match whence { wasi::__WASI_WHENCE_CUR => SeekFrom::Current(offset), @@ -253,7 +253,7 @@ pub(crate) unsafe fn fd_tell( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_TELL, 0)? - .as_actual_file_mut()?; + .as_file_mut()?; let host_offset = fd.seek(SeekFrom::Current(0))?; @@ -271,7 +271,10 @@ pub(crate) unsafe fn fd_fdstat_get( trace!("fd_fdstat_get(fd={:?}, fdstat_ptr={:#x?})", fd, fdstat_ptr); let mut fdstat = dec_fdstat_byref(memory, fdstat_ptr)?; - let host_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); + let host_fd = wasi_ctx + .get_fd_entry(fd)? + .as_descriptor(0, 0)? + .as_os_handle(); let fs_flags = hostcalls_impl::fd_fdstat_get(&host_fd)?; @@ -293,7 +296,10 @@ pub(crate) unsafe fn fd_fdstat_set_flags( ) -> Result<()> { trace!("fd_fdstat_set_flags(fd={:?}, fdflags={:#x?})", fd, fdflags); - let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); + let fd = wasi_ctx + .get_fd_entry(fd)? + .as_descriptor(0, 0)? + .as_os_handle(); hostcalls_impl::fd_fdstat_set_flags(&fd, fdflags) } @@ -329,7 +335,7 @@ pub(crate) unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> Resul let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_SYNC, 0)? - .as_actual_file()?; + .as_file()?; fd.sync_all().map_err(Into::into) } @@ -357,7 +363,7 @@ pub(crate) unsafe fn fd_write( .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_WRITE, 0)? { - Descriptor::OsFile(file) => file.write_vectored(&iovs)?, + Descriptor::OsHandle(file) => file.write_vectored(&iovs)?, Descriptor::Stdin => return Err(Error::EBADF), Descriptor::Stdout => { // lock for the duration of the scope @@ -393,7 +399,7 @@ pub(crate) unsafe fn fd_advise( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ADVISE, 0)? - .as_actual_file()?; + .as_file()?; hostcalls_impl::fd_advise(fd, advice, offset, len) } @@ -409,7 +415,7 @@ pub(crate) unsafe fn fd_allocate( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ALLOCATE, 0)? - .as_actual_file()?; + .as_file()?; let metadata = fd.metadata()?; @@ -672,10 +678,7 @@ pub(crate) unsafe fn fd_filestat_get( filestat_ptr ); - let fd = wasi_ctx - .get_fd_entry(fd)? - .as_descriptor(0, 0)? - .as_actual_file()?; + let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; let host_filestat = hostcalls_impl::fd_filestat_get_impl(fd)?; @@ -702,7 +705,7 @@ pub(crate) unsafe fn fd_filestat_set_times( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_TIMES, 0)? - .as_actual_file()?; + .as_file()?; fd_filestat_set_times_impl(fd, st_atim, st_mtim, fst_flags) } @@ -753,7 +756,7 @@ pub(crate) unsafe fn fd_filestat_set_size( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_SIZE, 0)? - .as_actual_file()?; + .as_file()?; // This check will be unnecessary when rust-lang/rust#63326 is fixed if st_size > i64::max_value() as u64 { @@ -1015,7 +1018,7 @@ pub(crate) unsafe fn fd_readdir( let file = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READDIR, 0)? - .as_actual_file_mut()?; + .as_file_mut()?; let mut host_buf = dec_slice_of_mut_u8(memory, buf, buf_len)?; trace!(" | (buf,buf_len)={:?}", host_buf); diff --git a/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs b/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs index 8a59681c47d9..5fd939b16730 100644 --- a/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs +++ b/crates/wasi-common/src/hostcalls_impl/fs_helpers.rs @@ -46,7 +46,7 @@ pub(crate) fn path_get( let dirfd = fe .as_descriptor(rights_base, rights_inheriting)? - .as_actual_file()? + .as_file()? .try_clone()?; // Stack of directory file descriptors. Index 0 always corresponds with the directory provided diff --git a/crates/wasi-common/src/old/snapshot_0/fdentry.rs b/crates/wasi-common/src/old/snapshot_0/fdentry.rs index 25e5e962f6c1..bc294db6ef8d 100644 --- a/crates/wasi-common/src/old/snapshot_0/fdentry.rs +++ b/crates/wasi-common/src/old/snapshot_0/fdentry.rs @@ -1,6 +1,6 @@ use crate::old::snapshot_0::sys::dev_null; use crate::old::snapshot_0::sys::fdentry_impl::{ - descriptor_as_osfile, determine_type_and_access_rights, OsFile, + descriptor_as_oshandle, determine_type_and_access_rights, OsHandle, }; use crate::old::snapshot_0::{wasi, Error, Result}; use std::mem::ManuallyDrop; @@ -9,33 +9,34 @@ use std::{fs, io}; #[derive(Debug)] pub(crate) enum Descriptor { - OsFile(OsFile), + OsHandle(OsHandle), Stdin, Stdout, Stderr, } impl Descriptor { - /// Return a reference to the actual `OsFile`, allowing operations which - /// require an actual file and not just a stream or socket file descriptor. - pub(crate) fn as_actual_file(&self) -> Result<&OsFile> { + /// Return a reference to the `OsHandle` treating it as an actual file/dir, and + /// allowing operations which require an actual file and not just a stream or + /// socket file descriptor. + pub(crate) fn as_file(&self) -> Result<&OsHandle> { match self { - Self::OsFile(file) => Ok(file), + Self::OsHandle(file) => Ok(file), _ => Err(Error::EBADF), } } - /// Like `as_actual_file`, but return a mutable reference. - pub(crate) fn as_actual_file_mut(&mut self) -> Result<&mut OsFile> { + /// Like `as_file`, but return a mutable reference. + pub(crate) fn as_file_mut(&mut self) -> Result<&mut OsHandle> { match self { - Self::OsFile(file) => Ok(file), + Self::OsHandle(file) => Ok(file), _ => Err(Error::EBADF), } } - /// Return an `OsFile`, which may be a stream or socket file descriptor. - pub(crate) fn as_file(&self) -> ManuallyDrop { - descriptor_as_osfile(self) + /// Return an `OsHandle`, which may be a stream or socket file descriptor. + pub(crate) fn as_os_handle(&self) -> ManuallyDrop { + descriptor_as_oshandle(self) } } @@ -62,7 +63,7 @@ impl FdEntry { unsafe { determine_type_and_access_rights(&file) }.map( |(file_type, rights_base, rights_inheriting)| Self { file_type, - descriptor: Descriptor::OsFile(OsFile::from(file)), + descriptor: Descriptor::OsHandle(OsHandle::from(file)), rights_base, rights_inheriting, preopen_path: None, diff --git a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs index 999fb9c9b10f..631c8b171b36 100644 --- a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs @@ -36,7 +36,7 @@ pub(crate) unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> R let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_DATASYNC, 0)? - .as_actual_file()?; + .as_file()?; fd.sync_data().map_err(Into::into) } @@ -62,7 +62,7 @@ pub(crate) unsafe fn fd_pread( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_READ | wasi::__WASI_RIGHTS_FD_SEEK, 0)? - .as_actual_file()?; + .as_file()?; let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?; @@ -114,7 +114,7 @@ pub(crate) unsafe fn fd_pwrite( wasi::__WASI_RIGHTS_FD_WRITE | wasi::__WASI_RIGHTS_FD_SEEK, 0, )? - .as_actual_file()?; + .as_file()?; let iovs = dec_ciovec_slice(memory, iovs_ptr, iovs_len)?; if offset > i64::max_value() as u64 { @@ -161,7 +161,7 @@ pub(crate) unsafe fn fd_read( .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READ, 0)? { - Descriptor::OsFile(file) => file.read_vectored(&mut iovs), + Descriptor::OsHandle(file) => file.read_vectored(&mut iovs), Descriptor::Stdin => io::stdin().lock().read_vectored(&mut iovs), _ => return Err(Error::EBADF), }; @@ -227,7 +227,7 @@ pub(crate) unsafe fn fd_seek( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(rights, 0)? - .as_actual_file_mut()?; + .as_file_mut()?; let pos = match whence { wasi::__WASI_WHENCE_CUR => SeekFrom::Current(offset), @@ -253,7 +253,7 @@ pub(crate) unsafe fn fd_tell( let fd = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_TELL, 0)? - .as_actual_file_mut()?; + .as_file_mut()?; let host_offset = fd.seek(SeekFrom::Current(0))?; @@ -271,7 +271,10 @@ pub(crate) unsafe fn fd_fdstat_get( trace!("fd_fdstat_get(fd={:?}, fdstat_ptr={:#x?})", fd, fdstat_ptr); let mut fdstat = dec_fdstat_byref(memory, fdstat_ptr)?; - let host_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); + let host_fd = wasi_ctx + .get_fd_entry(fd)? + .as_descriptor(0, 0)? + .as_os_handle(); let fs_flags = hostcalls_impl::fd_fdstat_get(&host_fd)?; @@ -293,7 +296,10 @@ pub(crate) unsafe fn fd_fdstat_set_flags( ) -> Result<()> { trace!("fd_fdstat_set_flags(fd={:?}, fdflags={:#x?})", fd, fdflags); - let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file(); + let fd = wasi_ctx + .get_fd_entry(fd)? + .as_descriptor(0, 0)? + .as_os_handle(); hostcalls_impl::fd_fdstat_set_flags(&fd, fdflags) } @@ -329,7 +335,7 @@ pub(crate) unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> Resul let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_SYNC, 0)? - .as_actual_file()?; + .as_file()?; fd.sync_all().map_err(Into::into) } @@ -357,7 +363,7 @@ pub(crate) unsafe fn fd_write( .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_WRITE, 0)? { - Descriptor::OsFile(file) => file.write_vectored(&iovs)?, + Descriptor::OsHandle(file) => file.write_vectored(&iovs)?, Descriptor::Stdin => return Err(Error::EBADF), Descriptor::Stdout => { // lock for the duration of the scope @@ -393,7 +399,7 @@ pub(crate) unsafe fn fd_advise( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ADVISE, 0)? - .as_actual_file()?; + .as_file()?; hostcalls_impl::fd_advise(fd, advice, offset, len) } @@ -409,7 +415,7 @@ pub(crate) unsafe fn fd_allocate( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_ALLOCATE, 0)? - .as_actual_file()?; + .as_file()?; let metadata = fd.metadata()?; @@ -593,7 +599,7 @@ pub(crate) unsafe fn fd_readdir( let file = wasi_ctx .get_fd_entry_mut(fd)? .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READDIR, 0)? - .as_actual_file_mut()?; + .as_file_mut()?; let host_buf = dec_slice_of_mut_u8(memory, buf, buf_len)?; trace!(" | (buf,buf_len)={:?}", host_buf); @@ -707,10 +713,7 @@ pub(crate) unsafe fn fd_filestat_get( filestat_ptr ); - let fd = wasi_ctx - .get_fd_entry(fd)? - .as_descriptor(0, 0)? - .as_actual_file()?; + let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; let host_filestat = hostcalls_impl::fd_filestat_get_impl(fd)?; @@ -737,7 +740,7 @@ pub(crate) unsafe fn fd_filestat_set_times( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_TIMES, 0)? - .as_actual_file()?; + .as_file()?; fd_filestat_set_times_impl(fd, st_atim, st_mtim, fst_flags) } @@ -788,7 +791,7 @@ pub(crate) unsafe fn fd_filestat_set_size( let fd = wasi_ctx .get_fd_entry(fd)? .as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_SET_SIZE, 0)? - .as_actual_file()?; + .as_file()?; // This check will be unnecessary when rust-lang/rust#63326 is fixed if st_size > i64::max_value() as u64 { diff --git a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs index 4ba2f3ed0875..3a26bfc54b0f 100644 --- a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs +++ b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs_helpers.rs @@ -46,7 +46,7 @@ pub(crate) fn path_get( let dirfd = fe .as_descriptor(rights_base, rights_inheriting)? - .as_actual_file()? + .as_file()? .try_clone()?; // Stack of directory file descriptors. Index 0 always corresponds with the directory provided diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/hostcalls_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/hostcalls_impl.rs index f42467198a50..d3647fb81b66 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/hostcalls_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/hostcalls_impl.rs @@ -1,4 +1,4 @@ -use super::osfile::OsFile; +use super::oshandle::OsHandle; use crate::old::snapshot_0::hostcalls_impl::PathGet; use crate::old::snapshot_0::sys::host_impl; use crate::old::snapshot_0::sys::unix::str_to_cstring; @@ -140,23 +140,23 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul } pub(crate) fn fd_readdir( - os_file: &mut OsFile, + os_handle: &mut OsHandle, host_buf: &mut [u8], cookie: wasi::__wasi_dircookie_t, ) -> Result { - use crate::old::snapshot_0::sys::unix::bsd::osfile::DirStream; + use crate::old::snapshot_0::sys::unix::bsd::oshandle::DirStream; use libc::{fdopendir, readdir, rewinddir, seekdir, telldir}; use nix::errno::Errno; use std::ffi::CStr; use std::mem::ManuallyDrop; use std::sync::Mutex; - let dir_stream = match os_file.dir_stream { + let dir_stream = match os_handle.dir_stream { Some(ref mut dir_stream) => dir_stream, None => { - let file = os_file.file.try_clone()?; + let file = os_handle.file.try_clone()?; let dir_ptr = unsafe { fdopendir(file.as_raw_fd()) }; - os_file.dir_stream.get_or_insert(Mutex::new(DirStream { + os_handle.dir_stream.get_or_insert(Mutex::new(DirStream { file: ManuallyDrop::new(file), dir_ptr, })) diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/mod.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/mod.rs index 4ba789dbc6f3..27d5442886d7 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/mod.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod filetime; pub(crate) mod hostcalls_impl; -pub(crate) mod osfile; +pub(crate) mod oshandle; pub(crate) mod fdentry_impl { use crate::old::snapshot_0::{sys::host_impl, Result}; diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/osfile.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/oshandle.rs similarity index 85% rename from crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/osfile.rs rename to crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/oshandle.rs index 41340149aa4e..3900ef8141ae 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/osfile.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/bsd/oshandle.rs @@ -17,12 +17,12 @@ impl Drop for DirStream { } #[derive(Debug)] -pub(crate) struct OsFile { +pub(crate) struct OsHandle { pub(crate) file: fs::File, pub(crate) dir_stream: Option>, } -impl From for OsFile { +impl From for OsHandle { fn from(file: fs::File) -> Self { Self { file, @@ -31,13 +31,13 @@ impl From for OsFile { } } -impl AsRawFd for OsFile { +impl AsRawFd for OsHandle { fn as_raw_fd(&self) -> RawFd { self.file.as_raw_fd() } } -impl Deref for OsFile { +impl Deref for OsHandle { type Target = fs::File; fn deref(&self) -> &Self::Target { @@ -45,7 +45,7 @@ impl Deref for OsFile { } } -impl DerefMut for OsFile { +impl DerefMut for OsHandle { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.file } diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs index 57aebfa78f1b..a3072f2c8d07 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs @@ -7,7 +7,7 @@ use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, RawFd}; cfg_if::cfg_if! { if #[cfg(target_os = "linux")] { - pub(crate) use super::linux::osfile::*; + pub(crate) use super::linux::oshandle::*; pub(crate) use super::linux::fdentry_impl::*; } else if #[cfg(any( target_os = "macos", @@ -17,7 +17,7 @@ cfg_if::cfg_if! { target_os = "ios", target_os = "dragonfly" ))] { - pub(crate) use super::bsd::osfile::*; + pub(crate) use super::bsd::oshandle::*; pub(crate) use super::bsd::fdentry_impl::*; } } @@ -25,7 +25,7 @@ cfg_if::cfg_if! { impl AsRawFd for Descriptor { fn as_raw_fd(&self) -> RawFd { match self { - Self::OsFile(file) => file.as_raw_fd(), + Self::OsHandle(file) => file.as_raw_fd(), Self::Stdin => io::stdin().as_raw_fd(), Self::Stdout => io::stdout().as_raw_fd(), Self::Stderr => io::stderr().as_raw_fd(), @@ -33,8 +33,10 @@ impl AsRawFd for Descriptor { } } -pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsFile::from(unsafe { File::from_raw_fd(desc.as_raw_fd()) })) +pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsHandle::from(unsafe { + File::from_raw_fd(desc.as_raw_fd()) + })) } /// This function is unsafe because it operates on a raw file descriptor. diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/mod.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/mod.rs index 4bfb6ec08f6e..e16410b61e82 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/mod.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod filetime; pub(crate) mod hostcalls_impl; -pub(crate) mod osfile; +pub(crate) mod oshandle; pub(crate) mod fdentry_impl { use crate::old::snapshot_0::{sys::host_impl, Result}; diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/osfile.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/oshandle.rs similarity index 72% rename from crates/wasi-common/src/old/snapshot_0/sys/unix/linux/osfile.rs rename to crates/wasi-common/src/old/snapshot_0/sys/unix/linux/oshandle.rs index b92a9793a69a..8104d9d5e38d 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/osfile.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/oshandle.rs @@ -3,21 +3,21 @@ use std::ops::{Deref, DerefMut}; use std::os::unix::prelude::{AsRawFd, RawFd}; #[derive(Debug)] -pub(crate) struct OsFile(fs::File); +pub(crate) struct OsHandle(fs::File); -impl From for OsFile { +impl From for OsHandle { fn from(file: fs::File) -> Self { Self(file) } } -impl AsRawFd for OsFile { +impl AsRawFd for OsHandle { fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } } -impl Deref for OsFile { +impl Deref for OsHandle { type Target = fs::File; fn deref(&self) -> &Self::Target { @@ -25,7 +25,7 @@ impl Deref for OsFile { } } -impl DerefMut for OsFile { +impl DerefMut for OsHandle { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } diff --git a/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs index 40597dffea5b..2c84d35e0f93 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs @@ -7,21 +7,21 @@ use std::ops::{Deref, DerefMut}; use std::os::windows::prelude::{AsRawHandle, FromRawHandle, RawHandle}; #[derive(Debug)] -pub(crate) struct OsFile(File); +pub(crate) struct OsHandle(File); -impl From for OsFile { +impl From for OsHandle { fn from(file: File) -> Self { Self(file) } } -impl AsRawHandle for OsFile { +impl AsRawHandle for OsHandle { fn as_raw_handle(&self) -> RawHandle { self.0.as_raw_handle() } } -impl Deref for OsFile { +impl Deref for OsHandle { type Target = File; fn deref(&self) -> &Self::Target { @@ -29,7 +29,7 @@ impl Deref for OsFile { } } -impl DerefMut for OsFile { +impl DerefMut for OsHandle { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } @@ -38,7 +38,7 @@ impl DerefMut for OsFile { impl AsRawHandle for Descriptor { fn as_raw_handle(&self) -> RawHandle { match self { - Self::OsFile(file) => file.as_raw_handle(), + Self::OsHandle(file) => file.as_raw_handle(), Self::Stdin => io::stdin().as_raw_handle(), Self::Stdout => io::stdout().as_raw_handle(), Self::Stderr => io::stderr().as_raw_handle(), @@ -46,8 +46,8 @@ impl AsRawHandle for Descriptor { } } -pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsFile::from(unsafe { +pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsHandle::from(unsafe { File::from_raw_handle(desc.as_raw_handle()) })) } diff --git a/crates/wasi-common/src/old/snapshot_0/sys/windows/hostcalls_impl/fs.rs b/crates/wasi-common/src/old/snapshot_0/sys/windows/hostcalls_impl/fs.rs index 3f3b9da7ace0..0a33e9056ee5 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/windows/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/windows/hostcalls_impl/fs.rs @@ -7,7 +7,7 @@ use crate::old::snapshot_0::helpers::systemtime_to_timestamp; use crate::old::snapshot_0::hostcalls_impl::{ fd_filestat_set_times_impl, Dirent, FileType, PathGet, }; -use crate::old::snapshot_0::sys::fdentry_impl::{determine_type_rights, OsFile}; +use crate::old::snapshot_0::sys::fdentry_impl::{determine_type_rights, OsHandle}; use crate::old::snapshot_0::sys::host_impl::{self, path_from_host}; use crate::old::snapshot_0::sys::hostcalls_impl::fs_helpers::PathGetExt; use crate::old::snapshot_0::{wasi, Error, Result}; @@ -261,11 +261,11 @@ pub(crate) fn fd_readdir_impl( // This should actually be common code with Linux pub(crate) fn fd_readdir( - os_file: &mut OsFile, + os_handle: &mut OsHandle, mut host_buf: &mut [u8], cookie: wasi::__wasi_dircookie_t, ) -> Result { - let iter = fd_readdir_impl(os_file, cookie)?; + let iter = fd_readdir_impl(os_handle, cookie)?; let mut used = 0; for dirent in iter { let dirent_raw = dirent?.to_wasi_raw()?; diff --git a/crates/wasi-common/src/sys/unix/bsd/hostcalls_impl.rs b/crates/wasi-common/src/sys/unix/bsd/hostcalls_impl.rs index 40cfcb480998..67194f02ac77 100644 --- a/crates/wasi-common/src/sys/unix/bsd/hostcalls_impl.rs +++ b/crates/wasi-common/src/sys/unix/bsd/hostcalls_impl.rs @@ -1,5 +1,5 @@ use super::super::dir::{Dir, Entry, SeekLoc}; -use super::osfile::OsFile; +use super::oshandle::OsHandle; use crate::hostcalls_impl::{Dirent, PathGet}; use crate::sys::host_impl; use crate::sys::unix::str_to_cstring; @@ -205,12 +205,12 @@ pub(crate) fn fd_advise( } pub(crate) fn fd_readdir<'a>( - os_file: &'a mut OsFile, + os_handle: &'a mut OsHandle, cookie: wasi::__wasi_dircookie_t, ) -> Result> + 'a> { use std::sync::Mutex; - let dir = match os_file.dir { + let dir = match os_handle.dir { Some(ref mut dir) => dir, None => { // We need to duplicate the fd, because `opendir(3)`: @@ -219,9 +219,9 @@ pub(crate) fn fd_readdir<'a>( // descriptor, or to modify the state of the associated description other // than by means of closedir(), readdir(), readdir_r(), or rewinddir(), // the behaviour is undefined. - let fd = (*os_file).try_clone()?; + let fd = (*os_handle).try_clone()?; let dir = Dir::from(fd)?; - os_file.dir.get_or_insert(Mutex::new(dir)) + os_handle.dir.get_or_insert(Mutex::new(dir)) } }; let mut dir = dir.lock().unwrap(); diff --git a/crates/wasi-common/src/sys/unix/bsd/mod.rs b/crates/wasi-common/src/sys/unix/bsd/mod.rs index e973751b77b2..4fe76b1be759 100644 --- a/crates/wasi-common/src/sys/unix/bsd/mod.rs +++ b/crates/wasi-common/src/sys/unix/bsd/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod filetime; pub(crate) mod hostcalls_impl; -pub(crate) mod osfile; +pub(crate) mod oshandle; pub(crate) mod fdentry_impl { use crate::{sys::host_impl, Result}; diff --git a/crates/wasi-common/src/sys/unix/bsd/osfile.rs b/crates/wasi-common/src/sys/unix/bsd/oshandle.rs similarity index 84% rename from crates/wasi-common/src/sys/unix/bsd/osfile.rs rename to crates/wasi-common/src/sys/unix/bsd/oshandle.rs index 379dcfdcedd4..eccc7ab33e2e 100644 --- a/crates/wasi-common/src/sys/unix/bsd/osfile.rs +++ b/crates/wasi-common/src/sys/unix/bsd/oshandle.rs @@ -5,9 +5,9 @@ use std::os::unix::prelude::{AsRawFd, RawFd}; use std::sync::Mutex; #[derive(Debug)] -pub(crate) struct OsFile { +pub(crate) struct OsHandle { pub(crate) file: fs::File, - // In case that this `OsFile` actually refers to a directory, + // In case that this `OsHandle` actually refers to a directory, // when the client makes a `fd_readdir` syscall on this descriptor, // we will need to cache the `libc::DIR` pointer manually in order // to be able to seek on it later. While on Linux, this is handled @@ -21,19 +21,19 @@ pub(crate) struct OsFile { pub(crate) dir: Option>, } -impl From for OsFile { +impl From for OsHandle { fn from(file: fs::File) -> Self { Self { file, dir: None } } } -impl AsRawFd for OsFile { +impl AsRawFd for OsHandle { fn as_raw_fd(&self) -> RawFd { self.file.as_raw_fd() } } -impl Deref for OsFile { +impl Deref for OsHandle { type Target = fs::File; fn deref(&self) -> &Self::Target { @@ -41,7 +41,7 @@ impl Deref for OsFile { } } -impl DerefMut for OsFile { +impl DerefMut for OsHandle { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.file } diff --git a/crates/wasi-common/src/sys/unix/fdentry_impl.rs b/crates/wasi-common/src/sys/unix/fdentry_impl.rs index fba32329f263..b80bc3e8ea4f 100644 --- a/crates/wasi-common/src/sys/unix/fdentry_impl.rs +++ b/crates/wasi-common/src/sys/unix/fdentry_impl.rs @@ -7,7 +7,7 @@ use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, RawFd}; cfg_if::cfg_if! { if #[cfg(target_os = "linux")] { - pub(crate) use super::linux::osfile::*; + pub(crate) use super::linux::oshandle::*; pub(crate) use super::linux::fdentry_impl::*; } else if #[cfg(any( target_os = "macos", @@ -17,7 +17,7 @@ cfg_if::cfg_if! { target_os = "ios", target_os = "dragonfly" ))] { - pub(crate) use super::bsd::osfile::*; + pub(crate) use super::bsd::oshandle::*; pub(crate) use super::bsd::fdentry_impl::*; } } @@ -25,7 +25,7 @@ cfg_if::cfg_if! { impl AsRawFd for Descriptor { fn as_raw_fd(&self) -> RawFd { match self { - Self::OsFile(file) => file.as_raw_fd(), + Self::OsHandle(file) => file.as_raw_fd(), Self::Stdin => io::stdin().as_raw_fd(), Self::Stdout => io::stdout().as_raw_fd(), Self::Stderr => io::stderr().as_raw_fd(), @@ -33,8 +33,10 @@ impl AsRawFd for Descriptor { } } -pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsFile::from(unsafe { File::from_raw_fd(desc.as_raw_fd()) })) +pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsHandle::from(unsafe { + File::from_raw_fd(desc.as_raw_fd()) + })) } /// This function is unsafe because it operates on a raw file descriptor. diff --git a/crates/wasi-common/src/sys/unix/linux/mod.rs b/crates/wasi-common/src/sys/unix/linux/mod.rs index 16b3555b5d76..32955b18c77d 100644 --- a/crates/wasi-common/src/sys/unix/linux/mod.rs +++ b/crates/wasi-common/src/sys/unix/linux/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod filetime; pub(crate) mod hostcalls_impl; -pub(crate) mod osfile; +pub(crate) mod oshandle; pub(crate) mod fdentry_impl { use crate::{sys::host_impl, Result}; diff --git a/crates/wasi-common/src/sys/unix/linux/osfile.rs b/crates/wasi-common/src/sys/unix/linux/oshandle.rs similarity index 72% rename from crates/wasi-common/src/sys/unix/linux/osfile.rs rename to crates/wasi-common/src/sys/unix/linux/oshandle.rs index b92a9793a69a..8104d9d5e38d 100644 --- a/crates/wasi-common/src/sys/unix/linux/osfile.rs +++ b/crates/wasi-common/src/sys/unix/linux/oshandle.rs @@ -3,21 +3,21 @@ use std::ops::{Deref, DerefMut}; use std::os::unix::prelude::{AsRawFd, RawFd}; #[derive(Debug)] -pub(crate) struct OsFile(fs::File); +pub(crate) struct OsHandle(fs::File); -impl From for OsFile { +impl From for OsHandle { fn from(file: fs::File) -> Self { Self(file) } } -impl AsRawFd for OsFile { +impl AsRawFd for OsHandle { fn as_raw_fd(&self) -> RawFd { self.0.as_raw_fd() } } -impl Deref for OsFile { +impl Deref for OsHandle { type Target = fs::File; fn deref(&self) -> &Self::Target { @@ -25,7 +25,7 @@ impl Deref for OsFile { } } -impl DerefMut for OsFile { +impl DerefMut for OsHandle { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } diff --git a/crates/wasi-common/src/sys/windows/fdentry_impl.rs b/crates/wasi-common/src/sys/windows/fdentry_impl.rs index ee6a06d7e64c..0d8045b352a7 100644 --- a/crates/wasi-common/src/sys/windows/fdentry_impl.rs +++ b/crates/wasi-common/src/sys/windows/fdentry_impl.rs @@ -7,21 +7,21 @@ use std::ops::{Deref, DerefMut}; use std::os::windows::prelude::{AsRawHandle, FromRawHandle, RawHandle}; #[derive(Debug)] -pub(crate) struct OsFile(File); +pub(crate) struct OsHandle(File); -impl From for OsFile { +impl From for OsHandle { fn from(file: File) -> Self { Self(file) } } -impl AsRawHandle for OsFile { +impl AsRawHandle for OsHandle { fn as_raw_handle(&self) -> RawHandle { self.0.as_raw_handle() } } -impl Deref for OsFile { +impl Deref for OsHandle { type Target = File; fn deref(&self) -> &Self::Target { @@ -29,7 +29,7 @@ impl Deref for OsFile { } } -impl DerefMut for OsFile { +impl DerefMut for OsHandle { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } @@ -38,7 +38,7 @@ impl DerefMut for OsFile { impl AsRawHandle for Descriptor { fn as_raw_handle(&self) -> RawHandle { match self { - Self::OsFile(file) => file.as_raw_handle(), + Self::OsHandle(file) => file.as_raw_handle(), Self::Stdin => io::stdin().as_raw_handle(), Self::Stdout => io::stdout().as_raw_handle(), Self::Stderr => io::stderr().as_raw_handle(), @@ -46,8 +46,8 @@ impl AsRawHandle for Descriptor { } } -pub(crate) fn descriptor_as_osfile(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsFile::from(unsafe { +pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { + ManuallyDrop::new(OsHandle::from(unsafe { File::from_raw_handle(desc.as_raw_handle()) })) } diff --git a/crates/wasi-common/src/sys/windows/hostcalls_impl/fs.rs b/crates/wasi-common/src/sys/windows/hostcalls_impl/fs.rs index d98c2a17aaef..4c8cfb269f35 100644 --- a/crates/wasi-common/src/sys/windows/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/sys/windows/hostcalls_impl/fs.rs @@ -5,7 +5,7 @@ use crate::ctx::WasiCtx; use crate::fdentry::FdEntry; use crate::helpers::systemtime_to_timestamp; use crate::hostcalls_impl::{fd_filestat_set_times_impl, Dirent, FileType, PathGet}; -use crate::sys::fdentry_impl::{determine_type_rights, OsFile}; +use crate::sys::fdentry_impl::determine_type_rights; use crate::sys::host_impl::{self, path_from_host}; use crate::sys::hostcalls_impl::fs_helpers::PathGetExt; use crate::{wasi, Error, Result}; From c1c5acaa81dd6a86cc8138b836ab3a581fdbffb0 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 27 Nov 2019 14:11:15 +0100 Subject: [PATCH 6/8] Fix compilation on Linux --- .../src/old/snapshot_0/sys/unix/linux/hostcalls_impl.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/hostcalls_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/hostcalls_impl.rs index deebe005ff4a..d582105ede46 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/hostcalls_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/linux/hostcalls_impl.rs @@ -1,5 +1,5 @@ use super::super::dir::{Dir, Entry, SeekLoc}; -use super::osfile::OsFile; +use super::oshandle::OsHandle; use crate::old::snapshot_0::hostcalls_impl::{Dirent, PathGet}; use crate::old::snapshot_0::sys::host_impl; use crate::old::snapshot_0::sys::unix::str_to_cstring; @@ -115,11 +115,11 @@ pub(crate) fn fd_readdir_impl( // This should actually be common code with Windows, // but there's BSD stuff remaining pub(crate) fn fd_readdir( - os_file: &mut OsFile, + os_handle: &mut OsHandle, mut host_buf: &mut [u8], cookie: wasi::__wasi_dircookie_t, ) -> Result { - let iter = fd_readdir_impl(os_file, cookie)?; + let iter = fd_readdir_impl(os_handle, cookie)?; let mut used = 0; for dirent in iter { let dirent_raw = dirent?.to_wasi_raw()?; From f52e1ef808b400204a41ad9129e8fce86ddcb350 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 27 Nov 2019 11:14:43 -0800 Subject: [PATCH 7/8] Introduce `OsHandleRef` for borrowing OS resources. To prevent a `ManuallyDrop` from outliving the resource it holds on to, create an `OsHandleRef` class parameterized on the lifetime of the `Descriptor`. --- crates/wasi-common/src/fdentry.rs | 36 ++++++++++++++++++- .../wasi-common/src/sys/unix/fdentry_impl.rs | 10 +++--- .../src/sys/windows/fdentry_impl.rs | 10 +++--- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/crates/wasi-common/src/fdentry.rs b/crates/wasi-common/src/fdentry.rs index 930e43ae82bc..21c7d8b33dfd 100644 --- a/crates/wasi-common/src/fdentry.rs +++ b/crates/wasi-common/src/fdentry.rs @@ -3,7 +3,9 @@ use crate::sys::fdentry_impl::{ descriptor_as_oshandle, determine_type_and_access_rights, OsHandle, }; use crate::{wasi, Error, Result}; +use std::marker::PhantomData; use std::mem::ManuallyDrop; +use std::ops::{Deref, DerefMut}; use std::path::PathBuf; use std::{fs, io}; @@ -35,7 +37,7 @@ impl Descriptor { } /// Return an `OsHandle`, which may be a stream or socket file descriptor. - pub(crate) fn as_os_handle(&self) -> ManuallyDrop { + pub(crate) fn as_os_handle<'descriptor>(&'descriptor self) -> OsHandleRef<'descriptor> { descriptor_as_oshandle(self) } } @@ -161,3 +163,35 @@ impl FdEntry { } } } + +/// This allows an `OsHandle` to be temporarily borrowed from a +/// `Descriptor`. The `Descriptor` continues to own the resource, +/// and `OsHandleRef`'s lifetime parameter ensures that it doesn't +/// outlive the `Descriptor`. +pub(crate) struct OsHandleRef<'descriptor> { + handle: ManuallyDrop, + _ref: PhantomData<&'descriptor Descriptor>, +} + +impl<'descriptor> OsHandleRef<'descriptor> { + pub fn new(handle: ManuallyDrop) -> Self { + OsHandleRef { + handle, + _ref: PhantomData, + } + } +} + +impl<'descriptor> Deref for OsHandleRef<'descriptor> { + type Target = fs::File; + + fn deref(&self) -> &Self::Target { + &self.handle + } +} + +impl<'descriptor> DerefMut for OsHandleRef<'descriptor> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.handle + } +} diff --git a/crates/wasi-common/src/sys/unix/fdentry_impl.rs b/crates/wasi-common/src/sys/unix/fdentry_impl.rs index b80bc3e8ea4f..8015eebf6f7e 100644 --- a/crates/wasi-common/src/sys/unix/fdentry_impl.rs +++ b/crates/wasi-common/src/sys/unix/fdentry_impl.rs @@ -1,4 +1,4 @@ -use crate::fdentry::Descriptor; +use crate::fdentry::{Descriptor, OsHandleRef}; use crate::{wasi, Error, Result}; use std::fs::File; use std::io; @@ -33,10 +33,12 @@ impl AsRawFd for Descriptor { } } -pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsHandle::from(unsafe { +pub(crate) fn descriptor_as_oshandle<'lifetime>( + desc: &'lifetime Descriptor, +) -> OsHandleRef<'lifetime> { + OsHandleRef::new(ManuallyDrop::new(OsHandle::from(unsafe { File::from_raw_fd(desc.as_raw_fd()) - })) + }))) } /// This function is unsafe because it operates on a raw file descriptor. diff --git a/crates/wasi-common/src/sys/windows/fdentry_impl.rs b/crates/wasi-common/src/sys/windows/fdentry_impl.rs index 0d8045b352a7..bb7b4263fcf4 100644 --- a/crates/wasi-common/src/sys/windows/fdentry_impl.rs +++ b/crates/wasi-common/src/sys/windows/fdentry_impl.rs @@ -1,4 +1,4 @@ -use crate::fdentry::Descriptor; +use crate::fdentry::{Descriptor, OsHandleRef}; use crate::{wasi, Error, Result}; use std::fs::File; use std::io; @@ -46,10 +46,12 @@ impl AsRawHandle for Descriptor { } } -pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsHandle::from(unsafe { +pub(crate) fn descriptor_as_oshandle<'lifetime>( + desc: &'lifetime Descriptor, +) -> OsHandleRef<'lifetime> { + OsHandleRef::new(ManuallyDrop::new(OsHandle::from(unsafe { File::from_raw_handle(desc.as_raw_handle()) - })) + }))) } /// This function is unsafe because it operates on a raw file handle. From 5d49e9d9a3222e34e2b91993ba723607dc5250c4 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 27 Nov 2019 23:15:53 +0100 Subject: [PATCH 8/8] Fix scoping to pub-priv and backport to snapshot_0 --- crates/wasi-common/src/fdentry.rs | 2 +- .../wasi-common/src/old/snapshot_0/fdentry.rs | 36 ++++++++++++++++++- .../old/snapshot_0/sys/unix/fdentry_impl.rs | 10 +++--- .../snapshot_0/sys/windows/fdentry_impl.rs | 10 +++--- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/crates/wasi-common/src/fdentry.rs b/crates/wasi-common/src/fdentry.rs index 21c7d8b33dfd..2bad6f79ab92 100644 --- a/crates/wasi-common/src/fdentry.rs +++ b/crates/wasi-common/src/fdentry.rs @@ -174,7 +174,7 @@ pub(crate) struct OsHandleRef<'descriptor> { } impl<'descriptor> OsHandleRef<'descriptor> { - pub fn new(handle: ManuallyDrop) -> Self { + pub(crate) fn new(handle: ManuallyDrop) -> Self { OsHandleRef { handle, _ref: PhantomData, diff --git a/crates/wasi-common/src/old/snapshot_0/fdentry.rs b/crates/wasi-common/src/old/snapshot_0/fdentry.rs index bc294db6ef8d..d6b69eed47fd 100644 --- a/crates/wasi-common/src/old/snapshot_0/fdentry.rs +++ b/crates/wasi-common/src/old/snapshot_0/fdentry.rs @@ -3,7 +3,9 @@ use crate::old::snapshot_0::sys::fdentry_impl::{ descriptor_as_oshandle, determine_type_and_access_rights, OsHandle, }; use crate::old::snapshot_0::{wasi, Error, Result}; +use std::marker::PhantomData; use std::mem::ManuallyDrop; +use std::ops::{Deref, DerefMut}; use std::path::PathBuf; use std::{fs, io}; @@ -35,7 +37,7 @@ impl Descriptor { } /// Return an `OsHandle`, which may be a stream or socket file descriptor. - pub(crate) fn as_os_handle(&self) -> ManuallyDrop { + pub(crate) fn as_os_handle<'descriptor>(&'descriptor self) -> OsHandleRef<'descriptor> { descriptor_as_oshandle(self) } } @@ -161,3 +163,35 @@ impl FdEntry { } } } + +/// This allows an `OsHandle` to be temporarily borrowed from a +/// `Descriptor`. The `Descriptor` continues to own the resource, +/// and `OsHandleRef`'s lifetime parameter ensures that it doesn't +/// outlive the `Descriptor`. +pub(crate) struct OsHandleRef<'descriptor> { + handle: ManuallyDrop, + _ref: PhantomData<&'descriptor Descriptor>, +} + +impl<'descriptor> OsHandleRef<'descriptor> { + pub(crate) fn new(handle: ManuallyDrop) -> Self { + OsHandleRef { + handle, + _ref: PhantomData, + } + } +} + +impl<'descriptor> Deref for OsHandleRef<'descriptor> { + type Target = fs::File; + + fn deref(&self) -> &Self::Target { + &self.handle + } +} + +impl<'descriptor> DerefMut for OsHandleRef<'descriptor> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.handle + } +} diff --git a/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs index a3072f2c8d07..3a628123d7b6 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/unix/fdentry_impl.rs @@ -1,4 +1,4 @@ -use crate::old::snapshot_0::fdentry::Descriptor; +use crate::old::snapshot_0::fdentry::{Descriptor, OsHandleRef}; use crate::old::snapshot_0::{wasi, Error, Result}; use std::fs::File; use std::io; @@ -33,10 +33,12 @@ impl AsRawFd for Descriptor { } } -pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsHandle::from(unsafe { +pub(crate) fn descriptor_as_oshandle<'lifetime>( + desc: &'lifetime Descriptor, +) -> OsHandleRef<'lifetime> { + OsHandleRef::new(ManuallyDrop::new(OsHandle::from(unsafe { File::from_raw_fd(desc.as_raw_fd()) - })) + }))) } /// This function is unsafe because it operates on a raw file descriptor. diff --git a/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs b/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs index 2c84d35e0f93..4b1c6ba39e96 100644 --- a/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs +++ b/crates/wasi-common/src/old/snapshot_0/sys/windows/fdentry_impl.rs @@ -1,4 +1,4 @@ -use crate::old::snapshot_0::fdentry::Descriptor; +use crate::old::snapshot_0::fdentry::{Descriptor, OsHandleRef}; use crate::old::snapshot_0::{wasi, Error, Result}; use std::fs::File; use std::io; @@ -46,10 +46,12 @@ impl AsRawHandle for Descriptor { } } -pub(crate) fn descriptor_as_oshandle(desc: &Descriptor) -> ManuallyDrop { - ManuallyDrop::new(OsHandle::from(unsafe { +pub(crate) fn descriptor_as_oshandle<'lifetime>( + desc: &'lifetime Descriptor, +) -> OsHandleRef<'lifetime> { + OsHandleRef::new(ManuallyDrop::new(OsHandle::from(unsafe { File::from_raw_handle(desc.as_raw_handle()) - })) + }))) } /// This function is unsafe because it operates on a raw file handle.