Skip to content

Commit 302e8b6

Browse files
authored
Prevent zombie processes (#16314)
Unfortunately go doesn't always ensure that execd processes are completely waited for. On linux this means that zombie processes can occur. This PR ensures that these are waited for by using signal notifier in serv and passing a context elsewhere. Signed-off-by: Andrew Thornton <[email protected]>
1 parent 365c4e9 commit 302e8b6

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

cmd/serv.go

+24-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@
66
package cmd
77

88
import (
9+
"context"
910
"fmt"
1011
"net/http"
1112
"net/url"
1213
"os"
1314
"os/exec"
15+
"os/signal"
1416
"regexp"
1517
"strconv"
1618
"strings"
19+
"syscall"
1720
"time"
1821

1922
"code.gitea.io/gitea/models"
@@ -273,12 +276,31 @@ func runServ(c *cli.Context) error {
273276
verb = strings.Replace(verb, "-", " ", 1)
274277
}
275278

279+
ctx, cancel := context.WithCancel(context.Background())
280+
defer cancel()
281+
go func() {
282+
// install notify
283+
signalChannel := make(chan os.Signal, 1)
284+
285+
signal.Notify(
286+
signalChannel,
287+
syscall.SIGINT,
288+
syscall.SIGTERM,
289+
)
290+
select {
291+
case <-signalChannel:
292+
case <-ctx.Done():
293+
}
294+
cancel()
295+
signal.Reset()
296+
}()
297+
276298
var gitcmd *exec.Cmd
277299
verbs := strings.Split(verb, " ")
278300
if len(verbs) == 2 {
279-
gitcmd = exec.Command(verbs[0], verbs[1], repoPath)
301+
gitcmd = exec.CommandContext(ctx, verbs[0], verbs[1], repoPath)
280302
} else {
281-
gitcmd = exec.Command(verb, repoPath)
303+
gitcmd = exec.CommandContext(ctx, verb, repoPath)
282304
}
283305

284306
gitcmd.Dir = setting.RepoRootPath

modules/markup/external/external.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package external
66

77
import (
8+
"context"
89
"fmt"
910
"io"
1011
"io/ioutil"
@@ -15,6 +16,7 @@ import (
1516

1617
"code.gitea.io/gitea/modules/log"
1718
"code.gitea.io/gitea/modules/markup"
19+
"code.gitea.io/gitea/modules/process"
1820
"code.gitea.io/gitea/modules/setting"
1921
"code.gitea.io/gitea/modules/util"
2022
)
@@ -96,7 +98,13 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
9698
args = append(args, f.Name())
9799
}
98100

99-
cmd := exec.Command(commands[0], args...)
101+
processCtx, cancel := context.WithCancel(ctx.Ctx)
102+
defer cancel()
103+
104+
pid := process.GetManager().Add(fmt.Sprintf("Render [%s] for %s", commands[0], ctx.URLPrefix), cancel)
105+
defer process.GetManager().Remove(pid)
106+
107+
cmd := exec.CommandContext(processCtx, commands[0], args...)
100108
cmd.Env = append(
101109
os.Environ(),
102110
"GITEA_PREFIX_SRC="+ctx.URLPrefix,

modules/ssh/ssh.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func sessionHandler(session ssh.Session) {
6666

6767
args := []string{"serv", "key-" + keyID, "--config=" + setting.CustomConf}
6868
log.Trace("SSH: Arguments: %v", args)
69-
cmd := exec.Command(setting.AppPath, args...)
69+
cmd := exec.CommandContext(session.Context(), setting.AppPath, args...)
7070
cmd.Env = append(
7171
os.Environ(),
7272
"SSH_ORIGINAL_COMMAND="+command,

0 commit comments

Comments
 (0)