Add yanix crate and replace nix with yanix in wasi-common (#649)
* Add yanix crate This commit adds `yanix` crate as a Unix dependency for `wasi-common`. `yanix` stands for Yet Another Nix crate and is exactly what the name suggests: a crate in the spirit of the `nix` crate, but which takes a different approach, using lower-level interfaces with less abstraction, so that it fits better with its main use case, implementation of WASI syscalls. * Replace nix with yanix crate Having introduced `yanix` crate as an in-house replacement for the `nix` crate, this commit makes the necessary changes to `wasi-common` to depend _only_ on `yanix` crate. * Address review comments * make `fd_dup` unsafe * rename `get_fd` to `get_fd_flags`, etc. * reuse `io::Error::last_os_error()` to get the last errno value * Address more comments * make all `fcntl` fns unsafe * adjust `wasi-common` impl appropriately * Make all fns operating on RawFd unsafe * Fix linux build * Address more comments
This commit is contained in:
52
crates/wasi-common/yanix/src/sys/bsd/dir.rs
Normal file
52
crates/wasi-common/yanix/src/sys/bsd/dir.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use crate::{
|
||||
dir::{Dir, Entry, EntryExt, SeekLoc},
|
||||
Errno, Result,
|
||||
};
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) struct EntryImpl {
|
||||
dirent: libc::dirent,
|
||||
loc: SeekLoc,
|
||||
}
|
||||
|
||||
impl Deref for EntryImpl {
|
||||
type Target = libc::dirent;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.dirent
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn iter_impl(dir: &Dir) -> Option<Result<EntryImpl>> {
|
||||
let errno = Errno::last();
|
||||
let dirent = libc::readdir(dir.0.as_ptr());
|
||||
if dirent.is_null() {
|
||||
if errno != Errno::last() {
|
||||
// TODO This should be verified on different BSD-flavours.
|
||||
//
|
||||
// According to 4.3BSD/POSIX.1-2001 man pages, there was an error
|
||||
// if the errno value has changed at some point during the sequence
|
||||
// of readdir calls.
|
||||
Some(Err(Errno::last().into()))
|
||||
} else {
|
||||
// Not an error. We've simply reached the end of the stream.
|
||||
None
|
||||
}
|
||||
} else {
|
||||
Some(Ok(EntryImpl {
|
||||
dirent: *dirent,
|
||||
loc: dir.tell(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl EntryExt for Entry {
|
||||
fn ino(&self) -> u64 {
|
||||
self.0.d_ino.into()
|
||||
}
|
||||
|
||||
fn seek_loc(&self) -> SeekLoc {
|
||||
self.0.loc
|
||||
}
|
||||
}
|
||||
51
crates/wasi-common/yanix/src/sys/bsd/fadvise.rs
Normal file
51
crates/wasi-common/yanix/src/sys/bsd/fadvise.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use crate::{Errno, Result};
|
||||
use std::{convert::TryInto, os::unix::prelude::*};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(i32)]
|
||||
pub enum PosixFadviseAdvice {
|
||||
Normal,
|
||||
Sequential,
|
||||
Random,
|
||||
NoReuse,
|
||||
WillNeed,
|
||||
DontNeed,
|
||||
}
|
||||
|
||||
// There's no posix_fadvise on macOS but we can use fcntl with F_RDADVISE
|
||||
// command instead to achieve the same
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub unsafe fn posix_fadvise(
|
||||
fd: RawFd,
|
||||
offset: libc::off_t,
|
||||
len: libc::off_t,
|
||||
_advice: PosixFadviseAdvice,
|
||||
) -> Result<()> {
|
||||
// From macOS man pages:
|
||||
// F_RDADVISE Issue an advisory read async with no copy to user.
|
||||
//
|
||||
// The F_RDADVISE command operates on the following structure which holds information passed from
|
||||
// the user to the system:
|
||||
//
|
||||
// struct radvisory {
|
||||
// off_t ra_offset; /* offset into the file */
|
||||
// int ra_count; /* size of the read */
|
||||
// };
|
||||
let advisory = libc::radvisory {
|
||||
ra_offset: offset,
|
||||
ra_count: len.try_into()?,
|
||||
};
|
||||
Errno::from_success_code(libc::fcntl(fd, libc::F_RDADVISE, &advisory))
|
||||
}
|
||||
|
||||
// TODO
|
||||
// On non-macOS BSD's we leave it as no-op for now
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
|
||||
pub unsafe fn posix_fadvise(
|
||||
_fd: RawFd,
|
||||
_offset: libc::off_t,
|
||||
_len: libc::off_t,
|
||||
_advice: PosixFadviseAdvice,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
18
crates/wasi-common/yanix/src/sys/bsd/file.rs
Normal file
18
crates/wasi-common/yanix/src/sys/bsd/file.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
use crate::{Errno, Result};
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
pub unsafe fn isatty(fd: RawFd) -> Result<bool> {
|
||||
let res = libc::isatty(fd);
|
||||
if res == 1 {
|
||||
// isatty() returns 1 if fd is an open file descriptor referring to a terminal...
|
||||
Ok(true)
|
||||
} else {
|
||||
// ... otherwise 0 is returned, and errno is set to indicate the error.
|
||||
let errno = Errno::last();
|
||||
if errno == Errno::ENOTTY {
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(errno.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
3
crates/wasi-common/yanix/src/sys/bsd/mod.rs
Normal file
3
crates/wasi-common/yanix/src/sys/bsd/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub(crate) mod dir;
|
||||
pub(crate) mod fadvise;
|
||||
pub(crate) mod file;
|
||||
Reference in New Issue
Block a user