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:
Jakub Konka
2019-12-09 01:40:05 +01:00
committed by Dan Gohman
parent ec8144b87d
commit 51f880f625
54 changed files with 2383 additions and 2031 deletions

View File

@@ -0,0 +1,46 @@
use crate::{
dir::{Dir, Entry, EntryExt, SeekLoc},
Errno, Result,
};
use std::ops::Deref;
#[derive(Copy, Clone, Debug)]
pub(crate) struct EntryImpl(libc::dirent64);
impl Deref for EntryImpl {
type Target = libc::dirent64;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl EntryExt for Entry {
fn ino(&self) -> u64 {
self.0.d_ino.into()
}
fn seek_loc(&self) -> SeekLoc {
unsafe { SeekLoc::from_raw(self.0.d_off) }
}
}
pub(crate) unsafe fn iter_impl(dir: &Dir) -> Option<Result<EntryImpl>> {
let errno = Errno::last();
let dirent = libc::readdir64(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)))
}
}

View File

@@ -0,0 +1,22 @@
use crate::{Errno, Result};
use std::os::unix::prelude::*;
#[derive(Debug, Copy, Clone)]
#[repr(i32)]
pub enum PosixFadviseAdvice {
Normal = libc::POSIX_FADV_NORMAL,
Sequential = libc::POSIX_FADV_SEQUENTIAL,
Random = libc::POSIX_FADV_RANDOM,
NoReuse = libc::POSIX_FADV_NOREUSE,
WillNeed = libc::POSIX_FADV_WILLNEED,
DontNeed = libc::POSIX_FADV_DONTNEED,
}
pub unsafe fn posix_fadvise(
fd: RawFd,
offset: libc::off_t,
len: libc::off_t,
advice: PosixFadviseAdvice,
) -> Result<()> {
Errno::from_success_code(libc::posix_fadvise(fd, offset, len, advice as libc::c_int))
}

View File

@@ -0,0 +1,23 @@
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();
// While POSIX specifies ENOTTY if the passed
// fd is *not* a tty, on Linux, some implementations
// may return EINVAL instead.
//
// https://linux.die.net/man/3/isatty
if errno == Errno::ENOTTY || errno == Errno::EINVAL {
Ok(false)
} else {
Err(errno.into())
}
}
}

View File

@@ -0,0 +1,3 @@
pub(crate) mod dir;
pub(crate) mod fadvise;
pub(crate) mod file;