diff --git a/lib/Cargo.toml b/lib/Cargo.toml index c89eb468..bb6964f9 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -24,7 +24,7 @@ hex = "0.4.3" indicatif = "0.16.0" once_cell = "1.9" libc = "0.2.92" -nix = "0.23" +rustix = "0.31.3" oci-spec = "0.5.0" openat = "0.1.20" openat-ext = "0.2.0" diff --git a/lib/src/cmdext.rs b/lib/src/cmdext.rs index bd1da4ea..65bdb096 100644 --- a/lib/src/cmdext.rs +++ b/lib/src/cmdext.rs @@ -1,19 +1,23 @@ -use std::os::unix::prelude::{CommandExt, RawFd}; +use rustix::fd::{FromRawFd, IntoRawFd}; +use rustix::io::OwnedFd; +use std::os::unix::prelude::CommandExt; +use std::sync::Arc; pub(crate) trait CommandRedirectionExt { /// Pass a file descriptor into the target process. - /// IMPORTANT: `fd` must be valid (i.e. cannot be closed) until after [`std::Process::Command::spawn`] or equivalent is invoked. - fn take_fd_n(&mut self, fd: i32, target: i32) -> &mut Self; + fn take_fd_n(&mut self, fd: Arc, target: i32) -> &mut Self; } #[allow(unsafe_code)] impl CommandRedirectionExt for std::process::Command { - fn take_fd_n(&mut self, fd: i32, target: i32) -> &mut Self { + fn take_fd_n(&mut self, fd: Arc, target: i32) -> &mut Self { unsafe { self.pre_exec(move || { - nix::unistd::dup2(fd, target as RawFd) - .map(|_r| ()) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e))) + let target = rustix::io::OwnedFd::from_raw_fd(target); + rustix::io::dup2(&*fd, &target)?; + // Intentionally leak into the child. + let _ = target.into_raw_fd(); + Ok(()) }); } self diff --git a/lib/src/container/ociwriter.rs b/lib/src/container/ociwriter.rs index b2429af1..6a459d03 100644 --- a/lib/src/container/ociwriter.rs +++ b/lib/src/container/ociwriter.rs @@ -169,8 +169,8 @@ impl<'a> OciWriter<'a> { #[context("Writing OCI")] pub(crate) fn complete(self) -> Result<()> { - let utsname = nix::sys::utsname::uname(); - let machine = utsname.machine(); + let uname = rustix::process::uname(); + let machine = uname.machine().to_str().unwrap(); let arch = MACHINE_TO_OCI.get(machine).unwrap_or(&machine); let arch = oci_image::Arch::from(*arch); diff --git a/lib/src/tar/write.rs b/lib/src/tar/write.rs index 8af16cb8..6e048d1e 100644 --- a/lib/src/tar/write.rs +++ b/lib/src/tar/write.rs @@ -13,12 +13,13 @@ use anyhow::{anyhow, Context}; use camino::{Utf8Component, Utf8Path, Utf8PathBuf}; use ostree::gio; use ostree::prelude::FileExt; +use rustix::fd::FromFd; use std::collections::BTreeMap; use std::convert::TryInto; use std::io::{BufWriter, Write}; -use std::os::unix::prelude::AsRawFd; use std::path::Path; use std::process::Stdio; +use std::sync::Arc; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite}; use tracing::instrument; @@ -197,13 +198,14 @@ pub async fn write_tar( }; let mut c = std::process::Command::new("ostree"); let repofd = repo.dfd_as_file()?; + let repofd = Arc::new(rustix::io::OwnedFd::from_into_fd(repofd)); { let c = c .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .args(&["commit"]); - c.take_fd_n(repofd.as_raw_fd(), 3); + c.take_fd_n(repofd.clone(), 3); c.arg("--repo=/proc/self/fd/3"); if let Some(sepolicy) = sepolicy.as_ref() { c.arg("--selinux-policy");