Skip to content

Commit 455438e

Browse files
halfaipgclaude
andcommitted
fix: cross-platform build — extract syscall into build-tagged files
Setpgid and syscall.Kill are Unix-only. Move process group management into proc_unix.go and proc_windows.go with build tags so goreleaser can compile for all targets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 094f485 commit 455438e

3 files changed

Lines changed: 39 additions & 6 deletions

File tree

proc_unix.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//go:build !windows
2+
3+
package main
4+
5+
import (
6+
"os/exec"
7+
"syscall"
8+
)
9+
10+
// setProcGroup sets up process group isolation so child processes
11+
// can be killed together on timeout.
12+
func setProcGroup(cmd *exec.Cmd) {
13+
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
14+
}
15+
16+
// killProcGroup kills an entire process group by PID.
17+
func killProcGroup(cmd *exec.Cmd) {
18+
if cmd.Process != nil {
19+
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
20+
}
21+
}

proc_windows.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build windows
2+
3+
package main
4+
5+
import "os/exec"
6+
7+
// setProcGroup is a no-op on Windows (no Setpgid support).
8+
func setProcGroup(cmd *exec.Cmd) {}
9+
10+
// killProcGroup kills the process on Windows.
11+
func killProcGroup(cmd *exec.Cmd) {
12+
if cmd.Process != nil {
13+
cmd.Process.Kill()
14+
}
15+
}

tools.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"path/filepath"
99
"sort"
1010
"strings"
11-
"syscall"
1211
"time"
1312
)
1413

@@ -1036,7 +1035,7 @@ func toolShell(args map[string]interface{}, workDir string) (string, bool) {
10361035
"CI=1",
10371036
)
10381037
// Use process group so we can kill children on timeout
1039-
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
1038+
setProcGroup(cmd)
10401039

10411040
// Combine stdout + stderr, timeout at 2 minutes
10421041
started := time.Now()
@@ -1061,10 +1060,8 @@ func toolShell(args map[string]interface{}, workDir string) (string, bool) {
10611060
}
10621061
return truncateOutput(fmt.Sprintf("%s\n\nExit code: 0 | Wall time: %.1fs", result, elapsed)), true
10631062
case <-time.After(2 * time.Minute):
1064-
if cmd.Process != nil {
1065-
// Kill entire process group to prevent zombies
1066-
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
1067-
}
1063+
// Kill entire process group to prevent zombies
1064+
killProcGroup(cmd)
10681065
return "Error: command timed out after 2 minutes", false
10691066
}
10701067
}

0 commit comments

Comments
 (0)