func ShellInteractiveCommand()

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
}