#![allow(unsafe_code)]
use crate::buffer::Buffer;
use crate::{backend, ffi, io, path};
use backend::c;
use backend::fd::AsFd;
use bitflags::bitflags;
bitflags! {
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct XattrFlags: ffi::c_uint {
const CREATE = c::XATTR_CREATE as c::c_uint;
const REPLACE = c::XATTR_REPLACE as c::c_uint;
const _ = !0;
}
}
#[inline]
pub fn getxattr<P: path::Arg, Name: path::Arg, Buf: Buffer<u8>>(
path: P,
name: Name,
mut value: Buf,
) -> io::Result<Buf::Output> {
path.into_with_c_str(|path| {
name.into_with_c_str(|name| {
let len = unsafe { backend::fs::syscalls::getxattr(path, name, value.parts_mut())? };
unsafe { Ok(value.assume_init(len)) }
})
})
}
#[inline]
pub fn lgetxattr<P: path::Arg, Name: path::Arg, Buf: Buffer<u8>>(
path: P,
name: Name,
mut value: Buf,
) -> io::Result<Buf::Output> {
path.into_with_c_str(|path| {
name.into_with_c_str(|name| {
let len = unsafe { backend::fs::syscalls::lgetxattr(path, name, value.parts_mut())? };
unsafe { Ok(value.assume_init(len)) }
})
})
}
#[inline]
pub fn fgetxattr<Fd: AsFd, Name: path::Arg, Buf: Buffer<u8>>(
fd: Fd,
name: Name,
mut value: Buf,
) -> io::Result<Buf::Output> {
name.into_with_c_str(|name| {
let len = unsafe { backend::fs::syscalls::fgetxattr(fd.as_fd(), name, value.parts_mut())? };
unsafe { Ok(value.assume_init(len)) }
})
}
#[inline]
pub fn setxattr<P: path::Arg, Name: path::Arg>(
path: P,
name: Name,
value: &[u8],
flags: XattrFlags,
) -> io::Result<()> {
path.into_with_c_str(|path| {
name.into_with_c_str(|name| backend::fs::syscalls::setxattr(path, name, value, flags))
})
}
#[inline]
pub fn lsetxattr<P: path::Arg, Name: path::Arg>(
path: P,
name: Name,
value: &[u8],
flags: XattrFlags,
) -> io::Result<()> {
path.into_with_c_str(|path| {
name.into_with_c_str(|name| backend::fs::syscalls::lsetxattr(path, name, value, flags))
})
}
#[inline]
pub fn fsetxattr<Fd: AsFd, Name: path::Arg>(
fd: Fd,
name: Name,
value: &[u8],
flags: XattrFlags,
) -> io::Result<()> {
name.into_with_c_str(|name| backend::fs::syscalls::fsetxattr(fd.as_fd(), name, value, flags))
}
#[inline]
pub fn listxattr<P: path::Arg, Buf: Buffer<u8>>(path: P, mut list: Buf) -> io::Result<Buf::Output> {
path.into_with_c_str(|path| {
let len = unsafe { backend::fs::syscalls::listxattr(path, list.parts_mut())? };
unsafe { Ok(list.assume_init(len)) }
})
}
#[inline]
pub fn llistxattr<P: path::Arg, Buf: Buffer<u8>>(
path: P,
mut list: Buf,
) -> io::Result<Buf::Output> {
path.into_with_c_str(|path| {
let len = unsafe { backend::fs::syscalls::llistxattr(path, list.parts_mut())? };
unsafe { Ok(list.assume_init(len)) }
})
}
#[inline]
pub fn flistxattr<Fd: AsFd, Buf: Buffer<u8>>(fd: Fd, mut list: Buf) -> io::Result<Buf::Output> {
let len = unsafe { backend::fs::syscalls::flistxattr(fd.as_fd(), list.parts_mut())? };
unsafe { Ok(list.assume_init(len)) }
}
pub fn removexattr<P: path::Arg, Name: path::Arg>(path: P, name: Name) -> io::Result<()> {
path.into_with_c_str(|path| {
name.into_with_c_str(|name| backend::fs::syscalls::removexattr(path, name))
})
}
pub fn lremovexattr<P: path::Arg, Name: path::Arg>(path: P, name: Name) -> io::Result<()> {
path.into_with_c_str(|path| {
name.into_with_c_str(|name| backend::fs::syscalls::lremovexattr(path, name))
})
}
pub fn fremovexattr<Fd: AsFd, Name: path::Arg>(fd: Fd, name: Name) -> io::Result<()> {
name.into_with_c_str(|name| backend::fs::syscalls::fremovexattr(fd.as_fd(), name))
}