Implement fd_filestat_get for all platforms (#42)
* Implement fd_filestat_get for all platforms * Remove an old comment * Remove panics from the syscall wrappers * Return WASI error type * Reuse Metadata if possible to save syscalls. * Refactor the change for two separate fd_filestat_get_impl * Refactor error handling
This commit is contained in:
committed by
Jakub Konka
parent
e759e3c2a4
commit
89fbde2c3f
@@ -3,11 +3,13 @@
|
||||
use super::fs_helpers::*;
|
||||
use crate::ctx::WasiCtx;
|
||||
use crate::fdentry::FdEntry;
|
||||
use crate::sys::errno_from_host;
|
||||
use crate::helpers::systemtime_to_timestamp;
|
||||
use crate::sys::{errno_from_ioerror, errno_from_host};
|
||||
use crate::sys::fdentry_impl::determine_type_rights;
|
||||
use crate::sys::host_impl;
|
||||
use crate::{host, Result};
|
||||
use std::fs::File;
|
||||
use std::convert::TryInto;
|
||||
use std::fs::{File, Metadata};
|
||||
use std::io::{self, Seek, SeekFrom};
|
||||
use std::os::windows::fs::FileExt;
|
||||
use std::os::windows::prelude::{AsRawHandle, FromRawHandle};
|
||||
@@ -173,8 +175,65 @@ pub(crate) fn path_rename(
|
||||
unimplemented!("path_rename")
|
||||
}
|
||||
|
||||
pub(crate) fn fd_filestat_get(fd: &File) -> Result<host::__wasi_filestat_t> {
|
||||
unimplemented!("fd_filestat_get")
|
||||
pub(crate) fn num_hardlinks(file: &File, _metadata: &Metadata) -> io::Result<u64> {
|
||||
Ok(winx::file::get_fileinfo(file)?.nNumberOfLinks.into())
|
||||
}
|
||||
|
||||
pub(crate) fn device_id(file: &File, _metadata: &Metadata) -> io::Result<u64> {
|
||||
Ok(winx::file::get_fileinfo(file)?.dwVolumeSerialNumber.into())
|
||||
}
|
||||
|
||||
pub(crate) fn file_serial_no(file: &File, _metadata: &Metadata) -> io::Result<u64> {
|
||||
let info = winx::file::get_fileinfo(file)?;
|
||||
let high = info.nFileIndexHigh;
|
||||
let low = info.nFileIndexLow;
|
||||
let no = ((high as u64) << 32) | (low as u64);
|
||||
Ok(no)
|
||||
}
|
||||
|
||||
pub(crate) fn change_time(file: &File, _metadata: &Metadata) -> io::Result<i64> {
|
||||
winx::file::change_time(file)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> {
|
||||
let metadata = file.metadata().map_err(errno_from_ioerror)?;
|
||||
Ok(host::__wasi_filestat_t {
|
||||
st_dev: device_id(file, &metadata).map_err(errno_from_ioerror)?,
|
||||
st_ino: file_serial_no(file, &metadata).map_err(errno_from_ioerror)?,
|
||||
st_nlink: num_hardlinks(file, &metadata)
|
||||
.map_err(errno_from_ioerror)?
|
||||
.try_into()
|
||||
.map_err(|_| host::__WASI_EOVERFLOW)?, // u64 doesn't fit into u32
|
||||
st_size: metadata.len(),
|
||||
st_atim: metadata
|
||||
.accessed()
|
||||
.map_err(errno_from_ioerror)
|
||||
.and_then(systemtime_to_timestamp)?,
|
||||
st_ctim: change_time(file, &metadata)
|
||||
.map_err(errno_from_ioerror)?
|
||||
.try_into()
|
||||
.map_err(|_| host::__WASI_EOVERFLOW)?, // i64 doesn't fit into u64
|
||||
st_mtim: metadata
|
||||
.modified()
|
||||
.map_err(errno_from_ioerror)
|
||||
.and_then(systemtime_to_timestamp)?,
|
||||
st_filetype: filetype(&metadata).map_err(errno_from_ioerror)?,
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
} else if ftype.is_dir() {
|
||||
host::__WASI_FILETYPE_DIRECTORY
|
||||
} else if ftype.is_symlink() {
|
||||
host::__WASI_FILETYPE_SYMBOLIC_LINK
|
||||
} else {
|
||||
host::__WASI_FILETYPE_UNKNOWN
|
||||
};
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_filestat_set_times(
|
||||
|
||||
Reference in New Issue
Block a user