Skip to main content

coreutils_rs/common/
mod.rs

1pub mod io;
2
3/// Get the GNU-compatible tool name by stripping the 'f' prefix.
4/// e.g., "fmd5sum" -> "md5sum", "fcut" -> "cut"
5#[inline]
6pub fn gnu_name(binary_name: &str) -> &str {
7    binary_name.strip_prefix('f').unwrap_or(binary_name)
8}
9
10/// Reset SIGPIPE to default behavior (SIG_DFL) for GNU coreutils compatibility.
11/// Rust sets SIGPIPE to SIG_IGN by default, but GNU tools are killed by SIGPIPE
12/// (exit code 141 = 128 + 13). This must be called at the start of main().
13#[inline]
14pub fn reset_sigpipe() {
15    #[cfg(unix)]
16    unsafe {
17        libc::signal(libc::SIGPIPE, libc::SIG_DFL);
18    }
19}
20
21/// Enlarge stdout pipe buffer on Linux for higher throughput.
22/// Only enlarges stdout (fd 1) when it is actually a pipe.
23/// Tries 8MB first (best for large data), falls back to 1MB then 256KB.
24/// Silently no-ops on non-pipes, non-Linux, or restricted environments.
25#[cfg(target_os = "linux")]
26pub fn enlarge_stdout_pipe() {
27    let mut stat: libc::stat = unsafe { std::mem::zeroed() };
28    if unsafe { libc::fstat(1, &mut stat) } != 0 {
29        return;
30    }
31    if (stat.st_mode & libc::S_IFMT) != libc::S_IFIFO {
32        return;
33    }
34    for &size in &[8 * 1024 * 1024i32, 1024 * 1024, 256 * 1024] {
35        if unsafe { libc::fcntl(1, libc::F_SETPIPE_SZ, size) } > 0 {
36            break;
37        }
38    }
39}
40
41#[cfg(not(target_os = "linux"))]
42pub fn enlarge_stdout_pipe() {}
43
44/// Format an IO error message without the "(os error N)" suffix.
45/// GNU coreutils prints e.g. "No such file or directory" while Rust's
46/// Display impl adds " (os error 2)". This strips the suffix for compat.
47#[cold]
48#[inline(never)]
49pub fn io_error_msg(e: &std::io::Error) -> String {
50    if let Some(raw) = e.raw_os_error() {
51        let os_err = std::io::Error::from_raw_os_error(raw);
52        let msg = format!("{}", os_err);
53        msg.replace(&format!(" (os error {})", raw), "")
54    } else {
55        format!("{}", e)
56    }
57}