// waitStatusToStateUpdate converts syscall.WaitStatus to a StateUpdate. func waitStatusToStateUpdate(ws syscall.WaitStatus) *stateUpdate { switch { case ws.Exited(): es := ws.ExitStatus() if es == 0 { return newExitedStateUpdate(ok) } return newExitedStateUpdate(newFailure(fmt.Sprint(es))) case ws.Signaled(): msg := fmt.Sprintf("signaled %v", ws.Signal()) if ws.CoreDump() { msg += " (core dumped)" } return newUnexitedStateUpdate(msg) case ws.Stopped(): msg := fmt.Sprintf("stopped %v", ws.StopSignal()) trap := ws.TrapCause() if trap != -1 { msg += fmt.Sprintf(" (trapped %v)", trap) } return newUnexitedStateUpdate(msg) case ws.Continued(): return newUnexitedStateUpdate("continued") default: return newUnexitedStateUpdate(fmt.Sprint("unknown status", ws)) } }
func printStatus(ws syscall.WaitStatus) string { switch { case ws.Exited(): es := ws.ExitStatus() if es == 0 { return "" } return fmt.Sprintf("exited %v", es) case ws.Signaled(): msg := fmt.Sprintf("signaled %v", ws.Signal()) if ws.CoreDump() { msg += " (core dumped)" } return msg case ws.Stopped(): msg := fmt.Sprintf("stopped %v", ws.StopSignal()) trap := ws.TrapCause() if trap != -1 { msg += fmt.Sprintf(" (trapped %v)", trap) } return msg case ws.Continued(): return "continued" default: return fmt.Sprintf("unknown status %v", ws) } }
// waitStatusToError converts syscall.WaitStatus to an Error. func waitStatusToError(ws syscall.WaitStatus) error { switch { case ws.Exited(): es := ws.ExitStatus() if es == 0 { return nil } return errors.New(fmt.Sprint(es)) case ws.Signaled(): msg := fmt.Sprintf("signaled %v", ws.Signal()) if ws.CoreDump() { msg += " (core dumped)" } return errors.New(msg) case ws.Stopped(): msg := fmt.Sprintf("stopped %v", ws.StopSignal()) trap := ws.TrapCause() if trap != -1 { msg += fmt.Sprintf(" (trapped %v)", trap) } return errors.New(msg) /* case ws.Continued(): return newUnexitedStateUpdate("continued") */ default: return fmt.Errorf("unknown WaitStatus", ws) } }
func (self *server) Execute(req *pb.ExecutionRequest, resp pb.Builder_ExecuteServer) error { if len(req.Args) == 0 { return fmt.Errorf("Request has no command to execute.") } var args []string if len(req.Args) > 1 { args = req.Args[1:] } if req.BuildEnv == nil { return fmt.Errorf("No build environment present") } else if err := sig.VerifyEnv(req.BuildEnv); err != nil { return fmt.Errorf("Failure verifying build environment: %s", err) } cmd := exec.Command(req.Args[0], args...) cmd.Env = convertEnv(req.GetEnv()) cmd.Stdin = bytes.NewReader(req.Stdin) cmd.Dir = req.BuildEnv.Path glog.V(1).Infof("Commands to execute %v (build dir: %s)", req, cmd.Dir) stdoutPipe, err := cmd.StdoutPipe() if err != nil { return err } stderrPipe, err := cmd.StderrPipe() if err != nil { return err } if err = cmd.Start(); err != nil { return err } streamReader(stdoutPipe, stderrPipe, resp) err = cmd.Wait() var status syscall.WaitStatus if err != nil { if _, ok := err.(*exec.ExitError); ok { status = err.(*exec.ExitError).Sys().(syscall.WaitStatus) } else { return err } } else if cmd.ProcessState != nil { status = cmd.ProcessState.Sys().(syscall.WaitStatus) } s := &pb.Status{ CoreDump: status.CoreDump(), Exited: status.Exited(), ExitStatus: int32(status.ExitStatus()), Signaled: status.Signaled(), Signal: int32(status.Signal()), } resp.Send(&pb.ExecutionResponse{Status: s}) return nil }