aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-03-15 00:33:25 +0900
committerOphestra <cat@gensokyo.uk>2025-03-15 00:33:25 +0900
commit73c1a830320636f91a0d15d6d247e88650e81df1 (patch)
tree74534bcb04f289047135cc0a61ee06317c5f7b6c /helper
parentf443d315ad60d761c06135569abb0adb183ac8c1 (diff)
helper: move process wrapper to direct
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'helper')
-rw-r--r--helper/direct.go109
-rw-r--r--helper/helper.go87
2 files changed, 96 insertions, 100 deletions
diff --git a/helper/direct.go b/helper/direct.go
index 93eae227..16aede83 100644
--- a/helper/direct.go
+++ b/helper/direct.go
@@ -4,12 +4,33 @@ import (
"context"
"errors"
"io"
+ "os"
"os/exec"
+ "slices"
"sync"
+ "syscall"
"git.gensokyo.uk/security/fortify/helper/proc"
)
+// NewDirect initialises a new direct Helper instance with wt as the null-terminated argument writer.
+// Function argF returns an array of arguments passed directly to the child process.
+func NewDirect(
+ ctx context.Context,
+ wt io.WriterTo,
+ name string,
+ argF func(argsFd, statFd int) []string,
+ cmdF func(cmd *exec.Cmd),
+ stat bool,
+) Helper {
+ d := new(direct)
+ d.helperCmd = newHelperCmd(ctx, name, wt, argF, nil, stat)
+ if cmdF != nil {
+ cmdF(d.helperCmd.Cmd)
+ }
+ return d
+}
+
// direct starts the helper directly and manages status and args fd.
type direct struct {
lock sync.RWMutex
@@ -31,20 +52,78 @@ func (h *direct) Start() error {
return proc.Fulfill(h.ctx, &h.ExtraFiles, h.Cmd.Start, h.files, h.extraFiles)
}
-// NewDirect initialises a new direct Helper instance with wt as the null-terminated argument writer.
-// Function argF returns an array of arguments passed directly to the child process.
-func NewDirect(
- ctx context.Context,
- wt io.WriterTo,
- name string,
- argF func(argsFd, statFd int) []string,
- cmdF func(cmd *exec.Cmd),
- stat bool,
-) Helper {
- d := new(direct)
- d.helperCmd = newHelperCmd(ctx, name, wt, argF, nil, stat)
- if cmdF != nil {
- cmdF(d.helperCmd.Cmd)
+func newHelperCmd(
+ ctx context.Context, name string,
+ wt io.WriterTo, argF func(argsFd, statFd int) []string,
+ extraFiles []*os.File, stat bool,
+) (cmd *helperCmd) {
+ cmd = new(helperCmd)
+ cmd.ctx = ctx
+ cmd.hasStatFd = stat
+
+ cmd.Cmd = commandContext(ctx, name)
+ cmd.Cmd.Cancel = func() error { return cmd.Process.Signal(syscall.SIGTERM) }
+ cmd.WaitDelay = WaitDelay
+
+ cmd.extraFiles = new(proc.ExtraFilesPre)
+ for _, f := range extraFiles {
+ _, v := cmd.extraFiles.Append()
+ *v = f
}
- return d
+
+ argsFd := -1
+ if wt != nil {
+ f := proc.NewWriterTo(wt)
+ argsFd = int(proc.InitFile(f, cmd.extraFiles))
+ cmd.files = append(cmd.files, f)
+ cmd.hasArgsFd = true
+ }
+ cmd.argF = func(statFd int) []string { return argF(argsFd, statFd) }
+
+ return
+}
+
+// helperCmd wraps Cmd and implements methods shared across all Helper implementations.
+type helperCmd struct {
+ // returns an array of arguments passed directly
+ // to the helper process
+ argF func(statFd int) []string
+ // whether argsFd is present
+ hasArgsFd bool
+ // whether statFd is present
+ hasStatFd bool
+
+ // closes statFd
+ stat io.Closer
+ // deferred extraFiles fulfillment
+ files []proc.File
+ // passed through to [proc.Fulfill] and [proc.InitFile]
+ extraFiles *proc.ExtraFilesPre
+
+ ctx context.Context
+ *exec.Cmd
+}
+
+// finalise sets up the underlying [exec.Cmd] object.
+func (h *helperCmd) finalise() (args []string) {
+ h.Env = slices.Grow(h.Env, 2)
+ if h.hasArgsFd {
+ h.Cmd.Env = append(h.Env, FortifyHelper+"=1")
+ } else {
+ h.Cmd.Env = append(h.Env, FortifyHelper+"=0")
+ }
+
+ statFd := -1
+ if h.hasStatFd {
+ f := proc.NewStat(&h.stat)
+ statFd = int(proc.InitFile(f, h.extraFiles))
+ h.files = append(h.files, f)
+ h.Cmd.Env = append(h.Cmd.Env, FortifyStatus+"=1")
+
+ // stat is populated on fulfill
+ h.Cmd.Cancel = func() error { return h.stat.Close() }
+ } else {
+ h.Cmd.Env = append(h.Cmd.Env, FortifyStatus+"=0")
+ }
+ return h.argF(statFd)
}
diff --git a/helper/helper.go b/helper/helper.go
index c500c63e..ab276442 100644
--- a/helper/helper.go
+++ b/helper/helper.go
@@ -2,20 +2,15 @@
package helper
import (
- "context"
"fmt"
- "io"
- "os"
"os/exec"
- "slices"
- "syscall"
"time"
-
- "git.gensokyo.uk/security/fortify/helper/proc"
)
var (
WaitDelay = 2 * time.Second
+
+ commandContext = exec.CommandContext
)
const (
@@ -33,81 +28,3 @@ type Helper interface {
fmt.Stringer
}
-
-func newHelperCmd(
- ctx context.Context, name string,
- wt io.WriterTo, argF func(argsFd, statFd int) []string,
- extraFiles []*os.File, stat bool,
-) (cmd *helperCmd) {
- cmd = new(helperCmd)
- cmd.ctx = ctx
- cmd.hasStatFd = stat
-
- cmd.Cmd = commandContext(ctx, name)
- cmd.Cmd.Cancel = func() error { return cmd.Process.Signal(syscall.SIGTERM) }
- cmd.WaitDelay = WaitDelay
-
- cmd.extraFiles = new(proc.ExtraFilesPre)
- for _, f := range extraFiles {
- _, v := cmd.extraFiles.Append()
- *v = f
- }
-
- argsFd := -1
- if wt != nil {
- f := proc.NewWriterTo(wt)
- argsFd = int(proc.InitFile(f, cmd.extraFiles))
- cmd.files = append(cmd.files, f)
- cmd.hasArgsFd = true
- }
- cmd.argF = func(statFd int) []string { return argF(argsFd, statFd) }
-
- return
-}
-
-// helperCmd wraps Cmd and implements methods shared across all Helper implementations.
-type helperCmd struct {
- // returns an array of arguments passed directly
- // to the helper process
- argF func(statFd int) []string
- // whether argsFd is present
- hasArgsFd bool
- // whether statFd is present
- hasStatFd bool
-
- // closes statFd
- stat io.Closer
- // deferred extraFiles fulfillment
- files []proc.File
- // passed through to [proc.Fulfill] and [proc.InitFile]
- extraFiles *proc.ExtraFilesPre
-
- ctx context.Context
- *exec.Cmd
-}
-
-// finalise sets up the underlying [exec.Cmd] object.
-func (h *helperCmd) finalise() (args []string) {
- h.Env = slices.Grow(h.Env, 2)
- if h.hasArgsFd {
- h.Cmd.Env = append(h.Env, FortifyHelper+"=1")
- } else {
- h.Cmd.Env = append(h.Env, FortifyHelper+"=0")
- }
-
- statFd := -1
- if h.hasStatFd {
- f := proc.NewStat(&h.stat)
- statFd = int(proc.InitFile(f, h.extraFiles))
- h.files = append(h.files, f)
- h.Cmd.Env = append(h.Cmd.Env, FortifyStatus+"=1")
-
- // stat is populated on fulfill
- h.Cmd.Cancel = func() error { return h.stat.Close() }
- } else {
- h.Cmd.Env = append(h.Cmd.Env, FortifyStatus+"=0")
- }
- return h.argF(statFd)
-}
-
-var commandContext = exec.CommandContext