diff --git a/cargo-generate.toml b/cargo-generate.toml index efa3ccc..8dcf2a3 100644 --- a/cargo-generate.toml +++ b/cargo-generate.toml @@ -1,6 +1,6 @@ [template] cargo_generate_version = ">=0.10.0" -ignore = [".github", "test.py"] +ignore = [".github", "main.go"] [placeholders.program_type] type = "string" diff --git a/main.go b/main.go index 3578a6f..4396f08 100644 --- a/main.go +++ b/main.go @@ -8,8 +8,8 @@ import ( "os/exec" "path/filepath" "runtime" + "strconv" "strings" - "syscall" "time" ) @@ -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) } } @@ -167,14 +167,9 @@ func run() error { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - cmd := exec.CommandContext(ctx, "cargo", "xtask", "run") + cmd := exec.CommandContext(ctx, "sh", "-c", "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 { @@ -192,8 +187,31 @@ 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) + childrenPath := fmt.Sprintf("/proc/%[1]d/task/%[1]d/children", cmd.Process.Pid) + childrenContent, err := os.ReadFile(childrenPath) + if err != nil { + return fmt.Errorf("failed to read %s: %w", childrenPath, err) + } + childrenFields := strings.Fields(string(childrenContent)) + if len(childrenFields) == 0 { + return fmt.Errorf("no children found in %s", childrenPath) + } + for _, childField := range childrenFields { + 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) + } + fmt.Printf("Sending SIGINT to child pid %d\n", child.Pid) + if err := child.Signal(os.Interrupt); err != nil { + return fmt.Errorf("failed to interrupt %d: %w", child, err) + } + } } } if err := scanner.Err(); err != nil {