diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-03-31 13:29:57 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-03-31 13:29:57 +0300 |
| commit | f8c452294d6f76ccb264c0d9e205398492f00e18 (patch) | |
| tree | 68f9505424de441b5da4dbe26fab6149e2a75734 /src/platform/macos.rs | |
| parent | b8ccdf600c750411b439d0eb41f6a70e3c595f4f (diff) | |
fix: terminate pane sessions on close
Diffstat (limited to 'src/platform/macos.rs')
| -rw-r--r-- | src/platform/macos.rs | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/platform/macos.rs b/src/platform/macos.rs index e2f368f8..82de0c5b 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -2,7 +2,7 @@ use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; -use super::{ForegroundJob, ForegroundProcess}; +use super::{ForegroundJob, ForegroundProcess, Signal}; /// Collect the foreground terminal job for a given child PID. pub fn foreground_job(child_pid: u32) -> Option<ForegroundJob> { @@ -284,3 +284,62 @@ pub fn process_cwd(pid: u32) -> Option<PathBuf> { } Some(PathBuf::from(OsStr::from_bytes(&vip_path[..nul]))) } + +pub fn session_processes(child_pid: u32) -> Vec<u32> { + if child_pid == 0 { + return Vec::new(); + } + + let target_session = unsafe { libc::getsid(child_pid as libc::c_int) }; + if target_session <= 0 { + return Vec::new(); + } + + let mut pids = vec![0i32; 4096]; + let bytes = unsafe { + libc::proc_listallpids( + pids.as_mut_ptr() as *mut libc::c_void, + (pids.len() * std::mem::size_of::<i32>()) as libc::c_int, + ) + }; + if bytes <= 0 { + return Vec::new(); + } + + let count = (bytes as usize) / std::mem::size_of::<i32>(); + pids.into_iter() + .take(count) + .filter(|pid| *pid > 0) + .filter(|pid| unsafe { libc::getsid(*pid) } == target_session) + .map(|pid| pid as u32) + .collect() +} + +pub fn signal_processes(pids: &[u32], signal: Signal) { + let sig = match signal { + Signal::Hangup => libc::SIGHUP, + Signal::Terminate => libc::SIGTERM, + Signal::Kill => libc::SIGKILL, + }; + + for &pid in pids { + if pid == 0 { + continue; + } + unsafe { + libc::kill(pid as libc::c_int, sig); + } + } +} + +pub fn process_exists(pid: u32) -> bool { + if pid == 0 { + return false; + } + let result = unsafe { libc::kill(pid as libc::c_int, 0) }; + if result == 0 { + true + } else { + std::io::Error::last_os_error().raw_os_error() == Some(libc::EPERM) + } +} |
