Audit of 9af1463
This commit is contained in:
@@ -8,10 +8,10 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"g.fc.run/ai/byre/internal/mcp"
|
||||
"g.fc.run/ai/byre/internal/procgroup"
|
||||
)
|
||||
|
||||
const bashKeep = 64 << 10
|
||||
@@ -68,13 +68,9 @@ func (m *Manager) bash(ctx context.Context, l *live, raw json.RawMessage) (strin
|
||||
|
||||
cctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(cctx, shell, "-l", "-c", args.Command)
|
||||
cmd := procgroup.CommandContext(cctx, shell, "-l", "-c", args.Command)
|
||||
cmd.Dir = l.dir
|
||||
cmd.Env = append(os.Environ(), portEnv(task)...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
cmd.Cancel = func() error {
|
||||
return syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
}
|
||||
cmd.WaitDelay = 5 * time.Second
|
||||
out := &tailWriter{}
|
||||
cmd.Stdout = out
|
||||
|
||||
@@ -8,13 +8,12 @@ import (
|
||||
"log/slog"
|
||||
"maps"
|
||||
"os"
|
||||
"os/exec"
|
||||
"slices"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"g.fc.run/ai/byre/internal/api"
|
||||
"g.fc.run/ai/byre/internal/procgroup"
|
||||
)
|
||||
|
||||
const usageTimeout = 10 * time.Second
|
||||
@@ -127,11 +126,7 @@ func runUsageCommand(cmdline string) (api.Usage, error) {
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), usageTimeout)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, shell, "-l", "-c", cmdline)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
cmd.Cancel = func() error {
|
||||
return syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
}
|
||||
cmd := procgroup.CommandContext(ctx, shell, "-l", "-c", cmdline)
|
||||
cmd.WaitDelay = time.Second
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -22,6 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"g.fc.run/ai/byre/internal/mcp"
|
||||
"g.fc.run/ai/byre/internal/procgroup"
|
||||
)
|
||||
|
||||
const maxRuleBytes = 24000
|
||||
@@ -115,7 +115,7 @@ func (e Event) Result() (Result, error) {
|
||||
}
|
||||
|
||||
type proc struct {
|
||||
cmd *exec.Cmd
|
||||
cmd *procgroup.Cmd
|
||||
stdin io.WriteCloser
|
||||
done chan struct{}
|
||||
expected bool
|
||||
@@ -324,7 +324,7 @@ func (s *Session) spawnLocked() error {
|
||||
}
|
||||
args = append(args, "--print", "")
|
||||
|
||||
cmd := exec.Command("agy", args...)
|
||||
cmd := procgroup.Command("agy", args...)
|
||||
cmd.Dir = s.opts.Cwd
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Env = append(os.Environ(),
|
||||
@@ -334,7 +334,6 @@ func (s *Session) spawnLocked() error {
|
||||
"GIT_COMMITTER_EMAIL="+s.opts.GitEmail,
|
||||
)
|
||||
cmd.Env = append(cmd.Env, s.opts.Env...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
@@ -429,7 +428,7 @@ func (s *Session) restartLocked() error {
|
||||
select {
|
||||
case <-p.done:
|
||||
case <-time.After(10 * time.Second):
|
||||
syscall.Kill(-p.cmd.Process.Pid, syscall.SIGKILL)
|
||||
p.cmd.Kill()
|
||||
<-p.done
|
||||
}
|
||||
return s.spawnLocked()
|
||||
@@ -568,7 +567,7 @@ func (s *Session) Kill() {
|
||||
s.mu.Unlock()
|
||||
|
||||
if p != nil {
|
||||
syscall.Kill(-p.cmd.Process.Pid, syscall.SIGKILL)
|
||||
p.cmd.Kill()
|
||||
<-p.done
|
||||
}
|
||||
s.die()
|
||||
|
||||
@@ -13,13 +13,12 @@ import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"g.fc.run/ai/byre/internal/mcp"
|
||||
"g.fc.run/ai/byre/internal/procgroup"
|
||||
)
|
||||
|
||||
type HookFunc func(ctx context.Context, input json.RawMessage) (map[string]any, error)
|
||||
@@ -194,7 +193,7 @@ func (e Event) Result() (Result, error) {
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
cmd *exec.Cmd
|
||||
cmd *procgroup.Cmd
|
||||
stdin io.WriteCloser
|
||||
events chan Event
|
||||
done chan struct{}
|
||||
@@ -255,11 +254,10 @@ func Start(ctx context.Context, opts Options) (*Session, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.cmd = exec.Command("claude", args...)
|
||||
s.cmd = procgroup.Command("claude", args...)
|
||||
s.cmd.Dir = opts.Cwd
|
||||
s.cmd.Stderr = os.Stderr
|
||||
s.cmd.Env = buildEnv(opts)
|
||||
s.cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
s.stdin, err = s.cmd.StdinPipe()
|
||||
if err != nil {
|
||||
@@ -514,7 +512,7 @@ func (s *Session) Close() error {
|
||||
select {
|
||||
case <-s.done:
|
||||
case <-time.After(5 * time.Second):
|
||||
syscall.Kill(-s.cmd.Process.Pid, syscall.SIGKILL)
|
||||
s.cmd.Kill()
|
||||
<-s.done
|
||||
}
|
||||
|
||||
@@ -522,7 +520,7 @@ func (s *Session) Close() error {
|
||||
}
|
||||
|
||||
func (s *Session) Kill() {
|
||||
syscall.Kill(-s.cmd.Process.Pid, syscall.SIGKILL)
|
||||
s.cmd.Kill()
|
||||
<-s.done
|
||||
s.cmd.Wait()
|
||||
}
|
||||
|
||||
@@ -11,15 +11,14 @@ import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"g.fc.run/ai/byre/internal/mcp"
|
||||
"g.fc.run/ai/byre/internal/procgroup"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
@@ -90,7 +89,7 @@ type rpcResult struct {
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
cmd *exec.Cmd
|
||||
cmd *procgroup.Cmd
|
||||
stdin *os.File
|
||||
events chan Event
|
||||
done chan struct{}
|
||||
@@ -156,11 +155,10 @@ func ReadRateLimits(ctx context.Context, cwd string, env []string) (RateLimitSna
|
||||
}
|
||||
|
||||
func spawn(opts Options) (*Session, error) {
|
||||
cmd := exec.Command("codex", "app-server", "-c", "check_for_update_on_startup=false")
|
||||
cmd := procgroup.Command("codex", "app-server", "-c", "check_for_update_on_startup=false")
|
||||
cmd.Dir = opts.Cwd
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Env = buildEnv(opts)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
stdinR, stdin, err := os.Pipe()
|
||||
if err != nil {
|
||||
@@ -538,7 +536,7 @@ func (s *Session) Close() error {
|
||||
select {
|
||||
case <-s.done:
|
||||
case <-time.After(5 * time.Second):
|
||||
syscall.Kill(-s.cmd.Process.Pid, syscall.SIGKILL)
|
||||
s.cmd.Kill()
|
||||
<-s.done
|
||||
}
|
||||
|
||||
@@ -546,7 +544,7 @@ func (s *Session) Close() error {
|
||||
}
|
||||
|
||||
func (s *Session) Kill() {
|
||||
syscall.Kill(-s.cmd.Process.Pid, syscall.SIGKILL)
|
||||
s.cmd.Kill()
|
||||
<-s.done
|
||||
s.cmd.Wait()
|
||||
}
|
||||
@@ -579,7 +577,7 @@ func (s *Session) write(m message, deadline time.Time) error {
|
||||
n, err := s.stdin.Write(append(b, '\n'))
|
||||
if n > 0 && errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
slog.Error("codex stopped reading its stdin mid-line; killing it", "pid", s.cmd.Process.Pid, "written", n, "len", len(b)+1)
|
||||
syscall.Kill(-s.cmd.Process.Pid, syscall.SIGKILL)
|
||||
s.cmd.Kill()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
+3
-6
@@ -11,8 +11,9 @@ import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"g.fc.run/ai/byre/internal/procgroup"
|
||||
)
|
||||
|
||||
type RepoInfo struct {
|
||||
@@ -435,14 +436,10 @@ func runNetwork(ctx context.Context, dir string, args ...string) (string, string
|
||||
}
|
||||
|
||||
func runCodeInput(ctx context.Context, dir string, env []string, stdin io.Reader, args ...string) (string, string, int, error) {
|
||||
cmd := exec.CommandContext(ctx, "git", args...)
|
||||
cmd := procgroup.CommandContext(ctx, "git", args...)
|
||||
cmd.Dir = dir
|
||||
cmd.Env = append(os.Environ(), env...)
|
||||
cmd.Stdin = stdin
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
cmd.Cancel = func() error {
|
||||
return syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
}
|
||||
cmd.WaitDelay = 5 * time.Second
|
||||
stderr := &strings.Builder{}
|
||||
cmd.Stderr = stderr
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package procgroup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type Cmd struct {
|
||||
*exec.Cmd
|
||||
}
|
||||
|
||||
func Command(name string, args ...string) *Cmd {
|
||||
return group(exec.Command(name, args...))
|
||||
}
|
||||
|
||||
func CommandContext(ctx context.Context, name string, args ...string) *Cmd {
|
||||
cmd := group(exec.CommandContext(ctx, name, args...))
|
||||
cmd.Cancel = cmd.Kill
|
||||
return cmd
|
||||
}
|
||||
|
||||
func group(cmd *exec.Cmd) *Cmd {
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
return &Cmd{Cmd: cmd}
|
||||
}
|
||||
|
||||
func (cmd *Cmd) Kill() error {
|
||||
return syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
}
|
||||
Reference in New Issue
Block a user