From 5a9b8c682578ee8de4f1578577b0e619bea4b6d4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 1 Apr 2026 02:51:15 +0900 Subject: [PATCH] cat: replace nix with rustix --- Cargo.lock | 2 +- src/uu/cat/Cargo.toml | 2 +- src/uu/cat/src/cat.rs | 4 ++-- src/uu/cat/src/platform/unix.rs | 14 ++++++-------- src/uu/cat/src/splice.rs | 18 +++++++++--------- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5dd54a97d2a..adf882f2232 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3288,7 +3288,7 @@ dependencies = [ "codspeed-divan-compat", "fluent", "memchr", - "nix", + "rustix", "tempfile", "thiserror 2.0.18", "uucore", diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 753efdbde52..e5c8ca35b86 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -26,7 +26,7 @@ uucore = { workspace = true, features = ["fast-inc", "fs", "pipes", "signals"] } fluent = { workspace = true } [target.'cfg(unix)'.dependencies] -nix = { workspace = true } +rustix = { workspace = true, features = ["fs"] } [target.'cfg(windows)'.dependencies] winapi-util = { workspace = true } diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index aef7d5eab50..46e4e1be911 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -84,10 +84,10 @@ enum CatError { /// Wrapper around `io::Error` #[error("{}", strip_errno(.0))] Io(#[from] io::Error), - /// Wrapper around `nix::Error` + /// Wrapper around `rustix::io::Errno` #[cfg(any(target_os = "linux", target_os = "android"))] #[error("{0}")] - Nix(#[from] nix::Error), + Rustix(#[from] rustix::io::Errno), /// Unknown file type; it's not a regular file, socket, etc. #[error("{}", translate!("cat-error-unknown-filetype", "ft_debug" => .ft_debug))] UnknownFiletype { diff --git a/src/uu/cat/src/platform/unix.rs b/src/uu/cat/src/platform/unix.rs index b2cdda2aa67..6cc55fc6967 100644 --- a/src/uu/cat/src/platform/unix.rs +++ b/src/uu/cat/src/platform/unix.rs @@ -5,8 +5,7 @@ // spell-checker:ignore lseek seekable -use nix::fcntl::{FcntlArg, OFlag, fcntl}; -use nix::unistd::{Whence, lseek}; +use rustix::fs::{OFlags, SeekFrom, fcntl_getfl}; use std::os::fd::AsFd; use uucore::fs::FileInformation; @@ -31,10 +30,10 @@ pub fn is_unsafe_overwrite(input: &I, output: &O) -> bool { if file_size == 0 { return false; } - // `lseek` returns an error if the file descriptor is closed or it refers to + // `seek` returns an error if the file descriptor is closed or it refers to // a non-seekable resource (e.g., pipe, socket, or some devices). - let input_pos = lseek(input.as_fd(), 0, Whence::SeekCur); - let output_pos = lseek(output.as_fd(), 0, Whence::SeekCur); + let input_pos = rustix::fs::seek(input, SeekFrom::Current(0)).map(|v| v as i64); + let output_pos = rustix::fs::seek(output, SeekFrom::Current(0)).map(|v| v as i64); if is_appending(output) { if let Ok(pos) = input_pos { if pos >= 0 && (pos as u64) >= file_size { @@ -54,9 +53,8 @@ pub fn is_unsafe_overwrite(input: &I, output: &O) -> bool { /// Whether the file is opened with the `O_APPEND` flag fn is_appending(file: &F) -> bool { - let flags_raw = fcntl(file.as_fd(), FcntlArg::F_GETFL).unwrap_or_default(); - let flags = OFlag::from_bits_truncate(flags_raw); - flags.contains(OFlag::O_APPEND) + let flags = fcntl_getfl(file).unwrap_or(OFlags::empty()); + flags.contains(OFlags::APPEND) } #[cfg(test)] diff --git a/src/uu/cat/src/splice.rs b/src/uu/cat/src/splice.rs index ca5265d2bf8..a8b01e22605 100644 --- a/src/uu/cat/src/splice.rs +++ b/src/uu/cat/src/splice.rs @@ -4,7 +4,7 @@ // file that was distributed with this source code. use super::{CatResult, FdReadable, InputHandle}; -use nix::unistd; +use rustix::io::{read, write}; use std::os::{fd::AsFd, unix::io::AsRawFd}; use uucore::pipes::{pipe, splice, splice_exact}; @@ -52,20 +52,20 @@ pub(super) fn write_fast_using_splice( /// Move exactly `num_bytes` bytes from `read_fd` to `write_fd`. /// /// Panics if not enough bytes can be read. -fn copy_exact(read_fd: &impl AsFd, write_fd: &impl AsFd, num_bytes: usize) -> nix::Result<()> { +fn copy_exact(read_fd: &impl AsFd, write_fd: &impl AsFd, num_bytes: usize) -> std::io::Result<()> { let mut left = num_bytes; let mut buf = [0; BUF_SIZE]; while left > 0 { - let read = unistd::read(read_fd, &mut buf)?; - assert_ne!(read, 0, "unexpected end of pipe"); + let n = read(read_fd, &mut buf)?; + assert_ne!(n, 0, "unexpected end of pipe"); let mut written = 0; - while written < read { - match unistd::write(write_fd, &buf[written..read])? { - 0 => panic!(), - n => written += n, + while written < n { + match write(write_fd, &buf[written..n])? { + 0 => unreachable!("fd should be writable"), + w => written += w, } } - left -= read; + left -= n; } Ok(()) }