Skip to content
This repository has been archived by the owner on Nov 9, 2019. It is now read-only.

Commit

Permalink
Refactor the change for two separate fd_filestat_get_impl
Browse files Browse the repository at this point in the history
  • Loading branch information
marmistrz committed Jul 26, 2019
1 parent f6a3680 commit e1f42b2
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 65 deletions.
10 changes: 10 additions & 0 deletions src/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::{host, Result};
use std::convert::TryInto;
use std::time::{SystemTime, UNIX_EPOCH};
pub(crate) fn systemtime_to_timestamp(st: SystemTime) -> Result<u64> {
st.duration_since(UNIX_EPOCH)
.map_err(|_| host::__WASI_EINVAL)? // date earlier than UNIX_EPOCH
.as_nanos()
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW) // u128 doesn't fit into u64
}
46 changes: 2 additions & 44 deletions src/hostcalls_impl/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::fdentry::{Descriptor, FdEntry};
use crate::memory::*;
use crate::sys::{errno_from_host, host_impl, hostcalls_impl};
use crate::{host, wasm32, Result};
use log::{debug, trace};
use log::trace;
use std::io::{self, Read, Seek, SeekFrom, Write};

pub(crate) fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> Result<()> {
Expand Down Expand Up @@ -730,55 +730,13 @@ pub(crate) fn fd_filestat_get(
.get_fd_entry(fd, 0, 0)
.and_then(|fe| fe.fd_object.descriptor.as_file())?;

let host_filestat = fd_filestat_get_impl(fd)?;
let host_filestat = hostcalls_impl::fd_filestat_get_impl(fd)?;

trace!(" | *filestat_ptr={:?}", host_filestat);

enc_filestat_byref(memory, filestat_ptr, host_filestat)
}

fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> {
use std::convert::TryInto;
use std::time::{SystemTime, UNIX_EPOCH};

fn convert_err(e: io::Error) -> host::__wasi_errno_t {
debug!("fd_filestat_get: os error: {}", e);
e.raw_os_error().map_or(host::__WASI_EIO, errno_from_host)
}

fn timestamp(st: SystemTime) -> Result<u64> {
st.duration_since(UNIX_EPOCH)
.map_err(|_| host::__WASI_EINVAL)? // date earlier than UNIX_EPOCH
.as_nanos()
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW) // u128 doesn't fit into u64
}

let metadata = file.metadata().map_err(convert_err)?;
Ok(host::__wasi_filestat_t {
st_dev: hostcalls_impl::device_id(file, &metadata).map_err(convert_err)?,
st_ino: hostcalls_impl::file_serial_no(file, &metadata).map_err(convert_err)?,
st_nlink: hostcalls_impl::num_hardlinks(file, &metadata)
.map_err(convert_err)?
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW)?, // u64 doesn't fit into u32
st_size: metadata.len(),
st_atim: metadata
.accessed()
.map_err(convert_err)
.and_then(timestamp)?,
st_ctim: hostcalls_impl::change_time(file, &metadata)
.map_err(convert_err)?
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW)?, // i64 doesn't fit into u64
st_mtim: metadata
.modified()
.map_err(convert_err)
.and_then(timestamp)?,
st_filetype: hostcalls_impl::filetype(&metadata).map_err(convert_err)?,
})
}

pub(crate) fn fd_filestat_set_times(
wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

mod ctx;
mod fdentry;
mod helpers;
mod hostcalls_impl;
mod sys;
#[macro_use]
Expand Down
53 changes: 33 additions & 20 deletions src/sys/unix/hostcalls_impl/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
use super::fs_helpers::*;
use crate::ctx::WasiCtx;
use crate::fdentry::FdEntry;
use crate::helpers::systemtime_to_timestamp;
use crate::sys::errno_from_host;
use crate::sys::fdentry_impl::determine_type_rights;
use crate::sys::host_impl;
use crate::{host, wasm32, Result};
use nix::libc::{self, c_long, c_void, off_t};
use std::convert::TryInto;
use std::ffi::CString;
use std::fs::{File, Metadata};
use std::io;
Expand Down Expand Up @@ -357,25 +359,43 @@ pub(crate) fn path_rename(
}
}

