package owrt import ( "bytes" "log" "os/exec" "syscall" ) // Executor interface to describe command runners signature type Executor interface { Run(command string, params ...string) *CommandResult } // CommandResult contain all information about a command execution, stdout, stderr type CommandResult struct { Stdout string Stderr string ReturnCode int } type localExecutor struct{} func (e *localExecutor) Run(command string, params ...string) *CommandResult { var out bytes.Buffer var outerr bytes.Buffer var exitCode int exe := exec.Command(command, params...) exe.Stdout = &out exe.Stderr = &outerr err := exe.Run() if err != nil { // try to get the exit code if exitError, ok := err.(*exec.ExitError); ok { ws := exitError.Sys().(syscall.WaitStatus) exitCode = ws.ExitStatus() } else { log.Printf("Could not get exit code for failed program: %v, %v", command, params) } } else { // success, exitCode should be 0 if go is ok ws := exe.ProcessState.Sys().(syscall.WaitStatus) exitCode = ws.ExitStatus() } return &CommandResult{ Stdout: out.String(), Stderr: outerr.String(), ReturnCode: exitCode, } }