improve bits for linux

This commit is contained in:
Peter Steinberger 2025-06-18 14:13:30 +02:00
parent b90986c354
commit f0658bccd0
2 changed files with 88 additions and 6 deletions

View file

@ -250,11 +250,20 @@ fn write_to_pipe_with_timeout(
}
pub fn is_pid_alive(pid: u32) -> bool {
let output = Command::new("ps").arg("-p").arg(pid.to_string()).output();
// On Linux, check /proc/{pid} for better performance
#[cfg(target_os = "linux")]
{
std::path::Path::new(&format!("/proc/{}", pid)).exists()
}
match output {
Ok(output) => output.status.success(),
Err(_) => false,
// On other platforms, use ps command
#[cfg(not(target_os = "linux"))]
{
let output = Command::new("ps").arg("-p").arg(pid.to_string()).output();
match output {
Ok(output) => output.status.success(),
Err(_) => false,
}
}
}

View file

@ -16,7 +16,18 @@ use crate::protocol::{
use anyhow::Error;
use jiff::Timestamp;
use nix::errno::Errno;
use nix::libc::{login_tty, O_NONBLOCK, TIOCGWINSZ, TIOCSWINSZ, VEOF};
#[cfg(any(
target_os = "macos",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
use nix::libc::login_tty;
use nix::libc::{O_NONBLOCK, TIOCGWINSZ, TIOCSWINSZ, VEOF};
// Define TIOCSCTTY for platforms where it's not exposed by libc
#[cfg(target_os = "linux")]
const TIOCSCTTY: u64 = 0x540E;
use nix::pty::{openpty, Winsize};
use nix::sys::select::{select, FdSet};
use nix::sys::signal::{killpg, Signal};
@ -32,6 +43,68 @@ use tempfile::NamedTempFile;
pub const DEFAULT_TERM: &str = "xterm-256color";
/// Cross-platform implementation of login_tty
/// On systems with login_tty, use it directly. Otherwise, implement manually.
#[cfg(any(
target_os = "macos",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
unsafe fn login_tty_compat(fd: i32) -> Result<(), Error> {
if login_tty(fd) == 0 {
Ok(())
} else {
Err(Error::msg("login_tty failed"))
}
}
#[cfg(not(any(
target_os = "macos",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
)))]
unsafe fn login_tty_compat(fd: i32) -> Result<(), Error> {
// Manual implementation of login_tty for Linux and other systems
// Create a new session
if libc::setsid() == -1 {
return Err(Error::msg("setsid failed"));
}
// Make the tty our controlling terminal
#[cfg(target_os = "linux")]
let tiocsctty = TIOCSCTTY;
#[cfg(not(target_os = "linux"))]
let tiocsctty = libc::TIOCSCTTY;
if libc::ioctl(fd, tiocsctty.try_into().unwrap_or(0x540E), 0) == -1 {
// Try without forcing
if libc::ioctl(fd, tiocsctty.try_into().unwrap_or(0x540E), 1) == -1 {
return Err(Error::msg("ioctl TIOCSCTTY failed"));
}
}
// Duplicate the tty to stdin/stdout/stderr
if libc::dup2(fd, 0) == -1 {
return Err(Error::msg("dup2 stdin failed"));
}
if libc::dup2(fd, 1) == -1 {
return Err(Error::msg("dup2 stdout failed"));
}
if libc::dup2(fd, 2) == -1 {
return Err(Error::msg("dup2 stderr failed"));
}
// Close the original fd if it's not one of the standard descriptors
if fd > 2 {
libc::close(fd);
}
Ok(())
}
/// Creates environment variables for `AsciinemaHeader`
fn create_env_vars(term: &str) -> std::collections::HashMap<String, String> {
let mut env_vars = std::collections::HashMap::new();
@ -523,7 +596,7 @@ fn spawn(mut opts: SpawnOptions) -> Result<i32, Error> {
}
} else {
unsafe {
login_tty(pty.slave.into_raw_fd());
login_tty_compat(pty.slave.into_raw_fd())?;
// No stderr redirection since script_mode is always false
}
}