TBR: playground: Change gosh.Cmd.StdinPipe to have unlimited-size.

It's more convenient for users if StdinPipe has an unlimited
size; otherwise they need to worry about deadlock.  You might
think we could just use our buffered pipe and be done with it,
but it's pretty tricky.  In particular os/exec will create its
own os.Pipe and a copier goroutine if we don't pass in a *os.File
for exec.Cmd.Stdin, and exec.Cmd.Wait will wait for that
goroutine to finish.

Note that we can't call exec.Cmd.StdinPipe; that ensures that
Close is only called once, but doesn't ensure Write and Close
calls are synchronous.  This makes a race possible: the user may
call Write on the StdinPipe, concurrently with the exit-waiter
goroutine calling Close on the StdinPipe when the process exits.
This race has shown up on jenkins, and is also easily
reproduced (under heavy machine load) with the new test.

To make this all work, we create our own os.Pipe that we set for
exec.Cmd.Stdin, and also create a buffered pipe, along with our
own copier goroutine.

MultiPart: 3/3

Change-Id: Idfbaee7611ef51b8bf786eb2cfbb074c6a0b53f3
diff --git a/go/src/v.io/x/playground/builder/builder_v23_test.go b/go/src/v.io/x/playground/builder/builder_v23_test.go
index b4ddf87..17325b6 100644
--- a/go/src/v.io/x/playground/builder/builder_v23_test.go
+++ b/go/src/v.io/x/playground/builder/builder_v23_test.go
@@ -5,6 +5,7 @@
 package main_test
 
 import (
+	"bytes"
 	"os"
 	"path/filepath"
 	"strings"
@@ -77,7 +78,7 @@
 	}
 	builder := sh.Cmd(builderPath, args...)
 	builder.Vars["PATH"] = PATH
-	builder.Stdin = string(bundle)
+	builder.SetStdinReader(bytes.NewReader(bundle))
 	builder.PropagateOutput = true
 	builder.Start()
 	return builder