From 75529a202f65e7df5395e0eca7d58aaa7718489c Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Fri, 25 Jan 2013 11:26:18 -0800 Subject: [PATCH] Fixed IO edge cases on docker client. Wait for stdin to close before exiting if it's a pipe, but not if it's a terminal. Correctly send stdin EOF to the server with TCP half-close --- docker/docker.go | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/docker/docker.go b/docker/docker.go index 66311efac1..1c3c5a366b 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -2,6 +2,7 @@ package main import ( "github.com/dotcloud/docker/rcli" + "github.com/dotcloud/docker/future" "io" "log" "os" @@ -174,15 +175,25 @@ func main() { if err != nil { Fatal(err) } - go func() { - if _, err := io.Copy(os.Stdout, conn); err != nil { - Fatal(err) + receive_stdout := future.Go(func() error { + _, err := io.Copy(os.Stdout, conn) + return err + }) + send_stdin := future.Go(func() error { + _, err := io.Copy(conn, os.Stdin) + if err := conn.CloseWrite(); err != nil { + log.Printf("Couldn't send EOF: " + err.Error()) } - Restore(0, oldState) - os.Exit(0) - }() - if _, err := io.Copy(conn, os.Stdin); err != nil { + return err + }) + if err := <-receive_stdout; err != nil { Fatal(err) } - Restore(0, oldState) + if IsTerminal(0) { + Restore(0, oldState) + } else { + if err := <-send_stdin; err != nil { + Fatal(err) + } + } }