Skip to content

Commit 1bda1af

Browse files
committed
cmd/gitmirror: kill subprocesses with SIGINT before SIGKILL
Hopefully this fixes golang/go#38887 by allowing the git command to clean up its subprocesses. Fixes golang/go#38887. Change-Id: Iefcb2ee7591a8bfad0df44381a320d27a8f5b4fb Reviewed-on: https://go-review.googlesource.com/c/build/+/325771 Trust: Heschi Kreinick <[email protected]> Trust: Bryan C. Mills <[email protected]> Run-TryBot: Heschi Kreinick <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent 4c0be6e commit 1bda1af

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

cmd/gitmirror/gitmirror.go

+30-2
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ func (r *repo) runGitQuiet(args ...string) ([]byte, []byte, error) {
375375
defer cancel()
376376

377377
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
378-
cmd := exec.CommandContext(ctx, "git", args...)
378+
cmd := exec.Command("git", args...)
379379
if args[0] == "clone" {
380380
// Small hack: if we're cloning, the root doesn't exist yet.
381381
cmd.Dir = "/"
@@ -384,7 +384,7 @@ func (r *repo) runGitQuiet(args ...string) ([]byte, []byte, error) {
384384
}
385385
cmd.Env = append(os.Environ(), "HOME="+r.mirror.homeDir)
386386
cmd.Stdout, cmd.Stderr = stdout, stderr
387-
err := cmd.Run()
387+
err := runCmdContext(ctx, cmd)
388388
return stdout.Bytes(), stderr.Bytes(), err
389389
}
390390

@@ -702,3 +702,31 @@ func handleDebugEnv(w http.ResponseWriter, r *http.Request) {
702702
fmt.Fprintf(w, "%s\n", kv)
703703
}
704704
}
705+
706+
// runCommandContext runs cmd controlled by ctx.
707+
func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
708+
if err := cmd.Start(); err != nil {
709+
return err
710+
}
711+
resChan := make(chan error, 1)
712+
go func() {
713+
resChan <- cmd.Wait()
714+
}()
715+
716+
select {
717+
case err := <-resChan:
718+
return err
719+
case <-ctx.Done():
720+
}
721+
// Canceled. Interrupt and see if it ends voluntarily.
722+
cmd.Process.Signal(os.Interrupt)
723+
select {
724+
case <-resChan:
725+
return ctx.Err()
726+
case <-time.After(time.Second):
727+
}
728+
// Didn't shut down in response to interrupt. Kill it hard.
729+
cmd.Process.Kill()
730+
<-resChan
731+
return ctx.Err()
732+
}

0 commit comments

Comments
 (0)