Add a typesafe enum for file type

This commit is contained in:
Marcin Mielniczuk
2019-10-03 15:21:43 +02:00
committed by Jakub Konka
parent 5dad532a43
commit 968fb19f17
4 changed files with 49 additions and 28 deletions

View File

@@ -1062,3 +1062,23 @@ pub(crate) unsafe fn fd_prestat_dir_name(
enc_slice_of(memory, path.as_bytes(), path_ptr)
})
}
#[allow(dead_code)] // trouble with sockets
#[derive(Clone, Copy, Debug)]
#[repr(u8)]
pub(crate) enum FileType {
Unknown = host::__WASI_FILETYPE_UNKNOWN,
BlockDevice = host::__WASI_FILETYPE_BLOCK_DEVICE,
CharacterDevice = host::__WASI_FILETYPE_CHARACTER_DEVICE,
Directory = host::__WASI_FILETYPE_DIRECTORY,
RegularFile = host::__WASI_FILETYPE_REGULAR_FILE,
SocketDgram = host::__WASI_FILETYPE_SOCKET_DGRAM,
SocketStream = host::__WASI_FILETYPE_SOCKET_STREAM,
Symlink = host::__WASI_FILETYPE_SYMBOLIC_LINK,
}
impl FileType {
pub(crate) fn to_wasi(&self) -> host::__wasi_filetype_t {
*self as host::__wasi_filetype_t
}
}

View File

@@ -2,6 +2,7 @@
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]
use crate::hostcalls_impl::FileType;
use crate::{host, memory, Error, Result};
use log::warn;
use std::ffi::OsStr;
@@ -156,22 +157,22 @@ pub(crate) fn nix_from_oflags(oflags: host::__wasi_oflags_t) -> nix::fcntl::OFla
nix_flags
}
pub(crate) fn filetype_from_nix(sflags: nix::sys::stat::SFlag) -> host::__wasi_filetype_t {
pub(crate) fn filetype_from_nix(sflags: nix::sys::stat::SFlag) -> FileType {
use nix::sys::stat::SFlag;
if sflags.contains(SFlag::S_IFCHR) {
host::__WASI_FILETYPE_CHARACTER_DEVICE
FileType::CharacterDevice
} else if sflags.contains(SFlag::S_IFBLK) {
host::__WASI_FILETYPE_BLOCK_DEVICE
FileType::BlockDevice
} else if sflags.contains(SFlag::S_IFSOCK) {
host::__WASI_FILETYPE_SOCKET_STREAM
FileType::SocketStream
} else if sflags.contains(SFlag::S_IFDIR) {
host::__WASI_FILETYPE_DIRECTORY
FileType::Directory
} else if sflags.contains(SFlag::S_IFREG) {
host::__WASI_FILETYPE_REGULAR_FILE
FileType::RegularFile
} else if sflags.contains(SFlag::S_IFLNK) {
host::__WASI_FILETYPE_SYMBOLIC_LINK
FileType::Symlink
} else {
host::__WASI_FILETYPE_UNKNOWN
FileType::Unknown
}
}
@@ -200,7 +201,7 @@ pub(crate) fn filestat_from_nix(
st_atim,
st_ctim,
st_mtim,
st_filetype: filetype_from_nix(filetype),
st_filetype: filetype_from_nix(filetype).to_wasi(),
})
}

View File

@@ -2,7 +2,7 @@
#![allow(unused_unsafe)]
use super::fs_helpers::*;
use crate::helpers::systemtime_to_timestamp;
use crate::hostcalls_impl::PathGet;
use crate::hostcalls_impl::{FileType, PathGet};
use crate::sys::host_impl;
use crate::{host, Error, Result};
use nix::libc;
@@ -219,35 +219,35 @@ pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_
st_atim: systemtime_to_timestamp(metadata.accessed()?)?,
st_ctim: metadata.ctime().try_into()?, // i64 doesn't fit into u64
st_mtim: systemtime_to_timestamp(metadata.modified()?)?,
st_filetype: filetype(file, &metadata)?,
st_filetype: filetype(file, &metadata)?.to_wasi(),
})
}
fn filetype(file: &File, metadata: &Metadata) -> Result<host::__wasi_filetype_t> {
fn filetype(file: &File, metadata: &Metadata) -> Result<FileType> {
use nix::sys::socket::{self, SockType};
use std::os::unix::fs::FileTypeExt;
let ftype = metadata.file_type();
if ftype.is_file() {
Ok(host::__WASI_FILETYPE_REGULAR_FILE)
Ok(FileType::RegularFile)
} else if ftype.is_dir() {
Ok(host::__WASI_FILETYPE_DIRECTORY)
Ok(FileType::Directory)
} else if ftype.is_symlink() {
Ok(host::__WASI_FILETYPE_SYMBOLIC_LINK)
Ok(FileType::Symlink)
} else if ftype.is_char_device() {
Ok(host::__WASI_FILETYPE_CHARACTER_DEVICE)
Ok(FileType::CharacterDevice)
} else if ftype.is_block_device() {
Ok(host::__WASI_FILETYPE_BLOCK_DEVICE)
Ok(FileType::BlockDevice)
} else if ftype.is_socket() {
match socket::getsockopt(file.as_raw_fd(), socket::sockopt::SockType)
.map_err(|err| err.as_errno().unwrap())
.map_err(host_impl::errno_from_nix)?
{
SockType::Datagram => Ok(host::__WASI_FILETYPE_SOCKET_DGRAM),
SockType::Stream => Ok(host::__WASI_FILETYPE_SOCKET_STREAM),
_ => Ok(host::__WASI_FILETYPE_UNKNOWN),
SockType::Datagram => Ok(FileType::SocketDgram),
SockType::Stream => Ok(FileType::SocketStream),
_ => Ok(FileType::Unknown),
}
} else {
Ok(host::__WASI_FILETYPE_UNKNOWN)
Ok(FileType::Unknown)
}
}

View File

@@ -4,7 +4,7 @@ use super::fs_helpers::*;
use crate::ctx::WasiCtx;
use crate::fdentry::FdEntry;
use crate::helpers::systemtime_to_timestamp;
use crate::hostcalls_impl::{fd_filestat_set_times_impl, PathGet};
use crate::hostcalls_impl::{fd_filestat_set_times_impl, FileType, PathGet};
use crate::sys::fdentry_impl::{determine_type_rights, OsFile};
use crate::sys::host_impl;
use crate::sys::hostcalls_impl::fs_helpers::PathGetExt;
@@ -286,20 +286,20 @@ pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_
st_atim: systemtime_to_timestamp(metadata.accessed()?)?,
st_ctim: change_time(file, &metadata)?.try_into()?, // i64 doesn't fit into u64
st_mtim: systemtime_to_timestamp(metadata.modified()?)?,
st_filetype: filetype(file, &metadata)?,
st_filetype: filetype(file, &metadata)?.to_wasi(),
})
}
fn filetype(_file: &File, metadata: &Metadata) -> Result<host::__wasi_filetype_t> {
fn filetype(_file: &File, metadata: &Metadata) -> Result<FileType> {
let ftype = metadata.file_type();
let ret = if ftype.is_file() {
host::__WASI_FILETYPE_REGULAR_FILE
FileType::RegularFile
} else if ftype.is_dir() {
host::__WASI_FILETYPE_DIRECTORY
FileType::Directory
} else if ftype.is_symlink() {
host::__WASI_FILETYPE_SYMBOLIC_LINK
FileType::Symlink
} else {
host::__WASI_FILETYPE_UNKNOWN
FileType::Unknown
};
Ok(ret)