diff options
| author | Aram Drevekenin <aram@poor.dev> | 2025-07-17 11:41:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-17 11:41:17 +0200 |
| commit | 19c159175c12a06e3517882487caa2f834f29033 (patch) | |
| tree | 6f23f02728658a2f98376a5a682b86bcd78d0c74 | |
| parent | fix(panes): do not default to tiled pane (#4295) (diff) | |
| download | sl0ppij-19c159175c12a06e3517882487caa2f834f29033.tar.gz sl0ppij-19c159175c12a06e3517882487caa2f834f29033.tar.xz sl0ppij-19c159175c12a06e3517882487caa2f834f29033.zip | |
fix(clipboard): reap process of external command (#4298)
* fix(clipboard): reap process of external command
* docs(changelog): add PR
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | zellij-server/src/tab/copy_command.rs | 29 |
2 files changed, 29 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a206b782..bffe11a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * fix: better command detection when serializing layouts for resurrection (https://github.com/zellij-org/zellij/pull/4287) * fix: slow startup on very large caches (https://github.com/zellij-org/zellij/pull/4292) * fix: don't show popups in the welcome screen (https://github.com/zellij-org/zellij/pull/4294) +* fix: reap processes when using an external clipboard tool (https://github.com/zellij-org/zellij/pull/4298) ## [0.42.2] - 2025-04-15 * refactor(terminal): track scroll_region as tuple rather than Option (https://github.com/zellij-org/zellij/pull/4082) diff --git a/zellij-server/src/tab/copy_command.rs b/zellij-server/src/tab/copy_command.rs index f0a592ef..eead0bd7 100644 --- a/zellij-server/src/tab/copy_command.rs +++ b/zellij-server/src/tab/copy_command.rs @@ -18,17 +18,44 @@ impl CopyCommand { } } pub fn set(&self, value: String) -> Result<()> { - let process = Command::new(self.command.clone()) + let mut process = Command::new(self.command.clone()) .args(self.args.clone()) .stdin(Stdio::piped()) .spawn() .with_context(|| format!("couldn't spawn {}", self.command))?; process .stdin + .take() .context("could not get stdin")? .write_all(value.as_bytes()) .with_context(|| format!("couldn't write to {} stdin", self.command))?; + // reap process with a 1 second timeout + std::thread::spawn(move || { + let timeout = std::time::Duration::from_secs(1); + let start = std::time::Instant::now(); + + loop { + match process.try_wait() { + Ok(Some(_)) => { + return; // Process finished normally + }, + Ok(None) => { + if start.elapsed() > timeout { + let _ = process.kill(); + log::error!("Copy operation times out after 1 second"); + return; + } + std::thread::sleep(std::time::Duration::from_millis(50)); + }, + Err(e) => { + log::error!("Clipboard failure: {}", e); + return; + }, + } + } + }); + Ok(()) } } |
