Ophestra
124743ffd3
App is no longer just a simple [exec.Cmd] wrapper, so exposing these steps separately no longer makes sense and actually hinders proper error handling, cleanup and cancellation. This change removes the five-second wait when the shim dies before receiving the payload, and provides caller the ability to gracefully stop execution of the confined process. Signed-off-by: Ophestra <cat@gensokyo.uk>
46 lines
1.0 KiB
Go
46 lines
1.0 KiB
Go
package proc
|
|
|
|
import (
|
|
"encoding/gob"
|
|
"errors"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
var (
|
|
ErrNotSet = errors.New("environment variable not set")
|
|
ErrInvalid = errors.New("bad file descriptor")
|
|
)
|
|
|
|
// Setup appends the read end of a pipe for payload transmission and returns its fd.
|
|
func Setup(extraFiles *[]*os.File) (int, *gob.Encoder, error) {
|
|
if r, w, err := os.Pipe(); err != nil {
|
|
return -1, nil, err
|
|
} else {
|
|
fd := 3 + len(*extraFiles)
|
|
*extraFiles = append(*extraFiles, r)
|
|
return fd, gob.NewEncoder(w), nil
|
|
}
|
|
}
|
|
|
|
// Receive retrieves payload pipe fd from the environment,
|
|
// receives its payload and returns the Close method of the pipe.
|
|
func Receive(key string, e any) (func() error, error) {
|
|
var setup *os.File
|
|
|
|
if s, ok := os.LookupEnv(key); !ok {
|
|
return nil, ErrNotSet
|
|
} else {
|
|
if fd, err := strconv.Atoi(s); err != nil {
|
|
return nil, err
|
|
} else {
|
|
setup = os.NewFile(uintptr(fd), "setup")
|
|
if setup == nil {
|
|
return nil, ErrInvalid
|
|
}
|
|
}
|
|
}
|
|
|
|
return func() error { return setup.Close() }, gob.NewDecoder(setup).Decode(e)
|
|
}
|