From 592c2f6f9a472bda227a03c819f73b8edc7c3320 Mon Sep 17 00:00:00 2001
From: Michael Crosby <michael@crosbymichael.com>
Date: Fri, 21 Feb 2014 12:42:37 -0800
Subject: [PATCH] Move term creation into driver Docker-DCO-1.1-Signed-off-by:
 Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

---
 container.go             |  3 --
 execdriver/lxc/driver.go |  6 ++--
 execdriver/term.go       | 61 ++++++++++++++++++++--------------------
 3 files changed, 33 insertions(+), 37 deletions(-)

diff --git a/container.go b/container.go
index 025479f240..733a31d5a2 100644
--- a/container.go
+++ b/container.go
@@ -530,9 +530,6 @@ func (container *Container) Start() (err error) {
 	}
 
 	populateCommand(container)
-	if err := execdriver.NewTerminal(container.command); err != nil {
-		return err
-	}
 
 	// Setup logging of stdout and stderr to disk
 	if err := container.runtime.LogToDisk(container.stdout, container.logPath("json"), "stdout"); err != nil {
diff --git a/execdriver/lxc/driver.go b/execdriver/lxc/driver.go
index da3bc1ec7c..c18b2e6ab4 100644
--- a/execdriver/lxc/driver.go
+++ b/execdriver/lxc/driver.go
@@ -77,10 +77,8 @@ func (d *driver) Name() string {
 }
 
 func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
-	if c.Terminal != nil {
-		if err := c.Terminal.Attach(pipes); err != nil {
-			return -1, err
-		}
+	if err := execdriver.SetTerminal(c, pipes); err != nil {
+		return -1, err
 	}
 	configPath, err := d.generateLXCConfig(c)
 	if err != nil {
diff --git a/execdriver/term.go b/execdriver/term.go
index e7ec46653c..ab399e8337 100644
--- a/execdriver/term.go
+++ b/execdriver/term.go
@@ -10,7 +10,6 @@ import (
 type Term interface {
 	io.Closer
 	Resize(height, width int) error
-	Attach(pipes *Pipes) error
 }
 
 type Pipes struct {
@@ -29,15 +28,15 @@ func NewPipes(stdin io.ReadCloser, stdout, stderr io.WriteCloser, useStdin bool)
 	return p
 }
 
-func NewTerminal(command *Command) error {
+func SetTerminal(command *Command, pipes *Pipes) error {
 	var (
 		term Term
 		err  error
 	)
 	if command.Tty {
-		term, err = NewTtyConsole(command)
+		term, err = NewTtyConsole(command, pipes)
 	} else {
-		term, err = NewStdConsole(command)
+		term, err = NewStdConsole(command, pipes)
 	}
 	if err != nil {
 		return err
@@ -47,20 +46,22 @@ func NewTerminal(command *Command) error {
 }
 
 type TtyConsole struct {
-	command *Command
-	Master  *os.File
-	Slave   *os.File
+	Master *os.File
+	Slave  *os.File
 }
 
-func NewTtyConsole(command *Command) (*TtyConsole, error) {
+func NewTtyConsole(command *Command, pipes *Pipes) (*TtyConsole, error) {
 	ptyMaster, ptySlave, err := pty.Open()
 	if err != nil {
 		return nil, err
 	}
 	tty := &TtyConsole{
-		Master:  ptyMaster,
-		Slave:   ptySlave,
-		command: command,
+		Master: ptyMaster,
+		Slave:  ptySlave,
+	}
+	if err := tty.attach(command, pipes); err != nil {
+		tty.Close()
+		return nil, err
 	}
 	return tty, nil
 }
@@ -69,11 +70,10 @@ func (t *TtyConsole) Resize(h, w int) error {
 	return term.SetWinsize(t.Master.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
 }
 
-func (t *TtyConsole) Attach(pipes *Pipes) error {
-	t.command.Stdout = t.Slave
-	t.command.Stderr = t.Slave
-
-	t.command.Console = t.Slave.Name()
+func (t *TtyConsole) attach(command *Command, pipes *Pipes) error {
+	command.Stdout = t.Slave
+	command.Stderr = t.Slave
+	command.Console = t.Slave.Name()
 
 	go func() {
 		defer pipes.Stdout.Close()
@@ -81,8 +81,8 @@ func (t *TtyConsole) Attach(pipes *Pipes) error {
 	}()
 
 	if pipes.Stdin != nil {
-		t.command.Stdin = t.Slave
-		t.command.SysProcAttr.Setctty = true
+		command.Stdin = t.Slave
+		command.SysProcAttr.Setctty = true
 
 		go func() {
 			defer pipes.Stdin.Close()
@@ -93,27 +93,28 @@ func (t *TtyConsole) Attach(pipes *Pipes) error {
 }
 
 func (t *TtyConsole) Close() error {
-	err := t.Slave.Close()
-	if merr := t.Master.Close(); err == nil {
-		err = merr
-	}
-	return err
+	t.Slave.Close()
+	return t.Master.Close()
 }
 
 type StdConsole struct {
-	command *Command
 }
 
-func NewStdConsole(command *Command) (*StdConsole, error) {
-	return &StdConsole{command}, nil
+func NewStdConsole(command *Command, pipes *Pipes) (*StdConsole, error) {
+	std := &StdConsole{}
+
+	if err := std.attach(command, pipes); err != nil {
+		return nil, err
+	}
+	return std, nil
 }
 
-func (s *StdConsole) Attach(pipes *Pipes) error {
-	s.command.Stdout = pipes.Stdout
-	s.command.Stderr = pipes.Stderr
+func (s *StdConsole) attach(command *Command, pipes *Pipes) error {
+	command.Stdout = pipes.Stdout
+	command.Stderr = pipes.Stderr
 
 	if pipes.Stdin != nil {
-		stdin, err := s.command.StdinPipe()
+		stdin, err := command.StdinPipe()
 		if err != nil {
 			return err
 		}