use std::os::raw::c_int;
use errno::errno;
use libc::{prctl, syscall};
use crate::Error;
use crate::ffi::{Data, Header};
#[derive(Copy, Clone, Debug)]
pub struct Cmd(c_int);
impl Cmd {
pub const AMBIENT_RAISE: Cmd = Self(libc::PR_CAP_AMBIENT_RAISE);
pub const AMBIENT_LOWER: Cmd = Self(libc::PR_CAP_AMBIENT_LOWER);
pub const AMBIENT_IS_SET: Cmd = Self(libc::PR_CAP_AMBIENT_IS_SET);
pub const AMBIENT_CLEAR_ALL: Cmd = Self(libc::PR_CAP_AMBIENT_CLEAR_ALL);
pub const BOUNDING_READ: Cmd = Self(libc::PR_CAPBSET_READ);
pub const BOUNDING_DROP: Cmd = Self(libc::PR_CAPBSET_DROP);
}
pub fn ambient(cmd: Cmd, cap: impl Into<c_int>) -> Result<c_int, Error> {
unsafe {
match prctl(libc::PR_CAP_AMBIENT, cmd.0, cap.into(), 0, 0) {
n @ 0..=1 => Ok(n),
_ => Err(error()),
}
}
}
pub fn bounding(cmd: Cmd, cap: impl Into<c_int>) -> Result<c_int, Error> {
unsafe {
match prctl(cmd.0, cap.into(), 0, 0, 0) {
n @ 0..=1 => Ok(n),
_ => Err(error()),
}
}
}
pub fn capget(head: &Header, data: &mut [Data]) -> Result<(), Error> {
unsafe {
match syscall(libc::SYS_capget, head, data.as_mut_ptr()) {
0 => Ok(()),
_ => Err(error()),
}
}
}
pub fn capset(head: &Header, data: &[Data]) -> Result<(), Error> {
unsafe {
match syscall(libc::SYS_capset, head, data.as_ptr()) {
0 => Ok(()),
_ => Err(error()),
}
}
}
fn error() -> Error {
Error::from(errno())
}