in executors/shell/executor_shell.go [69:126]
func (s *executor) Run(cmd common.ExecutorCommand) error {
// Create execution command
c := exec.Command(s.BuildShell.Command, s.BuildShell.Arguments...)
if c == nil {
return errors.New("Failed to generate execution command")
}
helpers.SetProcessGroup(c)
defer helpers.KillProcessGroup(c)
// Fill process environment variables
c.Env = append(os.Environ(), s.BuildShell.Environment...)
c.Stdout = s.Trace
c.Stderr = s.Trace
if s.BuildShell.PassFile {
scriptDir, err := ioutil.TempDir("", "build_script")
if err != nil {
return err
}
defer os.RemoveAll(scriptDir)
scriptFile := filepath.Join(scriptDir, "script."+s.BuildShell.Extension)
err = ioutil.WriteFile(scriptFile, []byte(cmd.Script), 0700)
if err != nil {
return err
}
c.Args = append(c.Args, scriptFile)
} else {
c.Stdin = bytes.NewBufferString(cmd.Script)
}
// Start a process
err := c.Start()
if err != nil {
return fmt.Errorf("Failed to start process: %s", err)
}
// Wait for process to finish
waitCh := make(chan error)
go func() {
err := c.Wait()
if _, ok := err.(*exec.ExitError); ok {
err = &common.BuildError{Inner: err}
}
waitCh <- err
}()
// Support process abort
select {
case err = <-waitCh:
return err
case <-cmd.Context.Done():
return s.killAndWait(c, waitCh)
}
}