commit | 521317be5ebc228a0f0ede099fa2a0b5ece22e49 | [log] [tgz] |
---|---|---|
author | Okunev Yu Dmitry <xaionaro@gmail.com> | Mon Mar 18 14:38:44 2019 +0200 |
committer | Guillaume J. Charmes <guillaume+github@charmes.net> | Mon Mar 18 08:38:44 2019 -0400 |
tree | e7c97c7e25eb544d96c7adbda5c97fbc87d477b4 | |
parent | 7dc38fb350b1d71383eed149e73acb7bae231ddb [diff] |
Don't set Stdin/Stdout/Stderr if already set (#71) * only set stdout and stderr if not already set * Don't set cmd.Stdin if it's already set Considered @craek's codereview
Pty is a Go package for using unix pseudo-terminals.
go get github.com/kr/pty
package main import ( "github.com/kr/pty" "io" "os" "os/exec" ) func main() { c := exec.Command("grep", "--color=auto", "bar") f, err := pty.Start(c) if err != nil { panic(err) } go func() { f.Write([]byte("foo\n")) f.Write([]byte("bar\n")) f.Write([]byte("baz\n")) f.Write([]byte{4}) // EOT }() io.Copy(os.Stdout, f) }
package main import ( "io" "log" "os" "os/exec" "os/signal" "syscall" "github.com/kr/pty" "golang.org/x/crypto/ssh/terminal" ) func test() error { // Create arbitrary command. c := exec.Command("bash") // Start the command with a pty. ptmx, err := pty.Start(c) if err != nil { return err } // Make sure to close the pty at the end. defer func() { _ = ptmx.Close() }() // Best effort. // Handle pty size. ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGWINCH) go func() { for range ch { if err := pty.InheritSize(os.Stdin, ptmx); err != nil { log.Printf("error resizing pty: %s", err) } } }() ch <- syscall.SIGWINCH // Initial resize. // Set stdin in raw mode. oldState, err := terminal.MakeRaw(int(os.Stdin.Fd())) if err != nil { panic(err) } defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort. // Copy stdin to the pty and the pty to stdout. go func() { _, _ = io.Copy(ptmx, os.Stdin) }() _, _ = io.Copy(os.Stdout, ptmx) return nil } func main() { if err := test(); err != nil { log.Fatal(err) } }