in astro/exec2/process.go [108:168]
func (p *Process) Run() error {
command := p.config.Command
args := p.config.Args
logger.Trace.Printf("exec2: running command: %v; args: %v\n", command, args)
p.execCmd = exec.Command(command, args...)
// Apply options
p.execCmd.Dir = p.config.WorkingDir
p.execCmd.Env = p.config.Env
p.configureOutputs()
if isInterrupted {
return fmt.Errorf("astro was interrupted, command won't be run: %s, args: %v", command, args)
}
// If no success codes were given, default to 0
if p.config.ExpectedSuccessCodes == nil {
p.config.ExpectedSuccessCodes = []int{0}
}
// Run the process
started := time.Now()
if err := p.execCmd.Start(); err != nil {
p.time = time.Since(started)
return err
} else {
// wait for the command to finish
waitCh := make(chan error, 1)
go func() {
waitCh <- p.execCmd.Wait()
close(waitCh)
}()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
var errors error
for {
select {
case sig := <-sigChan:
isInterrupted = true
errors = multierror.Append(fmt.Errorf("signal received: %s", sig))
process := p.execCmd.Process
logger.Trace.Printf("Signal: %s, process: %d\n", sig, process.Pid)
if err := process.Signal(sig); err != nil {
errors = multierror.Append(errors, err)
}
case err := <-waitCh:
// Record run time
p.time = time.Since(started)
logger.Trace.Printf("exec2: command exit code: %v\n", p.ExitCode())
// Return an error, if the command didn't exit with a success code
if !p.Success() {
errors = multierror.Append(errors, err)
return fmt.Errorf("%s%v", p.Stderr().String(), errors)
}
return errors
}
}
}
}