func StartExec(client *docker.Client, exec *docker.Exec) (err error) { var ( terminalFd uintptr oldState *term.State out io.Writer = os.Stdout ) if file, ok := out.(*os.File); ok { terminalFd = file.Fd() } else { return errors.New("Not a terminal!") } // Set up the pseudo terminal oldState, err = term.SetRawTerminal(terminalFd) if err != nil { return } // Clean up after the exec command has exited defer term.RestoreTerminal(terminalFd, oldState) // Start it errorChan := make(chan error) go startExec(client, exec, errorChan) // Make sure terminal resizes are passed on to the exec Tty monitorExecTty(client, exec.ID, terminalFd) return <-errorChan }
func Start(client *docker.Client, container *docker.Container, hostConfig *docker.HostConfig) (err error) { var ( terminalFd uintptr oldState *term.State out io.Writer = os.Stdout ) if file, ok := out.(*os.File); ok { terminalFd = file.Fd() } else { return errors.New("Not a terminal!") } // Set up the pseudo terminal oldState, err = term.SetRawTerminal(terminalFd) if err != nil { return } // Clean up after the container has exited defer term.RestoreTerminal(terminalFd, oldState) // Attach to the container on a separate thread attachChan := make(chan error) go attachToContainer(client, container.ID, attachChan) // Start it err = client.StartContainer(container.ID, hostConfig) if err != nil { return } // Make sure terminal resizes are passed on to the container monitorTty(client, container.ID, terminalFd) return <-attachChan }