let pid = c_try!(unsafe { libc::fork() });
if pid == 0 {
drop(pipe_r);
- let mut pipe_w = pipe_w.into_fd();
+ let pipe_w = pipe_w.into_fd();
let _ = std::panic::catch_unwind(move || {
- pipe_w.set_nonblocking(false).unwrap();
+ crate::tools::set_fd_nonblocking(&pipe_w, false).unwrap();
let mut pipe_w = unsafe { std::fs::File::from_raw_fd(pipe_w.into_raw_fd()) };
let out = match func() {
Ok(SyscallStatus::Ok(val)) => Data {
use std::io;
-use std::os::unix::io::{AsRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, OwnedFd, RawFd};
use tokio::io::unix::AsyncFd;
-use crate::tools::Fd;
-
pub mod cmsg;
pub mod pipe;
pub mod rw_traits;
pub mod seq_packet;
-pub async fn wrap_read<R, F>(async_fd: &AsyncFd<Fd>, mut call: F) -> io::Result<R>
+pub async fn wrap_read<R, F>(async_fd: &AsyncFd<OwnedFd>, mut call: F) -> io::Result<R>
where
F: FnMut(RawFd) -> io::Result<R>,
{
}
}
-pub async fn wrap_write<R, F>(async_fd: &AsyncFd<Fd>, mut call: F) -> io::Result<R>
+pub async fn wrap_write<R, F>(async_fd: &AsyncFd<OwnedFd>, mut call: F) -> io::Result<R>
where
F: FnMut(RawFd) -> io::Result<R>,
{
use std::convert::{TryFrom, TryInto};
use std::io;
use std::marker::PhantomData;
-use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use crate::io::rw_traits;
-use crate::tools::Fd;
pub use rw_traits::{Read, Write};
/// from the reactor, which will just break.
///
/// So we start out with this type which can be "upgraded" or "downgraded" into a `Pipe<T>` or
-/// `Fd`.
-pub struct PipeFd<RW>(Fd, PhantomData<RW>);
+/// `OwnedFd`.
+pub struct PipeFd<RW>(OwnedFd, PhantomData<RW>);
impl<RW> PipeFd<RW> {
- pub fn new(fd: Fd) -> Self {
+ pub fn new(fd: OwnedFd) -> Self {
Self(fd, PhantomData)
}
- pub fn into_fd(self) -> Fd {
+ pub fn into_fd(self) -> OwnedFd {
self.0
}
}
c_try!(unsafe { libc::pipe2(pfd.as_mut_ptr(), libc::O_CLOEXEC) });
- let (fd_in, fd_out) = unsafe { (Fd::from_raw_fd(pfd[0]), Fd::from_raw_fd(pfd[1])) };
+ let (fd_in, fd_out) = unsafe { (OwnedFd::from_raw_fd(pfd[0]), OwnedFd::from_raw_fd(pfd[1])) };
Ok((PipeFd::new(fd_in), PipeFd::new(fd_out)))
}
/// Tokio supported pipe file descriptor. `tokio::fs::File` requires tokio's complete file system
/// feature gate, so we just use this `AsyncFd` wrapper.
pub struct Pipe<RW> {
- fd: AsyncFd<Fd>,
+ fd: AsyncFd<OwnedFd>,
_phantom: PhantomData<RW>,
}
use std::io::{self, IoSlice, IoSliceMut};
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
use std::ptr;
use anyhow::Error;
use tokio::io::unix::AsyncFd;
use crate::tools::AssertSendSync;
-use crate::tools::Fd;
-fn seq_packet_socket(flags: SockFlag) -> nix::Result<Fd> {
+fn seq_packet_socket(flags: SockFlag) -> nix::Result<OwnedFd> {
let fd = socket::socket(
AddressFamily::Unix,
SockType::SeqPacket,
flags | SockFlag::SOCK_CLOEXEC,
None,
)?;
- Ok(unsafe { Fd::from_raw_fd(fd) })
+ Ok(unsafe { OwnedFd::from_raw_fd(fd) })
}
pub struct SeqPacketListener {
- fd: AsyncFd<Fd>,
+ fd: AsyncFd<OwnedFd>,
}
impl AsRawFd for SeqPacketListener {
})
.await?;
- let fd = unsafe { Fd::from_raw_fd(fd as RawFd) };
+ let fd = unsafe { OwnedFd::from_raw_fd(fd as RawFd) };
SeqPacketSocket::new(fd)
}
}
pub struct SeqPacketSocket {
- fd: AsyncFd<Fd>,
+ fd: AsyncFd<OwnedFd>,
}
impl AsRawFd for SeqPacketSocket {
}
impl SeqPacketSocket {
- pub fn new(fd: Fd) -> io::Result<Self> {
+ pub fn new(fd: OwnedFd) -> io::Result<Self> {
Ok(Self {
fd: AsyncFd::new(fd)?,
})
use std::mem;
use std::os::raw::{c_int, c_uint};
use std::os::unix::fs::FileExt;
-use std::os::unix::io::{FromRawFd, RawFd};
+use std::os::unix::io::{FromRawFd, OwnedFd, RawFd};
use anyhow::{bail, format_err, Error};
use lazy_static::lazy_static;
use crate::io::seq_packet::SeqPacketSocket;
use crate::process::PidFd;
use crate::seccomp::{SeccompNotif, SeccompNotifResp, SeccompNotifSizes};
-use crate::tools::{Fd, FromFd};
+use crate::tools::FromFd;
/// Seccomp notification proxy message sent by the lxc monitor.
///
bail!("expected SCM_RIGHTS control message");
}
- let fds: Vec<Fd> = cmsg
+ let fds: Vec<OwnedFd> = cmsg
.data
.chunks_exact(mem::size_of::<RawFd>())
.map(|chunk| unsafe {
// clippy bug
#[allow(clippy::cast_ptr_alignment)]
- Fd::from_raw_fd(std::ptr::read_unaligned(chunk.as_ptr() as _))
+ OwnedFd::from_raw_fd(std::ptr::read_unaligned(chunk.as_ptr() as _))
})
.collect();
/// Checked way to get a file descriptor argument.
#[inline]
- pub fn arg_fd(&self, arg: u32, flags: c_int) -> Result<Fd, Error> {
+ pub fn arg_fd(&self, arg: u32, flags: c_int) -> Result<OwnedFd, Error> {
let fd = self.arg(arg)? as RawFd;
// we pass negative ones 'as-is', others get opened via the pidfd
Ok(if fd == libc::AT_FDCWD {
// might want to reuse this one?
self.pid_fd().fd_cwd()?
} else if fd < 0 {
- Fd(fd)
+ unsafe { OwnedFd::from_raw_fd(fd) }
} else {
self.pid_fd().fd_num(fd, flags)?
})
use std::io::{self, BufRead, BufReader};
use std::os::raw::c_int;
use std::os::unix::ffi::OsStringExt;
-use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use anyhow::{bail, Error};
use libc::pid_t;
use crate::capability::Capabilities;
use crate::error::io_err_other;
use crate::nsfd::{ns_type, NsFd};
-use crate::tools::Fd;
use super::{CGroups, IdMap, IdMapEntry, ProcStatus, Uids, UserCaps};
///
/// The file descriptor must already be a valid pidfd, this is not checked. This function only
/// fails if reading the pid from the pidfd's proc entry fails.
- pub unsafe fn try_from_fd(fd: Fd) -> io::Result<Self> {
+ pub unsafe fn try_from_fd(fd: OwnedFd) -> io::Result<Self> {
#[allow(clippy::unnecessary_cast)] // pid_t is a type alias
let mut this = Self(fd.into_raw_fd(), -1 as pid_t);
let pid = this.read_pid()?;
NsFd::openat(self.0, c_str!("ns/user"))
}
- fn fd(&self, path: &CStr, flags: c_int, mode: c_int) -> io::Result<Fd> {
- Ok(Fd(c_try!(unsafe {
- libc::openat(
+ fn fd(&self, path: &CStr, flags: c_int, mode: c_int) -> io::Result<OwnedFd> {
+ Ok(unsafe {
+ OwnedFd::from_raw_fd(c_try!(libc::openat(
self.as_raw_fd(),
path.as_ptr() as *const _,
flags | libc::O_CLOEXEC,
mode,
- )
- })))
+ )))
+ })
}
- pub fn fd_cwd(&self) -> io::Result<Fd> {
+ pub fn fd_cwd(&self) -> io::Result<OwnedFd> {
self.fd(c_str!("cwd"), libc::O_DIRECTORY, 0)
}
- pub fn fd_num(&self, num: RawFd, flags: c_int) -> io::Result<Fd> {
+ pub fn fd_num(&self, num: RawFd, flags: c_int) -> io::Result<OwnedFd> {
let path = format!("fd/{}\0", num);
self.fd(
unsafe { CStr::from_bytes_with_nul_unchecked(path.as_bytes()) },
use std::ffi::CString;
-use std::os::unix::io::AsRawFd;
+use std::os::unix::io::{AsRawFd, OwnedFd};
use anyhow::Error;
use nix::errno::Errno;
use crate::process::PidFd;
use crate::sc_libc_try;
use crate::syscall::SyscallStatus;
-use crate::tools::Fd;
pub async fn mknod(msg: &ProxyMessageBuffer) -> Result<SyscallStatus, Error> {
let mode = msg.arg_mode_t(1)?;
async fn do_mknodat(
pidfd: &PidFd,
- dirfd: Fd,
+ dirfd: OwnedFd,
pathname: CString,
mode: stat::mode_t,
dev: stat::dev_t,
//! Note that this should stay small, otherwise we should introduce a dependency on our `proxmox`
//! crate as that's where we have all this stuff usually...
-use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
pub fn set_fd_nonblocking<T: AsRawFd + ?Sized>(fd: &T, on: bool) -> nix::Result<libc::c_int> {
use nix::fcntl;
fcntl::fcntl(fd, fcntl::FcntlArg::F_SETFL(flags))
}
-/// Guard a raw file descriptor with a drop handler. This is mostly useful when access to an owned
-/// `RawFd` is required without the corresponding handler object (such as when only the file
-/// descriptor number is required in a closure which may be dropped instead of being executed).
-#[repr(transparent)]
-pub struct Fd(pub RawFd);
-
-file_descriptor_impl!(Fd);
-
-impl FromRawFd for Fd {
- unsafe fn from_raw_fd(fd: RawFd) -> Self {
- Self(fd)
- }
-}
-
-impl Fd {
- pub fn set_nonblocking(&mut self, nb: bool) -> nix::Result<libc::c_int> {
- set_fd_nonblocking(self, nb)
- }
-}
-
-impl AsRef<RawFd> for Fd {
- #[inline]
- fn as_ref(&self) -> &RawFd {
- &self.0
- }
-}
-
/// Byte vector utilities.
pub mod vec {
/// Create an uninitialized byte vector of a specific size.