//go:build unix package tools import ( "os/exec" "syscall" ) // setProcessGroup hace que el comando se ejecute en su propio grupo de // procesos y que la cancelación (timeout, Ctrl+C) mate a todo el grupo. // // Por qué: con "bash -c 'a | b'" o un script que lanza hijos, matar solo // al proceso principal deja huérfanos que siguen corriendo y mantienen // abiertas las tuberías de salida, bloqueando la espera indefinidamente. func setProcessGroup(cmd *exec.Cmd) { cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} cmd.Cancel = func() error { if cmd.Process == nil { return nil } // PID negativo = todo el grupo. return syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) } }