diff --git a/githttpxfer/git.go b/githttpxfer/git.go index ab3461a..de667f9 100644 --- a/githttpxfer/git.go +++ b/githttpxfer/git.go @@ -6,6 +6,7 @@ import ( "os" "os/exec" "path" + "syscall" ) func newGit(rootPath string, binPath string, uploadPack bool, receivePack bool) *git { @@ -49,6 +50,7 @@ func (g *git) Exists(repoPath string) bool { func (g *git) GitCommand(repoPath string, args ...string) *exec.Cmd { command := exec.Command(g.binPath, args...) command.Dir = g.GetAbsolutePath(repoPath) + command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} return command } diff --git a/githttpxfer/githttpxfer.go b/githttpxfer/githttpxfer.go index b031b7b..6572715 100644 --- a/githttpxfer/githttpxfer.go +++ b/githttpxfer/githttpxfer.go @@ -266,6 +266,7 @@ func (ghx *GitHTTPXfer) serviceRPC(ctx Context, rpc string) { args := []string{rpc, "--stateless-rpc", "."} cmd := ghx.Git.GitCommand(repoPath, args...) cmd.Env = ctx.Env() + defer cleanUpProcessGroup(cmd) stdin, err := cmd.StdinPipe() if err != nil { @@ -283,7 +284,8 @@ func (ghx *GitHTTPXfer) serviceRPC(ctx Context, rpc string) { } defer stdout.Close() - if err = cmd.Start(); err != nil { + err = cmd.Start() + if err != nil { ghx.logger.Error("failed to starts the specified command. ", err.Error()) RenderInternalServerError(res.Writer) return diff --git a/githttpxfer/support.go b/githttpxfer/support.go index e987b74..28fd678 100644 --- a/githttpxfer/support.go +++ b/githttpxfer/support.go @@ -2,7 +2,9 @@ package githttpxfer import ( "net/http" + "os/exec" "strings" + "syscall" ) func getServiceType(req *http.Request) string { @@ -12,3 +14,13 @@ func getServiceType(req *http.Request) string { } return strings.Replace(serviceType, "git-", "", 1) } + +func cleanUpProcessGroup(cmd *exec.Cmd) { + if cmd == nil { + return + } + if process := cmd.Process; process != nil && process.Pid > 0 { + syscall.Kill(-process.Pid, syscall.SIGTERM) + } + cmd.Wait() +}