pub(crate) fn num_hardlinks(_file: &File, metadata: &Metadata) -> io::Result<u64> {
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> {
use std::os::unix::fs::MetadataExt;
Ok(metadata.nlink())
}

pub(crate) fn device_id(_file: &File, metadata: &Metadata) -> io::Result<u64> {
use std::os::unix::fs::MetadataExt;
Ok(metadata.dev())
}
fn convert_err(e: io::Error) -> host::__wasi_errno_t {
log::debug!("fd_filestat_get: os error: {}", e);
e.raw_os_error().map_or(host::__WASI_EIO, errno_from_host)
}

pub(crate) fn file_serial_no(_file: &File, metadata: &Metadata) -> io::Result<u64> {
use std::os::unix::fs::MetadataExt;
Ok(metadata.ino())
let metadata = file.metadata().map_err(convert_err)?;
Ok(host::__wasi_filestat_t {
st_dev: metadata.dev(),
st_ino: metadata.ino(),
st_nlink: metadata
.nlink()
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW)?, // u64 doesn't fit into u32
st_size: metadata.len(),
st_atim: metadata
.accessed()
.map_err(convert_err)
.and_then(systemtime_to_timestamp)?,
st_ctim: metadata
.ctime()
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW)?, // i64 doesn't fit into u64
st_mtim: metadata
.modified()
.map_err(convert_err)
.and_then(systemtime_to_timestamp)?,
st_filetype: filetype(&metadata),
})
}

pub(crate) fn filetype(metadata: &Metadata) -> io::Result<host::__wasi_filetype_t> {
fn filetype(metadata: &Metadata) -> host::__wasi_filetype_t {
use std::os::unix::fs::FileTypeExt;
let ftype = metadata.file_type();
let ret = if ftype.is_file() {
if ftype.is_file() {
host::__WASI_FILETYPE_REGULAR_FILE
} else if ftype.is_dir() {
host::__WASI_FILETYPE_DIRECTORY
Expand All @@ -391,14 +411,7 @@ pub(crate) fn filetype(metadata: &Metadata) -> io::Result<host::__wasi_filetype_
host::__WASI_FILETYPE_SOCKET_STREAM
} else {
host::__WASI_FILETYPE_UNKNOWN
};

Ok(ret)
}

pub(crate) fn change_time(_file: &File, metadata: &Metadata) -> io::Result<i64> {
use std::os::unix::fs::MetadataExt;
Ok(metadata.ctime())
}
}

pub(crate) fn fd_filestat_set_times(
Expand Down
35 changes: 34 additions & 1 deletion src/sys/windows/hostcalls_impl/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
use super::fs_helpers::*;
use crate::ctx::WasiCtx;
use crate::fdentry::FdEntry;
use crate::helpers::systemtime_to_timestamp;
use crate::sys::errno_from_host;
use crate::sys::fdentry_impl::determine_type_rights;
use crate::sys::host_impl;
use crate::{host, Result};
use std::convert::TryInto;
use std::fs::{File, Metadata};
use std::io::{self, Seek, SeekFrom};
use std::os::windows::fs::FileExt;
Expand Down Expand Up @@ -193,7 +195,38 @@ pub(crate) fn change_time(file: &File, _metadata: &Metadata) -> io::Result<i64>
winx::file::change_time(file)
}

pub(crate) fn filetype(metadata: &Metadata) -> io::Result<host::__wasi_filetype_t> {
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> {
fn convert_err(e: io::Error) -> host::__wasi_errno_t {
log::debug!("fd_filestat_get: os error: {}", e);
e.raw_os_error().map_or(host::__WASI_EIO, errno_from_host)
}

let metadata = file.metadata().map_err(convert_err)?;
Ok(host::__wasi_filestat_t {
st_dev: device_id(file, &metadata).map_err(convert_err)?,
st_ino: file_serial_no(file, &metadata).map_err(convert_err)?,
st_nlink: num_hardlinks(file, &metadata)
.map_err(convert_err)?
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW)?, // u64 doesn't fit into u32
st_size: metadata.len(),
st_atim: metadata
.accessed()
.map_err(convert_err)
.and_then(systemtime_to_timestamp)?,
st_ctim: change_time(file, &metadata)
.map_err(convert_err)?
.try_into()
.map_err(|_| host::__WASI_EOVERFLOW)?, // i64 doesn't fit into u64
st_mtim: metadata
.modified()
.map_err(convert_err)
.and_then(systemtime_to_timestamp)?,
st_filetype: filetype(&metadata).map_err(convert_err)?,
})
}

fn filetype(metadata: &Metadata) -> io::Result<host::__wasi_filetype_t> {
let ftype = metadata.file_type();
let ret = if ftype.is_file() {
host::__WASI_FILETYPE_REGULAR_FILE
Expand Down

0 comments on commit e1f42b2

Please sign in to comment.