package runtime import ( "os" "os/exec" "github.com/creack/pty" ) // CreatePTY starts cmd attached to a PTY and returns the PTY file. func CreatePTY(cmd *exec.Cmd) (*os.File, error) { ptmx, err := pty.Start(cmd) if err != nil { return nil, err } return ptmx, nil } // ReadLoop reads from a PTY in non-blocking mode and streams chunks to onData. func ReadLoop(ptyFile *os.File, stop <-chan struct{}, onData func([]byte) error) error { buf := make([]byte, 4096) for { n, err := ptyFile.Read(buf) if n > 0 { if writeErr := onData(buf[:n]); writeErr != nil { return writeErr } } if err != nil { return err } select { case <-stop: return nil default: } } } // Write sends data to the PTY. func Write(ptyFile *os.File, data []byte) error { _, err := ptyFile.Write(data) return err }