feat(shuma-exec): spill con splice (copia cero) + limpieza de temporales

El volcado de la salida excedente ya no copia por espacio de usuario:
pasado el tope, el lector escribe la línea que cruzó + lo bufereado y
luego mueve el resto del pipe al archivo con splice(2) —kernel a
kernel, sin copia—. Se aplica a stdout (el contenido principal).

shuma-shell limpia sus archivos de volcado al cerrar la sesión
(Drop). Los spills llevan el pid en el nombre para no chocar entre
instancias.

shuma-exec: 11 tests verdes (el de spill ahora verifica el camino
splice).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-20 20:15:30 +00:00
parent b08d5cbe0a
commit 22a0ae8c58
4 changed files with 74 additions and 42 deletions
+18 -2
View File
@@ -642,8 +642,10 @@ impl Shell {
/// aplica la política de captura de la sesión.
fn build_spec(&self, line: &str, stdin: Option<String>, run_id: RunId) -> CommandSpec {
let policy = self.session.capture();
let spill_path = (policy.spill && policy.limit_bytes > 0)
.then(|| std::env::temp_dir().join(format!("shuma-spill-{run_id}.log")));
let spill_path = (policy.spill && policy.limit_bytes > 0).then(|| {
std::env::temp_dir()
.join(format!("shuma-spill-{}-{run_id}.log", std::process::id()))
});
CommandSpec {
exec: plan_exec(line),
cwd: self.session.cwd().to_string(),
@@ -1621,6 +1623,20 @@ impl Render for Shell {
}
}
impl Drop for Shell {
/// Al cerrar la sesión, limpia sus archivos de volcado temporales.
fn drop(&mut self) {
let prefix = format!("shuma-spill-{}-", std::process::id());
if let Ok(entries) = std::fs::read_dir(std::env::temp_dir()) {
for e in entries.flatten() {
if e.file_name().to_string_lossy().starts_with(&prefix) {
let _ = std::fs::remove_file(e.path());
}
}
}
}
}
fn main() {
launch_app("brahman · shuma shell", (1100., 700.), Shell::new);
}