github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/api/client/attach.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/Sirupsen/logrus" 8 "github.com/docker/docker/api/types" 9 Cli "github.com/docker/docker/cli" 10 flag "github.com/docker/docker/pkg/mflag" 11 "github.com/docker/docker/pkg/signal" 12 ) 13 14 // CmdAttach attaches to a running container. 15 // 16 // Usage: docker attach [OPTIONS] CONTAINER 17 func (cli *DockerCli) CmdAttach(args ...string) error { 18 cmd := Cli.Subcmd("attach", []string{"CONTAINER"}, Cli.DockerCommands["attach"].Description, true) 19 noStdin := cmd.Bool([]string{"-no-stdin"}, false, "Do not attach STDIN") 20 proxy := cmd.Bool([]string{"-sig-proxy"}, true, "Proxy all received signals to the process") 21 22 cmd.Require(flag.Exact, 1) 23 24 cmd.ParseFlags(args, true) 25 26 c, err := cli.client.ContainerInspect(cmd.Arg(0)) 27 if err != nil { 28 return err 29 } 30 31 if !c.State.Running { 32 return fmt.Errorf("You cannot attach to a stopped container, start it first") 33 } 34 35 if c.State.Paused { 36 return fmt.Errorf("You cannot attach to a paused container, unpause it first") 37 } 38 39 if err := cli.CheckTtyInput(!*noStdin, c.Config.Tty); err != nil { 40 return err 41 } 42 43 if c.Config.Tty && cli.isTerminalOut { 44 if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil { 45 logrus.Debugf("Error monitoring TTY size: %s", err) 46 } 47 } 48 49 options := types.ContainerAttachOptions{ 50 ContainerID: cmd.Arg(0), 51 Stream: true, 52 Stdin: !*noStdin && c.Config.OpenStdin, 53 Stdout: true, 54 Stderr: true, 55 } 56 57 var in io.ReadCloser 58 if options.Stdin { 59 in = cli.in 60 } 61 62 if *proxy && !c.Config.Tty { 63 sigc := cli.forwardAllSignals(options.ContainerID) 64 defer signal.StopCatch(sigc) 65 } 66 67 resp, err := cli.client.ContainerAttach(options) 68 if err != nil { 69 return err 70 } 71 defer resp.Close() 72 73 if err := cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp); err != nil { 74 return err 75 } 76 77 _, status, err := getExitCode(cli, options.ContainerID) 78 if err != nil { 79 return err 80 } 81 if status != 0 { 82 return Cli.StatusError{StatusCode: status} 83 } 84 85 return nil 86 }