]> git.proxmox.com Git - pve-lxc-syscalld.git/blob - src/nsfd.rs
blocking fixup, and actually recvmsg on recvmsg
[pve-lxc-syscalld.git] / src / nsfd.rs
1 use std::ffi::CStr;
2 use std::io;
3 use std::marker::PhantomData;
4 use std::os::raw::c_int;
5 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
6
7 pub mod ns_type {
8 pub trait NsType {
9 const TYPE: libc::c_int;
10 }
11
12 macro_rules! define_ns_type {
13 ($name:ident, $number:expr) => {
14 pub struct $name;
15 impl NsType for $name {
16 const TYPE: libc::c_int = $number;
17 }
18 };
19 }
20
21 define_ns_type!(Mount, libc::CLONE_NEWNS);
22 define_ns_type!(User, libc::CLONE_NEWUSER);
23 define_ns_type!(Cgroup, libc::CLONE_NEWCGROUP);
24 }
25
26 pub use ns_type::NsType;
27
28 file_descriptor_type!(RawNsFd);
29
30 impl RawNsFd {
31 pub fn open(path: &CStr) -> io::Result<Self> {
32 Self::openat(libc::AT_FDCWD, path)
33 }
34
35 pub fn openat(fd: RawFd, path: &CStr) -> io::Result<Self> {
36 let fd =
37 c_try!(unsafe { libc::openat(fd, path.as_ptr(), libc::O_RDONLY | libc::O_CLOEXEC) });
38
39 Ok(Self(fd))
40 }
41
42 pub fn setns(&self, ns_type: c_int) -> io::Result<()> {
43 c_try!(unsafe { libc::setns(self.0, ns_type) });
44 Ok(())
45 }
46 }
47
48 #[repr(transparent)]
49 pub struct NsFd<T: NsType>(RawNsFd, PhantomData<T>);
50
51 impl<T: NsType> std::ops::Deref for NsFd<T> {
52 type Target = RawNsFd;
53
54 fn deref(&self) -> &Self::Target {
55 &self.0
56 }
57 }
58
59 impl<T: NsType> NsFd<T> {
60 pub fn open(path: &CStr) -> io::Result<Self> {
61 Ok(Self(RawNsFd::open(path)?, PhantomData))
62 }
63
64 pub fn openat(fd: RawFd, path: &CStr) -> io::Result<Self> {
65 Ok(Self(RawNsFd::openat(fd, path)?, PhantomData))
66 }
67
68 pub fn setns(&self) -> io::Result<()> {
69 self.0.setns(T::TYPE)
70 }
71 }