From c2a237f019d8b6eca4ee400a3c73a9ea937eee98 Mon Sep 17 00:00:00 2001 From: Solomon Hykes <solomon@docker.com> Date: Fri, 9 May 2014 15:39:55 -0700 Subject: [PATCH] Fix stdin handling in engine.Sender and engine.Receiver This introduces a superficial change to the Beam API: * `beam.SendPipe` is renamed to the more accurate `beam.SendRPipe` * `beam.SendWPipe` is introduced as a mirror to `SendRPipe` There is no other change in the beam API. Docker-DCO-1.1-Signed-off-by: Solomon Hykes <solomon@docker.com> (github: shykes) --- beam/beam.go | 41 ++++++++++++++++++++++++++++---- beam/examples/beamsh/beamsh.go | 4 ++-- beam/examples/beamsh/builtins.go | 2 +- beam/router.go | 2 +- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/beam/beam.go b/beam/beam.go index b1e4667..88d3ea7 100644 --- a/beam/beam.go +++ b/beam/beam.go @@ -29,17 +29,48 @@ type ReceiveSender interface { Sender } -func SendPipe(dst Sender, data []byte) (*os.File, error) { +const ( + R int = 1 << (32 - 1 - iota) + W +) + +func sendPipe(dst Sender, data []byte, mode int) (*os.File, error) { r, w, err := os.Pipe() if err != nil { return nil, err } - if err := dst.Send(data, r); err != nil { - r.Close() - w.Close() + var ( + remote *os.File + local *os.File + ) + if mode == R { + remote = r + local = w + } else if mode == W { + remote = w + local = r + } + if err := dst.Send(data, remote); err != nil { + local.Close() + remote.Close() return nil, err } - return w, nil + return local, nil + +} + +// SendRPipe create a pipe and sends its *read* end attached in a beam message +// to `dst`, with `data` as the message payload. +// It returns the *write* end of the pipe, or an error. +func SendRPipe(dst Sender, data []byte) (*os.File, error) { + return sendPipe(dst, data, R) +} + +// SendWPipe create a pipe and sends its *read* end attached in a beam message +// to `dst`, with `data` as the message payload. +// It returns the *write* end of the pipe, or an error. +func SendWPipe(dst Sender, data []byte) (*os.File, error) { + return sendPipe(dst, data, W) } func SendConn(dst Sender, data []byte) (conn *UnixConn, err error) { diff --git a/beam/examples/beamsh/beamsh.go b/beam/examples/beamsh/beamsh.go index 3f258de..808f038 100644 --- a/beam/examples/beamsh/beamsh.go +++ b/beam/examples/beamsh/beamsh.go @@ -257,12 +257,12 @@ func Handlers(sink beam.Sender) (*beam.UnixConn, error) { if handler == nil { return } - stdout, err := beam.SendPipe(conn, data.Empty().Set("cmd", "log", "stdout").Set("fromcmd", cmd...).Bytes()) + stdout, err := beam.SendRPipe(conn, data.Empty().Set("cmd", "log", "stdout").Set("fromcmd", cmd...).Bytes()) if err != nil { return } defer stdout.Close() - stderr, err := beam.SendPipe(conn, data.Empty().Set("cmd", "log", "stderr").Set("fromcmd", cmd...).Bytes()) + stderr, err := beam.SendRPipe(conn, data.Empty().Set("cmd", "log", "stderr").Set("fromcmd", cmd...).Bytes()) if err != nil { return } diff --git a/beam/examples/beamsh/builtins.go b/beam/examples/beamsh/builtins.go index cc94d2b..3242237 100644 --- a/beam/examples/beamsh/builtins.go +++ b/beam/examples/beamsh/builtins.go @@ -272,7 +272,7 @@ func CmdPrint(args []string, stdout, stderr io.Writer, in beam.Receiver, out bea } // Skip commands if a != nil && data.Message(payload).Get("cmd") == nil { - dup, err := beam.SendPipe(out, payload) + dup, err := beam.SendRPipe(out, payload) if err != nil { a.Close() return diff --git a/beam/router.go b/beam/router.go index fc41a89..15910e9 100644 --- a/beam/router.go +++ b/beam/router.go @@ -78,7 +78,7 @@ func (route *Route) Tee(dst Sender) *Route { return inner(payload, attachment) } // Setup the tee - w, err := SendPipe(dst, payload) + w, err := SendRPipe(dst, payload) if err != nil { return err }