sys: deprecate Fd, add its methods as module functions

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2022-10-19 13:25:08 +02:00
parent 85c260f6b5
commit 8420c266af
8 changed files with 66 additions and 24 deletions

View File

@ -1,3 +1,5 @@
#![allow(deprecated)]
use std::marker::PhantomData; use std::marker::PhantomData;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};

View File

@ -9,8 +9,10 @@ use nix::NixPath;
/// `RawFd` is required without the corresponding handler object (such as when only the file /// `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). /// descriptor number is required in a closure which may be dropped instead of being executed).
#[derive(Debug)] #[derive(Debug)]
#[deprecated(note = "use std::os::unix::io::OwnedFd instead")]
pub struct Fd(pub RawFd); pub struct Fd(pub RawFd);
#[allow(deprecated)]
impl Drop for Fd { impl Drop for Fd {
fn drop(&mut self) { fn drop(&mut self) {
// `>= 0` instead of `!= -1` to also handle things like AT_FDCWD // `>= 0` instead of `!= -1` to also handle things like AT_FDCWD
@ -22,11 +24,14 @@ impl Drop for Fd {
} }
} }
#[allow(deprecated)]
impl Fd { impl Fd {
#[deprecated(note = "use proxmox_sys::fd::cwd instead")]
pub const fn cwd() -> Self { pub const fn cwd() -> Self {
Self(libc::AT_FDCWD) Self(libc::AT_FDCWD)
} }
#[deprecated(note = "use proxmox_sys::fd::open instead")]
pub fn open<P>(path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error> pub fn open<P>(path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error>
where where
P: ?Sized + NixPath, P: ?Sized + NixPath,
@ -34,6 +39,7 @@ impl Fd {
nix::fcntl::open(path, oflag, mode).map(Self) nix::fcntl::open(path, oflag, mode).map(Self)
} }
#[deprecated(note = "use proxmox_sys::fd::openat instead")]
pub fn openat<D, P>(dirfd: &D, path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error> pub fn openat<D, P>(dirfd: &D, path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error>
where where
D: AsRawFd, D: AsRawFd,
@ -48,18 +54,21 @@ impl Fd {
} }
} }
#[allow(deprecated)]
impl FromRawFd for Fd { impl FromRawFd for Fd {
unsafe fn from_raw_fd(fd: RawFd) -> Self { unsafe fn from_raw_fd(fd: RawFd) -> Self {
Self(fd) Self(fd)
} }
} }
#[allow(deprecated)]
impl AsRawFd for Fd { impl AsRawFd for Fd {
fn as_raw_fd(&self) -> RawFd { fn as_raw_fd(&self) -> RawFd {
self.0 self.0
} }
} }
#[allow(deprecated)]
impl IntoRawFd for Fd { impl IntoRawFd for Fd {
fn into_raw_fd(mut self) -> RawFd { fn into_raw_fd(mut self) -> RawFd {
let fd = self.0; let fd = self.0;
@ -68,18 +77,21 @@ impl IntoRawFd for Fd {
} }
} }
#[allow(deprecated)]
impl AsRef<FdRef> for Fd { impl AsRef<FdRef> for Fd {
fn as_ref(&self) -> &FdRef { fn as_ref(&self) -> &FdRef {
self.as_fd_ref() self.as_fd_ref()
} }
} }
#[allow(deprecated)]
impl Borrow<FdRef> for Fd { impl Borrow<FdRef> for Fd {
fn borrow(&self) -> &FdRef { fn borrow(&self) -> &FdRef {
self.as_fd_ref() self.as_fd_ref()
} }
} }
#[allow(deprecated)]
impl std::ops::Deref for Fd { impl std::ops::Deref for Fd {
type Target = FdRef; type Target = FdRef;

View File

@ -1,5 +1,11 @@
//! Raw file descriptor related structures. //! Raw file descriptor related structures.
use std::os::unix::io::AsRawFd;
use nix::fcntl::OFlag;
use nix::sys::stat::Mode;
use nix::NixPath;
mod fd_impl; mod fd_impl;
pub use fd_impl::*; pub use fd_impl::*;
@ -9,14 +15,39 @@ pub use raw_fd_num::*;
mod borrowed_fd; mod borrowed_fd;
pub use borrowed_fd::*; pub use borrowed_fd::*;
use std::os::unix::io::RawFd; use std::os::unix::io::{FromRawFd, OwnedFd, RawFd};
use nix::fcntl::{fcntl, FdFlag, F_GETFD, F_SETFD}; use nix::fcntl::{fcntl, FdFlag, F_GETFD, F_SETFD};
/// Change the `O_CLOEXEC` flag of an existing file descriptor. /// Change the `O_CLOEXEC` flag of an existing file descriptor.
pub fn fd_change_cloexec(fd: RawFd, on: bool) -> Result<(), anyhow::Error> { pub fn fd_change_cloexec(fd: RawFd, on: bool) -> Result<(), anyhow::Error> {
change_cloexec(fd, on)
}
/// Change the `O_CLOEXEC` flag of an existing file descriptor.
pub fn change_cloexec(fd: RawFd, on: bool) -> Result<(), anyhow::Error> {
let mut flags = unsafe { FdFlag::from_bits_unchecked(fcntl(fd, F_GETFD)?) }; let mut flags = unsafe { FdFlag::from_bits_unchecked(fcntl(fd, F_GETFD)?) };
flags.set(FdFlag::FD_CLOEXEC, on); flags.set(FdFlag::FD_CLOEXEC, on);
fcntl(fd, F_SETFD(flags))?; fcntl(fd, F_SETFD(flags))?;
Ok(()) Ok(())
} }
pub fn cwd() -> OwnedFd {
unsafe { OwnedFd::from_raw_fd(libc::AT_FDCWD) }
}
pub fn open<P>(path: &P, oflag: OFlag, mode: Mode) -> Result<OwnedFd, nix::Error>
where
P: ?Sized + NixPath,
{
nix::fcntl::open(path, oflag, mode).map(|fd| unsafe { OwnedFd::from_raw_fd(fd) })
}
pub fn openat<D, P>(dirfd: &D, path: &P, oflag: OFlag, mode: Mode) -> Result<OwnedFd, nix::Error>
where
D: AsRawFd,
P: ?Sized + NixPath,
{
nix::fcntl::openat(dirfd.as_raw_fd(), path, oflag, mode)
.map(|fd| unsafe { OwnedFd::from_raw_fd(fd) })
}

View File

@ -1,5 +1,5 @@
use std::ffi::CStr; use std::ffi::CStr;
use std::os::unix::io::AsRawFd; use std::os::unix::io::{AsRawFd, OwnedFd};
use std::path::Path; use std::path::Path;
use anyhow::{bail, Error}; use anyhow::{bail, Error};
@ -8,7 +8,6 @@ use nix::fcntl::OFlag;
use nix::sys::stat; use nix::sys::stat;
use nix::unistd; use nix::unistd;
use crate::fd::Fd;
use crate::fs::{fchown, CreateOptions}; use crate::fs::{fchown, CreateOptions};
/// Creates directory at the provided path with specified ownership. /// Creates directory at the provided path with specified ownership.
@ -66,11 +65,11 @@ fn create_path_do(
use std::path::Component; use std::path::Component;
let mut iter = path.components().peekable(); let mut iter = path.components().peekable();
let at: Fd = match iter.peek() { let at: OwnedFd = match iter.peek() {
Some(Component::Prefix(_)) => bail!("illegal prefix path component encountered"), Some(Component::Prefix(_)) => bail!("illegal prefix path component encountered"),
Some(Component::RootDir) => { Some(Component::RootDir) => {
let _ = iter.next(); let _ = iter.next();
Fd::open( crate::fd::open(
unsafe { CStr::from_bytes_with_nul_unchecked(b"/\0") }, unsafe { CStr::from_bytes_with_nul_unchecked(b"/\0") },
OFlag::O_DIRECTORY, OFlag::O_DIRECTORY,
stat::Mode::empty(), stat::Mode::empty(),
@ -78,11 +77,11 @@ fn create_path_do(
} }
Some(Component::CurDir) => { Some(Component::CurDir) => {
let _ = iter.next(); let _ = iter.next();
Fd::cwd() crate::fd::cwd()
} }
Some(Component::ParentDir) => { Some(Component::ParentDir) => {
let _ = iter.next(); let _ = iter.next();
Fd::open( crate::fd::open(
unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") }, unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") },
OFlag::O_DIRECTORY, OFlag::O_DIRECTORY,
stat::Mode::empty(), stat::Mode::empty(),
@ -90,7 +89,7 @@ fn create_path_do(
} }
Some(Component::Normal(_)) => { Some(Component::Normal(_)) => {
// simply do not advance the iterator, heavy lifting happens in create_path_at_do() // simply do not advance the iterator, heavy lifting happens in create_path_at_do()
Fd::cwd() crate::fd::cwd()
} }
None => bail!("create_path on empty path?"), None => bail!("create_path on empty path?"),
}; };
@ -99,7 +98,7 @@ fn create_path_do(
} }
fn create_path_at_do( fn create_path_at_do(
mut at: Fd, mut at: OwnedFd,
mut iter: std::iter::Peekable<std::path::Components>, mut iter: std::iter::Peekable<std::path::Components>,
intermediate_opts: Option<CreateOptions>, intermediate_opts: Option<CreateOptions>,
final_opts: Option<CreateOptions>, final_opts: Option<CreateOptions>,
@ -112,7 +111,7 @@ fn create_path_at_do(
None => return Ok(created), None => return Ok(created),
Some(Component::ParentDir) => { Some(Component::ParentDir) => {
at = Fd::openat( at = crate::fd::openat(
&at, &at,
unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") }, unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") },
OFlag::O_DIRECTORY, OFlag::O_DIRECTORY,
@ -138,7 +137,7 @@ fn create_path_at_do(
Err(e) => return Err(e.into()), Err(e) => return Err(e.into()),
Ok(_) => true, Ok(_) => true,
}; };
at = Fd::openat(&at, path, OFlag::O_DIRECTORY, stat::Mode::empty())?; at = crate::fd::openat(&at, path, OFlag::O_DIRECTORY, stat::Mode::empty())?;
if let (true, Some(opts)) = (created, opts) { if let (true, Some(opts)) = (created, opts) {
if opts.owner.is_some() || opts.group.is_some() { if opts.owner.is_some() || opts.group.is_some() {

View File

@ -32,6 +32,7 @@ macro_rules! identity {
#[cfg(feature = "sortable-macro")] #[cfg(feature = "sortable-macro")]
pub use proxmox_sortable_macro::sortable; pub use proxmox_sortable_macro::sortable;
#[allow(deprecated)]
use fd::Fd; use fd::Fd;
/// Returns the hosts node name (UTS node name) /// Returns the hosts node name (UTS node name)
@ -57,6 +58,7 @@ pub fn nodename() -> &'static str {
/// Safe wrapper for `nix::unistd::pipe2` defaulting to `O_CLOEXEC` /// Safe wrapper for `nix::unistd::pipe2` defaulting to `O_CLOEXEC`
/// and guarding the file descriptors. /// and guarding the file descriptors.
#[allow(deprecated)]
pub fn pipe() -> Result<(Fd, Fd), nix::Error> { pub fn pipe() -> Result<(Fd, Fd), nix::Error> {
let (pin, pout) = nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC)?; let (pin, pout) = nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC)?;
Ok((Fd(pin), Fd(pout))) Ok((Fd(pin), Fd(pout)))

View File

@ -2,7 +2,7 @@
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use nix::fcntl::OFlag; use nix::fcntl::OFlag;
use nix::sys::signal::Signal; use nix::sys::signal::Signal;
@ -14,7 +14,6 @@ use nix::NixPath;
use proxmox_lang::{c_str, error::io_err_other}; use proxmox_lang::{c_str, error::io_err_other};
use crate::error::SysResult; use crate::error::SysResult;
use crate::fd::Fd;
use crate::linux::procfs::{MountInfo, PidStat}; use crate::linux::procfs::{MountInfo, PidStat};
use crate::{c_result, c_try}; use crate::{c_result, c_try};
@ -41,7 +40,7 @@ unsafe fn pidfd_send_signal(
/// File descriptor refernce to a process. /// File descriptor refernce to a process.
pub struct PidFd { pub struct PidFd {
fd: Fd, fd: OwnedFd,
pid: Pid, pid: Pid,
} }
@ -53,7 +52,7 @@ impl PidFd {
/// Open a pidfd for the given process id. /// Open a pidfd for the given process id.
pub fn open(pid: Pid) -> io::Result<Self> { pub fn open(pid: Pid) -> io::Result<Self> {
let fd = unsafe { Fd::from_raw_fd(c_try!(pidfd_open(pid.as_raw(), 0)) as RawFd) }; let fd = unsafe { OwnedFd::from_raw_fd(c_try!(pidfd_open(pid.as_raw(), 0)) as RawFd) };
Ok(Self { fd, pid }) Ok(Self { fd, pid })
} }
@ -85,7 +84,7 @@ impl PidFd {
/// Open a procfs file from. This is equivalent to opening `/proc/<pid>/<file>` using this /// Open a procfs file from. This is equivalent to opening `/proc/<pid>/<file>` using this
/// process actual pid. This also works if the file descriptor has been sent over /// process actual pid. This also works if the file descriptor has been sent over
pub fn open_file<P: ?Sized + NixPath>(&self, path: &P) -> io::Result<File> { pub fn open_file<P: ?Sized + NixPath>(&self, path: &P) -> io::Result<File> {
Fd::openat( crate::fd::openat(
self, self,
path, path,
OFlag::O_RDONLY | OFlag::O_CLOEXEC, OFlag::O_RDONLY | OFlag::O_CLOEXEC,
@ -124,7 +123,7 @@ impl PidFd {
/// This will attempt to read the pid number via the file descriptor. /// This will attempt to read the pid number via the file descriptor.
pub fn try_from_raw_fd(fd: RawFd) -> io::Result<Self> { pub fn try_from_raw_fd(fd: RawFd) -> io::Result<Self> {
let mut this = Self { let mut this = Self {
fd: unsafe { Fd::from_raw_fd(fd) }, fd: unsafe { OwnedFd::from_raw_fd(fd) },
pid: Pid::from_raw(1), pid: Pid::from_raw(1),
}; };
// Simple check first: is it a valid pid file descriptor: // Simple check first: is it a valid pid file descriptor:

View File

@ -10,8 +10,6 @@ use nix::sys::stat::Mode;
use nix::unistd::{dup2, setsid}; use nix::unistd::{dup2, setsid};
use nix::{ioctl_write_int_bad, ioctl_write_ptr_bad, Result}; use nix::{ioctl_write_int_bad, ioctl_write_ptr_bad, Result};
use crate::fd::Fd;
ioctl_write_int_bad!(set_controlling_tty, libc::TIOCSCTTY); ioctl_write_int_bad!(set_controlling_tty, libc::TIOCSCTTY);
ioctl_write_ptr_bad!(set_size, libc::TIOCSWINSZ, nix::pty::Winsize); ioctl_write_ptr_bad!(set_size, libc::TIOCSWINSZ, nix::pty::Winsize);
@ -64,7 +62,7 @@ pub fn make_controlling_terminal(terminal: &str) -> Result<()> {
| Mode::S_IWGRP | Mode::S_IWGRP
| Mode::S_IROTH | Mode::S_IROTH
| Mode::S_IWOTH; // 0666 | Mode::S_IWOTH; // 0666
let secondary_fd = Fd::open(terminal, OFlag::O_RDWR | OFlag::O_NOCTTY, mode)?; let secondary_fd = crate::fd::open(terminal, OFlag::O_RDWR | OFlag::O_NOCTTY, mode)?;
let s_raw_fd = secondary_fd.as_raw_fd(); let s_raw_fd = secondary_fd.as_raw_fd();
unsafe { set_controlling_tty(s_raw_fd, 0) }?; unsafe { set_controlling_tty(s_raw_fd, 0) }?;
dup2(s_raw_fd, 0)?; dup2(s_raw_fd, 0)?;

View File

@ -1,6 +1,6 @@
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::os::unix::io::AsRawFd; use std::os::unix::io::{AsRawFd, OwnedFd};
use anyhow::{bail, format_err, Error}; use anyhow::{bail, format_err, Error};
use nix::fcntl::OFlag; use nix::fcntl::OFlag;
@ -9,7 +9,6 @@ use nix::sys::stat::Mode;
use proxmox_lang::try_block; use proxmox_lang::try_block;
use crate::c_try; use crate::c_try;
use crate::fd::Fd;
/// Get the current size of the terminal (for stdout). /// Get the current size of the terminal (for stdout).
/// # Safety /// # Safety
@ -44,7 +43,7 @@ pub fn stdin_isatty() -> bool {
pub enum TtyOutput { pub enum TtyOutput {
Stdout(std::io::Stdout), Stdout(std::io::Stdout),
DevTty(Fd), DevTty(OwnedFd),
} }
impl Write for TtyOutput { impl Write for TtyOutput {
@ -79,7 +78,7 @@ impl TtyOutput {
if unsafe { libc::isatty(stdout.as_raw_fd()) } == 1 { if unsafe { libc::isatty(stdout.as_raw_fd()) } == 1 {
Ok(Some(TtyOutput::Stdout(stdout))) Ok(Some(TtyOutput::Stdout(stdout)))
} else { } else {
match Fd::open( match crate::fd::open(
"/dev/tty", "/dev/tty",
OFlag::O_WRONLY | OFlag::O_CLOEXEC | OFlag::O_NOCTTY, OFlag::O_WRONLY | OFlag::O_CLOEXEC | OFlag::O_NOCTTY,
Mode::empty(), Mode::empty(),