aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper/direct.go
blob: 9198952d8467b942da9fa0c5b05043f7fec64524 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package helper

import (
	"context"
	"errors"
	"io"
	"sync"

	"git.gensokyo.uk/security/fortify/helper/proc"
)

// direct wraps *exec.Cmd and manages status and args fd.
// Args is always 3 and status if set is always 4.
type direct struct {
	lock sync.RWMutex
	*helperCmd
}

func (h *direct) Start(ctx context.Context, stat bool) error {
	h.lock.Lock()
	defer h.lock.Unlock()

	// Check for doubled Start calls before we defer failure cleanup. If the prior
	// call to Start succeeded, we don't want to spuriously close its pipes.
	if h.Cmd != nil && h.Cmd.Process != nil {
		return errors.New("exec: already started")
	}

	args := h.finalise(ctx, stat)
	h.Cmd.Args = append(h.Cmd.Args, args...)
	return proc.Fulfill(ctx, h.Cmd, h.files, h.extraFiles)
}

// New 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 New(wt io.WriterTo, name string, argF func(argsFd, statFd int) []string) Helper {
	d := new(direct)
	d.helperCmd = newHelperCmd(d, name, wt, argF, nil)
	return d
}