use std::{
io,
os::{fd::AsFd, unix::io::AsRawFd},
};
use crate::common::CapRights;
#[repr(u32)]
#[derive(Debug)]
pub enum Fcntl {
GetFL = libc::CAP_FCNTL_GETFL,
SetFL = libc::CAP_FCNTL_SETFL,
GetOwn = libc::CAP_FCNTL_GETOWN,
SetOwn = libc::CAP_FCNTL_SETOWN,
}
#[derive(Debug, Default)]
#[deprecated(since = "0.4.0", note = "Use FcntlRights directly")]
pub struct FcntlsBuilder(u32);
#[allow(deprecated)]
impl FcntlsBuilder {
#[allow(missing_docs)]
pub fn new(right: Fcntl) -> FcntlsBuilder {
FcntlsBuilder(right as u32)
}
#[allow(missing_docs)]
pub fn add(&mut self, right: Fcntl) -> &mut FcntlsBuilder {
self.0 |= right as u32;
self
}
pub fn finalize(&self) -> FcntlRights {
FcntlRights(self.0)
}
#[allow(missing_docs)]
#[deprecated(
since = "0.4.0",
note = "If you still need this method, please file an issue at https://github.com/dlrobertson/capsicum-rs/issues"
)]
pub fn raw(&self) -> u32 {
self.0
}
#[allow(missing_docs)]
pub fn remove(&mut self, right: Fcntl) -> &mut FcntlsBuilder {
self.0 &= !(right as u32);
self
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct FcntlRights(u32);
impl FcntlRights {
pub fn new() -> FcntlRights {
FcntlRights::default()
}
pub fn allow(&mut self, right: Fcntl) -> &mut Self {
self.0 |= right as u32;
self
}
pub fn deny(&mut self, right: Fcntl) -> &mut Self {
self.0 &= !(right as u32);
self
}
pub fn from_file<F: AsFd>(f: &F) -> io::Result<FcntlRights> {
unsafe {
let mut empty_fcntls = 0;
let fd = f.as_fd().as_raw_fd();
let res = libc::cap_fcntls_get(fd, &mut empty_fcntls as *mut u32);
if res < 0 {
Err(io::Error::last_os_error())
} else {
Ok(FcntlRights(empty_fcntls))
}
}
}
}
impl CapRights for FcntlRights {
fn limit<F: AsFd>(&self, fd: &F) -> io::Result<()> {
unsafe {
if libc::cap_fcntls_limit(fd.as_fd().as_raw_fd(), self.0) < 0 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}
}
}