// 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 }