diff --git a/main.go b/main.go index f42c75c..2e2fc95 100644 --- a/main.go +++ b/main.go @@ -5,63 +5,29 @@ import ( "io" "os" "time" - - "golang.org/x/term" - - "github.com/aymanbagabas/go-pty" - - "github.com/hymkor/go-windows1x-virtualterminal" ) -func loop(ptmx pty.Pty) error { - watcher := NewWatcher(ptmx) +func mains() error { + term, err := NewTerm() + if err != nil { + return err + } + defer term.Close() - sh := ptmx.Command("cmd.exe") + watcher := NewWatcher(term) + + sh := term.Command("cmd.exe") if err := sh.Start(); err != nil { return err } i := watcher.ExpectWithTimeout(time.Duration(10*time.Second), "100") // i := watcher.Expect("100") - io.WriteString(ptmx, "exit\r") + io.WriteString(term, "\x03exit\r") println(i) return sh.Wait() } -func mains() error { - disableStdout, err := virtualterminal.EnableStdout() - if err != nil { - return err - } - defer disableStdout() - - disableStdin, err := virtualterminal.EnableStdin() - if err != nil { - return err - } - defer disableStdin() - - ptmx, err := pty.New() - if err != nil { - return err - } - defer ptmx.Close() - - width, height, err := term.GetSize(int(os.Stdout.Fd())) - if err != nil { - return err - } - ptmx.Resize(width, height) - - oldState, err := term.MakeRaw(int(os.Stdin.Fd())) - if err != nil { - return err - } - defer term.Restore(int(os.Stdin.Fd()), oldState) - - return loop(ptmx) -} - func main() { if err := mains(); err != nil { fmt.Fprintln(os.Stderr, err.Error()) diff --git a/term.go b/term.go new file mode 100644 index 0000000..3845bdc --- /dev/null +++ b/term.go @@ -0,0 +1,62 @@ +package main + +import ( + "os" + + "golang.org/x/term" + + "github.com/aymanbagabas/go-pty" + + "github.com/hymkor/go-windows1x-virtualterminal" +) + +type Term struct { + pty.Pty + closers []func() +} + +func (T *Term) Close() { + for i := len(T.closers) - 1; i >= 0; i-- { + T.closers[i]() + } + T.closers = nil +} + +func NewTerm() (*Term, error) { + T := &Term{} + + disableStdout, err := virtualterminal.EnableStdout() + if err != nil { + return nil, err + } + T.closers = append(T.closers, disableStdout) + + disableStdin, err := virtualterminal.EnableStdin() + if err != nil { + T.Close() + return nil, err + } + T.closers = append(T.closers, disableStdin) + + T.Pty, err = pty.New() + if err != nil { + T.Close() + return nil, err + } + T.closers = append(T.closers, func() { T.Pty.Close() }) + + width, height, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + T.Close() + return nil, err + } + T.Pty.Resize(width, height) + + oldState, err := term.MakeRaw(int(os.Stdin.Fd())) + if err != nil { + T.Close() + return nil, err + } + T.closers = append(T.closers, func() { term.Restore(int(os.Stdin.Fd()), oldState) }) + return T, nil +}