aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper/pipe.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-02-13 23:15:34 +0900
committerOphestra <cat@gensokyo.uk>2025-02-13 23:34:15 +0900
commitfe7d208cf76fa6f24bb9d12ba29b5ed61d837ce3 (patch)
treecac02af50a13b2078739a8f5a74d219f3b60833d /helper/pipe.go
parent60c287375048b21eab2bd82f1e7d43e36dcfb3a2 (diff)
helper: use generic extra files interface
This replaces the pipes object and integrates context into helper process lifecycle. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'helper/pipe.go')
-rw-r--r--helper/pipe.go149
1 files changed, 0 insertions, 149 deletions
diff --git a/helper/pipe.go b/helper/pipe.go
deleted file mode 100644
index f17b74fb..00000000
--- a/helper/pipe.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package helper
-
-import (
- "errors"
- "io"
- "os"
- "os/exec"
-
- "git.gensokyo.uk/security/fortify/helper/proc"
-)
-
-type pipes struct {
- args io.WriterTo
-
- statP [2]*os.File
- argsP [2]*os.File
-
- ready chan error
-
- cmd *exec.Cmd
-}
-
-func (p *pipes) pipe() error {
- if p.statP[0] != nil || p.statP[1] != nil ||
- p.argsP[0] != nil || p.argsP[1] != nil {
- panic("attempted to pipe twice")
- }
- if p.args == nil {
- panic("attempted to pipe without args")
- }
-
- // create pipes
- if pr, pw, err := os.Pipe(); err != nil {
- return err
- } else {
- p.argsP[0], p.argsP[1] = pr, pw
- }
-
- // create status pipes if ready signal is requested
- if p.ready != nil {
- if pr, pw, err := os.Pipe(); err != nil {
- return err
- } else {
- p.statP[0], p.statP[1] = pr, pw
- }
- }
-
- return nil
-}
-
-// calls pipe to create pipes and sets them up as ExtraFiles, returning their fd
-func (p *pipes) prepareCmd(cmd *exec.Cmd) (argsFd, statFd int, err error) {
- argsFd, statFd = -1, -1
- if err = p.pipe(); err != nil {
- return
- }
-
- // save a reference of cmd for future use
- p.cmd = cmd
-
- argsFd = int(proc.ExtraFile(cmd, p.argsP[0]))
- if p.ready != nil {
- statFd = int(proc.ExtraFile(cmd, p.statP[1]))
- }
-
- return
-}
-
-func (p *pipes) readyWriteArgs() error {
- statsP, argsP := p.statP[0], p.argsP[1]
-
- // write arguments and close args pipe
- if _, err := p.args.WriteTo(argsP); err != nil {
- if err1 := p.cmd.Process.Kill(); err1 != nil {
- // should be unreachable
- panic(err1.Error())
- }
- return err
- } else {
- if err = argsP.Close(); err != nil {
- if err1 := p.cmd.Process.Kill(); err1 != nil {
- // should be unreachable
- panic(err1.Error())
- }
- return err
- }
- }
-
- if p.ready != nil {
- // monitor stat pipe
- go func() {
- n, err := statsP.Read(make([]byte, 1))
- switch n {
- case -1:
- if err1 := p.cmd.Process.Kill(); err1 != nil {
- // should be unreachable
- panic(err1.Error())
- }
- // ensure error is not nil
- if err == nil {
- err = ErrStatusFault
- }
- p.ready <- err
- case 0:
- // ensure error is not nil
- if err == nil {
- err = ErrStatusRead
- }
- p.ready <- err
- case 1:
- p.ready <- nil
- default:
- panic("unreachable") // unexpected read count
- }
- }()
- }
-
- return nil
-}
-
-func (p *pipes) mustClosePipes() {
- if err := p.argsP[0].Close(); err != nil && !errors.Is(err, os.ErrClosed) {
- // unreachable
- panic(err.Error())
- }
- if err := p.argsP[1].Close(); err != nil && !errors.Is(err, os.ErrClosed) {
- // unreachable
- panic(err.Error())
- }
-
- if p.ready != nil {
- if err := p.statP[0].Close(); err != nil && !errors.Is(err, os.ErrClosed) {
- // unreachable
- panic(err.Error())
- }
- if err := p.statP[1].Close(); err != nil && !errors.Is(err, os.ErrClosed) {
- // unreachable
- panic(err.Error())
- }
- }
-}
-
-func (p *pipes) closeStatus() error {
- if p.ready == nil {
- panic("attempted to close helper with no status pipe")
- }
-
- return p.statP[0].Close()
-}