@@ -161,15 +161,15 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
161161 waitDisplayID chan struct {}
162162 errCh chan error
163163 )
164- if ! config .AttachStdout && ! config .AttachStderr {
164+ attach := config .AttachStdin || config .AttachStdout || config .AttachStderr
165+ if ! attach {
165166 // Make this asynchronous to allow the client to write to stdin before having to read the ID
166167 waitDisplayID = make (chan struct {})
167168 go func () {
168169 defer close (waitDisplayID )
169170 _ , _ = fmt .Fprintln (stdout , containerID )
170171 }()
171172 }
172- attach := config .AttachStdin || config .AttachStdout || config .AttachStderr
173173 if attach {
174174 detachKeys := dockerCli .ConfigFile ().DetachKeys
175175 if runOpts .detachKeys != "" {
@@ -215,14 +215,22 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
215215 return toStatusError (err )
216216 }
217217
218- if (config .AttachStdin || config .AttachStdout || config .AttachStderr ) && config .Tty && dockerCli .Out ().IsTerminal () {
218+ // Detached mode: wait for the id to be displayed and return.
219+ if ! attach {
220+ // Detached mode
221+ <- waitDisplayID
222+ return nil
223+ }
224+
225+ if config .Tty && dockerCli .Out ().IsTerminal () {
219226 if err := MonitorTtySize (ctx , dockerCli , containerID , false ); err != nil {
220227 _ , _ = fmt .Fprintln (stderr , "Error monitoring TTY size:" , err )
221228 }
222229 }
223230
224- if errCh != nil {
225- if err := <- errCh ; err != nil {
231+ select {
232+ case err := <- errCh :
233+ if err != nil {
226234 if _ , ok := err .(term.EscapeError ); ok {
227235 // The user entered the detach escape sequence.
228236 return nil
@@ -231,19 +239,20 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
231239 logrus .Debugf ("Error hijack: %s" , err )
232240 return err
233241 }
242+ status := <- statusChan
243+ if status != 0 {
244+ return cli.StatusError {StatusCode : status }
245+ }
246+ case status := <- statusChan :
247+ // notify hijackedIOStreamer that we're exiting and wait
248+ // so that the terminal can be restored.
249+ cancelFun ()
250+ <- errCh
251+ if status != 0 {
252+ return cli.StatusError {StatusCode : status }
253+ }
234254 }
235255
236- // Detached mode: wait for the id to be displayed and return.
237- if ! config .AttachStdout && ! config .AttachStderr {
238- // Detached mode
239- <- waitDisplayID
240- return nil
241- }
242-
243- status := <- statusChan
244- if status != 0 {
245- return cli.StatusError {StatusCode : status }
246- }
247256 return nil
248257}
249258
0 commit comments