Files
exec/host/host.go
T
2026-06-18 22:39:18 -03:00

145 lines
2.8 KiB
Go

// Run process in host
package host
import (
"io"
"os"
"os/exec"
"path/filepath"
"syscall"
goexec "sirherobrine23.com.br/go-bds/exec/v2/process"
)
var _ = goexec.RegisterProcess(NewProc, "host", "os")
func NewProc() (*Os, error) {
return &Os{}, nil
}
type Os struct {
SysProc *syscall.SysProcAttr
Rootfs string
osProc *exec.Cmd
stdin io.Reader
stdout, stderr io.Writer
}
func (w *Os) Kill() error {
if w.osProc == nil {
return goexec.ErrNoProcess
}
return w.osProc.Process.Kill()
}
func (w *Os) Close() error {
if w.osProc != nil {
return w.Signal(os.Interrupt)
}
return nil
}
func (w *Os) Signal(sig os.Signal) error {
return w.osProc.Process.Signal(sig)
}
func (os *Os) Wait() error {
switch {
case os.osProc != nil && os.osProc.ProcessState != nil:
if !os.osProc.ProcessState.Success() {
return &exec.ExitError{ProcessState: os.osProc.ProcessState}
}
return nil
case os.osProc != nil && os.osProc.Process != nil:
return os.osProc.Wait()
default:
return goexec.ErrNoProcess
}
}
func (os *Os) ExitCode() (int, error) {
switch {
case os.osProc != nil && os.osProc.ProcessState != nil:
return os.osProc.ProcessState.ExitCode(), nil
case os.osProc != nil && os.osProc.Process != nil:
state, err := os.osProc.Process.Wait()
if err != nil {
return -1, err
}
return state.ExitCode(), nil
default:
return -1, goexec.ErrNoProcess
}
}
func (w *Os) AttachStdin(r io.Reader) error {
w.stdin = r
return nil
}
func (w *Os) AttachStdout(w2 io.Writer) error {
w.stdout = w2
return nil
}
func (w *Os) AttachStderr(w2 io.Writer) error {
w.stderr = w2
return nil
}
func (w *Os) Start(options *goexec.Exec) error {
w.osProc = exec.Command(options.Arguments[0], options.Arguments[1:]...)
if options.Context != nil {
w.osProc = exec.CommandContext(options.Context, options.Arguments[0], options.Arguments[1:]...)
// replace to SIGINT Cancel
w.osProc.Cancel = func() error {
return w.osProc.Process.Signal(os.Interrupt)
}
}
w.osProc.SysProcAttr = w.SysProc
if err := w.osProc.Err; err != nil {
return err
}
w.osProc.Env = append(w.osProc.Env, options.Environment.ToSlice()...)
if options.Cwd != "" {
w.osProc.Dir = options.Cwd
}
// Append rootfs to dir start
if w.Rootfs != "" {
w.osProc.Dir = filepath.Join(w.Rootfs, filepath.Clean(w.osProc.Dir))
}
// attach stdin
switch {
case options.Stdin != nil:
w.osProc.Stdin = options.Stdin
case w.stdin != nil:
w.osProc.Stdin = w.stdin
}
// attach stdout
switch {
case options.Stdout != nil:
w.osProc.Stdout = options.Stdout
case w.stdout != nil:
w.osProc.Stdout = w.stdout
}
// attach stderr
switch {
case options.Stderr != nil:
w.osProc.Stderr = options.Stderr
case w.stderr != nil:
w.osProc.Stderr = w.stderr
}
// Start process
if err := w.osProc.Start(); err != nil {
return err
}
return nil
}