diff --git a/src/lib.rs b/src/lib.rs index 0234d74..09f86c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,7 +93,7 @@ impl StderrSilencer { #[cfg(unix)] unsafe { // Duplicate current stderr (fd 2) - let old_fd = unix_fd::dup(unix_fd::STDERR_FILENO); + let old_fd = dup(2); if old_fd < 0 { return Self { active: false, @@ -103,10 +103,10 @@ impl StderrSilencer { } // Open /dev/null for writing let devnull_cstr = std::ffi::CString::new("/dev/null").unwrap(); - let dn = unix_fd::open(devnull_cstr.as_ptr(), unix_fd::O_WRONLY); + let dn = open(devnull_cstr.as_ptr(), O_WRONLY); if dn < 0 { // failed to open devnull; restore and bail - unix_fd::close(old_fd); + close(old_fd); return Self { active: false, old_stderr_fd: -1, @@ -114,9 +114,9 @@ impl StderrSilencer { }; } // Redirect fd 2 to devnull - if unix_fd::dup2(dn, unix_fd::STDERR_FILENO) < 0 { - unix_fd::close(dn); - unix_fd::close(old_fd); + if dup2(dn, 2) < 0 { + close(dn); + close(old_fd); return Self { active: false, old_stderr_fd: -1, @@ -144,9 +144,9 @@ impl Drop for StderrSilencer { #[cfg(unix)] unsafe { // Restore old stderr and close devnull and old copies - let _ = unix_fd::dup2(self.old_stderr_fd, unix_fd::STDERR_FILENO); - let _ = unix_fd::close(self.devnull_fd); - let _ = unix_fd::close(self.old_stderr_fd); + let _ = dup2(self.old_stderr_fd, 2); + let _ = close(self.devnull_fd); + let _ = close(self.old_stderr_fd); } self.active = false; } @@ -242,18 +242,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; #[cfg(unix)] -mod unix_fd { - pub use libc::O_WRONLY; - pub const STDERR_FILENO: i32 = 2; // libc::STDERR_FILENO isn't always available on all targets - #[inline] - pub unsafe fn dup(fd: i32) -> i32 { libc::dup(fd) } - #[inline] - pub unsafe fn dup2(fd: i32, fd2: i32) -> i32 { libc::dup2(fd, fd2) } - #[inline] - pub unsafe fn open(path: *const libc::c_char, flags: i32) -> i32 { libc::open(path, flags) } - #[inline] - pub unsafe fn close(fd: i32) -> i32 { libc::close(fd) } -} +use libc::{O_WRONLY, close, dup, dup2, open}; /// Re-export backend module (GPU/CPU selection and transcription). pub mod backend; diff --git a/tests/with_suppressed_stderr.rs b/tests/with_suppressed_stderr.rs deleted file mode 100644 index 9cf00e5..0000000 --- a/tests/with_suppressed_stderr.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Unix-only tests for with_suppressed_stderr restoring file descriptors -// Skip on Windows and non-Unix targets. - -#![cfg(unix)] - -use std::panic::{catch_unwind, AssertUnwindSafe}; - -fn stat_of_fd(fd: i32) -> (u64, u64) { - unsafe { - let mut st: libc::stat = std::mem::zeroed(); - let r = libc::fstat(fd, &mut st as *mut libc::stat); - assert_eq!(r, 0, "fstat failed on fd {fd}"); - (st.st_dev as u64, st.st_ino as u64) - } -} - -fn stat_of_path(path: &str) -> (u64, u64) { - use std::ffi::CString; - unsafe { - let c = CString::new(path).unwrap(); - let fd = libc::open(c.as_ptr(), libc::O_RDONLY); - assert!(fd >= 0, "failed to open {path}"); - let s = stat_of_fd(fd); - let _ = libc::close(fd); - s - } -} - -#[test] -fn stderr_is_redirected_and_restored() { - let before = stat_of_fd(2); - let devnull = stat_of_path("/dev/null"); - - // During the call, fd 2 should be /dev/null; after, restored to before - polyscribe::with_suppressed_stderr(|| { - let inside = stat_of_fd(2); - assert_eq!(inside, devnull, "stderr should point to /dev/null during suppression"); - // This write should be suppressed - eprintln!("this should be suppressed"); - }); - - let after = stat_of_fd(2); - assert_eq!(after, before, "stderr should be restored after suppression"); -} - -#[test] -fn stderr_is_restored_even_if_closure_panics() { - let before = stat_of_fd(2); - let res = catch_unwind(AssertUnwindSafe(|| { - polyscribe::with_suppressed_stderr(|| { - // Trigger a deliberate panic inside the closure - panic!("boom inside with_suppressed_stderr"); - }); - })); - assert!(res.is_err(), "expected panic to propagate"); - let after = stat_of_fd(2); - assert_eq!(after, before, "stderr should be restored after panic"); -}