mod argument;
pub mod fuse_abi;
pub(crate) mod reply;
mod request;
use std::{convert::TryInto, num::NonZeroI32, time::SystemTime};
pub use reply::Response;
pub use request::{
AnyRequest, FileHandle, INodeNo, Lock, Operation, Request, RequestError, RequestId, Version,
};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum TimeOrNow {
SpecificTime(SystemTime),
Now,
}
macro_rules! errno {
($x: expr) => {
Errno(unsafe {
const _X: [(); 0 - !{
const ASSERT: bool = ($x > 0);
ASSERT
} as usize] = [];
NonZeroI32::new_unchecked($x)
})
};
}
#[derive(Debug)]
pub struct Errno(pub NonZeroI32);
impl Errno {
pub const EPERM: Errno = errno!(libc::EPERM);
pub const ENOENT: Errno = errno!(libc::ENOENT);
pub const ESRCH: Errno = errno!(libc::ESRCH);
pub const EINTR: Errno = errno!(libc::EINTR);
pub const EIO: Errno = errno!(libc::EIO);
pub const ENXIO: Errno = errno!(libc::ENXIO);
pub const E2BIG: Errno = errno!(libc::E2BIG);
pub const ENOEXEC: Errno = errno!(libc::ENOEXEC);
pub const EBADF: Errno = errno!(libc::EBADF);
pub const ECHILD: Errno = errno!(libc::ECHILD);
pub const EAGAIN: Errno = errno!(libc::EAGAIN);
pub const ENOMEM: Errno = errno!(libc::ENOMEM);
pub const EACCES: Errno = errno!(libc::EACCES);
pub const EFAULT: Errno = errno!(libc::EFAULT);
pub const ENOTBLK: Errno = errno!(libc::ENOTBLK);
pub const EBUSY: Errno = errno!(libc::EBUSY);
pub const EEXIST: Errno = errno!(libc::EEXIST);
pub const EXDEV: Errno = errno!(libc::EXDEV);
pub const ENODEV: Errno = errno!(libc::ENODEV);
pub const ENOTDIR: Errno = errno!(libc::ENOTDIR);
pub const EISDIR: Errno = errno!(libc::EISDIR);
pub const EINVAL: Errno = errno!(libc::EINVAL);
pub const ENFILE: Errno = errno!(libc::ENFILE);
pub const EMFILE: Errno = errno!(libc::EMFILE);
pub const ENOTTY: Errno = errno!(libc::ENOTTY);
pub const ETXTBSY: Errno = errno!(libc::ETXTBSY);
pub const EFBIG: Errno = errno!(libc::EFBIG);
pub const ENOSPC: Errno = errno!(libc::ENOSPC);
pub const ESPIPE: Errno = errno!(libc::ESPIPE);
pub const EROFS: Errno = errno!(libc::EROFS);
pub const EMLINK: Errno = errno!(libc::EMLINK);
pub const EPIPE: Errno = errno!(libc::EPIPE);
pub const EDOM: Errno = errno!(libc::EDOM);
pub const ERANGE: Errno = errno!(libc::ERANGE);
pub const EDEADLK: Errno = errno!(libc::EDEADLK);
pub const ENAMETOOLONG: Errno = errno!(libc::ENAMETOOLONG);
pub const ENOLCK: Errno = errno!(libc::ENOLCK);
pub const ENOSYS: Errno = errno!(libc::ENOSYS);
pub const ENOTEMPTY: Errno = errno!(libc::ENOTEMPTY);
pub const ELOOP: Errno = errno!(libc::ELOOP);
pub const EWOULDBLOCK: Errno = errno!(libc::EWOULDBLOCK);
pub const ENOMSG: Errno = errno!(libc::ENOMSG);
pub const EIDRM: Errno = errno!(libc::EIDRM);
pub const EREMOTE: Errno = errno!(libc::EREMOTE);
pub const ENOLINK: Errno = errno!(libc::ENOLINK);
pub const EPROTO: Errno = errno!(libc::EPROTO);
pub const EMULTIHOP: Errno = errno!(libc::EMULTIHOP);
pub const EBADMSG: Errno = errno!(libc::EBADMSG);
pub const EOVERFLOW: Errno = errno!(libc::EOVERFLOW);
pub const EILSEQ: Errno = errno!(libc::EILSEQ);
pub const EUSERS: Errno = errno!(libc::EUSERS);
pub const ENOTSOCK: Errno = errno!(libc::ENOTSOCK);
pub const EDESTADDRREQ: Errno = errno!(libc::EDESTADDRREQ);
pub const EMSGSIZE: Errno = errno!(libc::EMSGSIZE);
pub const EPROTOTYPE: Errno = errno!(libc::EPROTOTYPE);
pub const ENOPROTOOPT: Errno = errno!(libc::ENOPROTOOPT);
pub const EPROTONOSUPPORT: Errno = errno!(libc::EPROTONOSUPPORT);
pub const ESOCKTNOSUPPORT: Errno = errno!(libc::ESOCKTNOSUPPORT);
pub const EOPNOTSUPP: Errno = errno!(libc::EOPNOTSUPP);
pub const EPFNOSUPPORT: Errno = errno!(libc::EPFNOSUPPORT);
pub const EAFNOSUPPORT: Errno = errno!(libc::EAFNOSUPPORT);
pub const EADDRINUSE: Errno = errno!(libc::EADDRINUSE);
pub const EADDRNOTAVAIL: Errno = errno!(libc::EADDRNOTAVAIL);
pub const ENETDOWN: Errno = errno!(libc::ENETDOWN);
pub const ENETUNREACH: Errno = errno!(libc::ENETUNREACH);
pub const ENETRESET: Errno = errno!(libc::ENETRESET);
pub const ECONNABORTED: Errno = errno!(libc::ECONNABORTED);
pub const ECONNRESET: Errno = errno!(libc::ECONNRESET);
pub const ENOBUFS: Errno = errno!(libc::ENOBUFS);
pub const EISCONN: Errno = errno!(libc::EISCONN);
pub const ENOTCONN: Errno = errno!(libc::ENOTCONN);
pub const ESHUTDOWN: Errno = errno!(libc::ESHUTDOWN);
pub const ETOOMANYREFS: Errno = errno!(libc::ETOOMANYREFS);
pub const ETIMEDOUT: Errno = errno!(libc::ETIMEDOUT);
pub const ECONNREFUSED: Errno = errno!(libc::ECONNREFUSED);
pub const EHOSTDOWN: Errno = errno!(libc::EHOSTDOWN);
pub const EHOSTUNREACH: Errno = errno!(libc::EHOSTUNREACH);
pub const EALREADY: Errno = errno!(libc::EALREADY);
pub const EINPROGRESS: Errno = errno!(libc::EINPROGRESS);
pub const ESTALE: Errno = errno!(libc::ESTALE);
pub const EDQUOT: Errno = errno!(libc::EDQUOT);
pub const ECANCELED: Errno = errno!(libc::ECANCELED);
pub const EOWNERDEAD: Errno = errno!(libc::EOWNERDEAD);
pub const ENOTRECOVERABLE: Errno = errno!(libc::ENOTRECOVERABLE);
pub const ENOTSUP: Errno = errno!(libc::ENOTSUP);
#[cfg(target_os = "linux")]
pub const ENODATA: Errno = errno!(libc::ENODATA);
#[cfg(not(target_os = "linux"))]
pub const ENOATTR: Errno = errno!(libc::ENOATTR);
#[cfg(target_os = "linux")]
pub const NO_XATTR: Errno = Self::ENODATA;
#[cfg(not(target_os = "linux"))]
pub const NO_XATTR: Errno = Self::ENOATTR;
pub fn from_i32(err: i32) -> Errno {
err.try_into().ok().map(Errno).unwrap_or(Errno::EIO)
}
}
impl From<std::io::Error> for Errno {
fn from(err: std::io::Error) -> Self {
let errno = err.raw_os_error().unwrap_or(0);
match errno.try_into() {
Ok(i) => Errno(i),
Err(_) => Errno::EIO,
}
}
}
impl From<std::io::ErrorKind> for Errno {
fn from(x: std::io::ErrorKind) -> Self {
let err: std::io::Error = x.into();
err.into()
}
}
impl From<Errno> for i32 {
fn from(x: Errno) -> Self {
x.0.into()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Generation(pub u64);
impl From<Generation> for u64 {
fn from(fh: Generation) -> Self {
fh.0
}
}
#[cfg(test)]
mod test {
use std::ops::{Deref, DerefMut};
#[cfg(test)]
#[repr(align(8))]
pub(crate) struct AlignedData<T>(pub T);
impl<T> Deref for AlignedData<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for AlignedData<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
}