in util/util.go [443:514]
func ShellInteractiveCommand(cmdStr []string, env map[string]string,
flagBlock bool) error {
// Escape special characters for Windows.
fixupCmdArgs(cmdStr)
var newt_sh string
if runtime.GOOS == "windows" && strings.HasSuffix(cmdStr[0], ".sh") {
newt_sh = os.Getenv("NEWT_SH")
if newt_sh == "" {
bash, err := exec.LookPath("bash")
if err != nil {
return err
}
newt_sh = bash
}
cmdStr = append([]string{newt_sh}, cmdStr...)
}
log.Print("[VERBOSE] " + cmdStr[0])
c := make(chan os.Signal, 1)
// Block SIGINT, at least.
// Otherwise Ctrl-C meant for gdb would kill newt.
if flagBlock == false {
signal.Notify(c, os.Interrupt)
signal.Notify(c, syscall.SIGTERM)
go func() {
<-c
}()
}
m, err := EnvironAsMap()
if err != nil {
return err
}
for k, v := range env {
m[k] = v
}
envSlice := EnvVarsToSlice(m)
// Transfer stdin, stdout, and stderr to the new process
// and also set target directory for the shell to start in.
// and set the additional environment variables
pa := os.ProcAttr{
Env: envSlice,
Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
}
// Start up a new shell.
proc, err := os.StartProcess(cmdStr[0], cmdStr, &pa)
if err != nil {
signal.Stop(c)
return NewNewtError(err.Error())
}
// Release and exit
state, err := proc.Wait()
signal.Stop(c)
if err != nil {
return NewNewtError(err.Error())
}
if state.ExitCode() != 0 {
return FmtNewtError(
"command %v exited with nonzero status %d",
cmdStr, state.ExitCode())
}
return nil
}