]> git.proxmox.com Git - pve-lxc-syscalld.git/blob - src/tools.rs
prepare to drop Fd type for OwnedFd (std io_safety)
[pve-lxc-syscalld.git] / src / tools.rs
1 //! Various utilities.
2 //!
3 //! Note that this should stay small, otherwise we should introduce a dependency on our `proxmox`
4 //! crate as that's where we have all this stuff usually...
5
6 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
7
8 pub fn set_fd_nonblocking<T: AsRawFd + ?Sized>(fd: &T, on: bool) -> nix::Result<libc::c_int> {
9 use nix::fcntl;
10 let fd = fd.as_raw_fd();
11 let mut flags = fcntl::OFlag::from_bits(fcntl::fcntl(fd, fcntl::FcntlArg::F_GETFL)?).unwrap();
12 flags.set(fcntl::OFlag::O_NONBLOCK, on);
13 fcntl::fcntl(fd, fcntl::FcntlArg::F_SETFL(flags))
14 }
15
16 /// Guard a raw file descriptor with a drop handler. This is mostly useful when access to an owned
17 /// `RawFd` is required without the corresponding handler object (such as when only the file
18 /// descriptor number is required in a closure which may be dropped instead of being executed).
19 #[repr(transparent)]
20 pub struct Fd(pub RawFd);
21
22 file_descriptor_impl!(Fd);
23
24 impl FromRawFd for Fd {
25 unsafe fn from_raw_fd(fd: RawFd) -> Self {
26 Self(fd)
27 }
28 }
29
30 impl Fd {
31 pub fn set_nonblocking(&mut self, nb: bool) -> nix::Result<libc::c_int> {
32 set_fd_nonblocking(self, nb)
33 }
34 }
35
36 impl AsRef<RawFd> for Fd {
37 #[inline]
38 fn as_ref(&self) -> &RawFd {
39 &self.0
40 }
41 }
42
43 /// Byte vector utilities.
44 pub mod vec {
45 /// Create an uninitialized byte vector of a specific size.
46 ///
47 /// This is just a shortcut for:
48 /// ```no_run
49 /// # let len = 64usize;
50 /// let mut v = Vec::<u8>::with_capacity(len);
51 /// unsafe {
52 /// v.set_len(len);
53 /// }
54 /// ```
55 ///
56 /// # Safety
57 ///
58 /// This is generally safe to call, but the contents of the vector are undefined.
59 #[inline]
60 pub unsafe fn uninitialized(len: usize) -> Vec<u8> {
61 unsafe {
62 let data = std::alloc::alloc(std::alloc::Layout::array::<u8>(len).unwrap());
63 Vec::from_raw_parts(data as *mut u8, len, len)
64 }
65 }
66 }
67
68 pub trait FromFd {
69 fn from_fd<T: IntoRawFd>(fd: T) -> Self;
70 }
71
72 impl<T: FromRawFd> FromFd for T {
73 fn from_fd<F: IntoRawFd>(fd: F) -> Self {
74 unsafe { Self::from_raw_fd(fd.into_raw_fd()) }
75 }
76 }
77
78 /// This is totally unsafe. Only use this when you know what you're doing.
79 #[derive(Debug, Clone)]
80 #[repr(transparent)]
81 pub struct AssertSendSync<T>(pub T);
82 unsafe impl<T> Send for AssertSendSync<T> {}
83 unsafe impl<T> Sync for AssertSendSync<T> {}