Beispiel #1
0
func NewSubProcess(name string, arg ...string) (sp *SubProcess, err error) {
	sp = new(SubProcess)
	if sp.Term, err = pty.NewTerminal(); err != nil {
		return
	}
	sp.cmd = exec.Command(name, arg...)
	sp.DelayBeforeSend = 50 * time.Microsecond
	sp.CheckInterval = time.Microsecond
	if x, y, err := pty.GetWinSize(os.Stdout); err == nil {
		sp.Term.SetWinSize(x, y)

	}
	return
}
Beispiel #2
0
func (sp *SubProcess) InteractTimeout(d time.Duration) (err error) {
	sp.Write(sp.After)
	sp.After = []byte{}
	oldState, _ := pty.Tcgetattr(os.Stdin)
	pty.SetRaw(os.Stdin)
	defer pty.Tcsetattr(os.Stdin, oldState)
	s := make(chan os.Signal, 1)
	signal.Notify(s, syscall.SIGINT, syscall.SIGWINCH, syscall.SIGTSTP)
	go func() {
		for sig := range s {
			switch sig {
			case syscall.SIGINT:
				sp.Term.SendIntr()
			case syscall.SIGWINCH:
				if x, y, err := pty.GetWinSize(os.Stdout); err == nil {
					sp.Term.SetWinSize(x, y)
				}
			default:
				continue
			}
		}
	}()
	execerr := make(chan error, 1)
	if d > 0 {
		go func() {
			time.Sleep(d)
			execerr <- TIMEOUT
		}()
	}
	go func() {
		execerr <- sp.cmd.Wait()
	}()
	in := make(chan byte, 1)
	stdin := bufio.NewReader(os.Stdin)
	go func() error {
		var b byte
		for {
			if b, err = stdin.ReadByte(); err != nil {
				if err == io.EOF {
					sp.Term.SendEOF()
					continue
				} else {
					return err
				}
			}
			in <- b
		}
	}()
	go func() {
		io.Copy(os.Stdout, sp)
		return
	}()
	for {
		select {
		case err := <-execerr:
			return err
		case b := <-in:
			_, err = sp.Write([]byte{b})
		}
	}
	return
}