tty_term.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package namespaces
  2. import (
  3. "io"
  4. "os"
  5. "os/exec"
  6. "github.com/dotcloud/docker/pkg/term"
  7. )
  8. type TtyTerminal struct {
  9. stdin io.Reader
  10. stdout, stderr io.Writer
  11. master *os.File
  12. state *term.State
  13. }
  14. func (t *TtyTerminal) Resize(h, w int) error {
  15. return term.SetWinsize(t.master.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
  16. }
  17. func (t *TtyTerminal) SetMaster(master *os.File) {
  18. t.master = master
  19. }
  20. func (t *TtyTerminal) Attach(command *exec.Cmd) error {
  21. go io.Copy(t.stdout, t.master)
  22. go io.Copy(t.master, t.stdin)
  23. state, err := t.setupWindow(t.master, os.Stdin)
  24. if err != nil {
  25. return err
  26. }
  27. t.state = state
  28. return err
  29. }
  30. // SetupWindow gets the parent window size and sets the master
  31. // pty to the current size and set the parents mode to RAW
  32. func (t *TtyTerminal) setupWindow(master, parent *os.File) (*term.State, error) {
  33. ws, err := term.GetWinsize(parent.Fd())
  34. if err != nil {
  35. return nil, err
  36. }
  37. if err := term.SetWinsize(master.Fd(), ws); err != nil {
  38. return nil, err
  39. }
  40. return term.SetRawTerminal(parent.Fd())
  41. }
  42. func (t *TtyTerminal) Close() error {
  43. term.RestoreTerminal(os.Stdin.Fd(), t.state)
  44. return t.master.Close()
  45. }