lib: v23test: port more tests

Also adds a big TODO to gosh/cmd.go, describing planned changes to be
implemented in a follow-up CL.

MultiPart: 1/2

Change-Id: Iec546278d849022dce1e3aae5159413ac80586d1
diff --git a/gosh/buffered_pipe.go b/gosh/buffered_pipe.go
index 86757f4..0cae34f 100644
--- a/gosh/buffered_pipe.go
+++ b/gosh/buffered_pipe.go
@@ -17,9 +17,9 @@
 	err  error
 }
 
-// NewBufferedPipe returns a new pipe backed by an unbounded in-memory buffer.
-// Writes on the pipe never block; reads on the pipe block until data is
-// available.
+// NewBufferedPipe returns a new thread-safe pipe backed by an unbounded
+// in-memory buffer. Writes on the pipe never block; reads on the pipe block
+// until data is available.
 func NewBufferedPipe() io.ReadWriteCloser {
 	return &bufferedPipe{cond: sync.NewCond(&sync.Mutex{})}
 }
diff --git a/gosh/cmd.go b/gosh/cmd.go
index 2337696..19ccdfb 100644
--- a/gosh/cmd.go
+++ b/gosh/cmd.go
@@ -56,6 +56,23 @@
 	recvVars       map[string]string // protected by condVars.L
 }
 
+// TODO(sadovsky):
+// - Change "Errorf" to "Fatalf" everywhere.
+// - Drop "CombinedOutput", change "Output" to "StdoutStderr", and add "Stdout".
+// - Add Cmd.Clone method that returns a new Cmd with the same configuration.
+// - Add Cmd.StdinPipe method that creates a new bufferedPipe, returns a
+//   WriteCloser, and stores a ReadCloser. Cmd.StdinPipe cannot be called more
+//   than once.
+// - In Cmd.Start, start a goroutine that monitors the started process and
+//   closes the stdinPipe ReadCloser (if it's not already closed) when the
+//   process exits.
+// - Make it so awaitReady and awaitVars return an error if/when our goroutine
+//   detects that the process has exited.
+// - Add unit test for piping from one Cmd's stdout to another's stdin. It
+//   should be possible to wait on just the last Cmd.
+// - Add unit test to demonstrate that Cmd.Wait returns immediately for a
+//   process that blocks on non-nil stdin if Cmd.StdinPipe was never called.
+
 // StdoutPipe returns a Reader backed by a buffered pipe for the command's
 // stdout. Must be called before Start. May be called more than once; each
 // invocation creates a new pipe.
@@ -328,7 +345,7 @@
 	return err
 }
 
-// TODO(sadovsky): Add timeouts for Cmd.{awaitReady,awaitVars,wait}.
+// TODO(sadovsky): Maybe add timeouts for Cmd.{awaitReady,awaitVars,wait}.
 
 func (c *Cmd) awaitReady() error {
 	if !c.calledStart() {