Skip to content

Commit

Permalink
innermost child
Browse files Browse the repository at this point in the history
  • Loading branch information
tamird committed Oct 18, 2024
1 parent 897520f commit 21d8d4b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,6 @@ jobs:
with:
go-version: stable
- run: go run main.go ${{ github.workspace }} ${{ matrix.program }}

- uses: mxschmitt/action-tmate@v3
if: ${{ failure() }}
2 changes: 1 addition & 1 deletion cargo-generate.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[template]
cargo_generate_version = ">=0.10.0"
ignore = [".github", "test.py"]
ignore = [".github", "main.go"]

[placeholders.program_type]
type = "string"
Expand Down
55 changes: 46 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"syscall"
"time"
)

Expand Down Expand Up @@ -157,9 +157,9 @@ func run() error {
cmd.Env = cmdSpec.Env
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
fmt.Printf("%+v\n", cmdSpec)
fmt.Printf("%#v\n", cmdSpec)
if err := cmd.Run(); err != nil {
return fmt.Errorf("%+v failed: %w", cmdSpec, err)
return fmt.Errorf("%#v failed: %w", cmdSpec, err)
}
}

Expand All @@ -170,11 +170,6 @@ func run() error {
cmd := exec.CommandContext(ctx, "cargo", "xtask", "run")
cmd.Dir = projectDir
cmd.Stderr = os.Stderr
// Prevent the child process from being in our process group so that we can send it a SIGINT
// without sending one to ourselves.
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}

stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
Expand All @@ -192,8 +187,11 @@ func run() error {
if _, err := fmt.Fprintln(os.Stdout, text); err != nil {
panic(err)
}

if strings.Contains(text, "Waiting for Ctrl-C") {
syscall.Kill(-cmd.Process.Pid, syscall.SIGINT)
if err := signalChildren(cmd.Process); err != nil {
return fmt.Errorf("failed to signal children of %d: %w", cmd.Process.Pid, err)
}
}
}
if err := scanner.Err(); err != nil {
Expand All @@ -207,3 +205,42 @@ func run() error {

return nil
}

func signalChildren(process *os.Process) error {
fmt.Printf("Sending SIGINT to children of pid %d\n", process.Pid)
taskPath := fmt.Sprintf("/proc/%d/task", process.Pid)
entries, err := os.ReadDir(taskPath)
if err != nil {
return fmt.Errorf("failed to readdir %s: %w", taskPath, err)
}
for _, entry := range entries {
if !entry.IsDir() {
continue
}
childrenPath := fmt.Sprintf("%s/%s/children", taskPath, entry.Name())
childrenContent, err := os.ReadFile(childrenPath)
if err != nil {
return fmt.Errorf("failed to read %s: %w", childrenPath, err)
}
for _, childField := range strings.Fields(string(childrenContent)) {
childPid, err := strconv.Atoi(childField)
if err != nil {
return fmt.Errorf("failed to parse %s: %w", childField, err)
}
child, err := os.FindProcess(childPid)
if err != nil {
return fmt.Errorf("failed to find process %d: %w", childPid, err)
}
if err := signalChildren(child); err != nil {
return fmt.Errorf("failed to signal children of %d: %w", child.Pid, err)
}
}
}
fmt.Printf("Sending SIGINT to pid %d\n", process.Pid)
if err := process.Signal(os.Interrupt); err != nil {
if _, err := fmt.Fprintf(os.Stderr, "failed to interrupt %d: %s", process, err); err != nil {
panic(err)
}
}
return nil
}

0 comments on commit 21d8d4b

Please sign in to comment.