veyron/examples/tunnel: Fix race in IO

When the shell command exits, stdout and stderr are closed, which means
that both stdout2outchan() and stderr2outchan() will report an error.
The problem happens when there is still data to be read from one file
descriptor when the error is detected on the other, which would drop the
unread data.

This change makes sure that all the queues are properly drained when an
error is reported, and adds new tests for common patterns.

Change-Id: Iaa636e768a6c890155cbdc9ed44e3a925cbe676c
diff --git a/tunnel.vdl b/tunnel.vdl
index 88eb2bf..3098e0e 100644
--- a/tunnel.vdl
+++ b/tunnel.vdl
@@ -20,21 +20,23 @@
 }
 
 type ShellOpts struct {
-	UsePty       bool      // Whether to open a pseudo-terminal
-	Environment  []string  // Environment variables to pass to the remote shell.
-	Rows, Cols   uint32    // Window size.
+  UsePty      bool      // Whether to open a pseudo-terminal
+  Environment []string  // Environment variables to pass to the remote shell.
+  Rows, Cols  uint32    // Window size.
 }
 
 type ClientShellPacket struct {
-        // Bytes going to the shell's stdin.
-        Stdin       []byte
-        // A dynamic update of the window size. The default value of 0 means no-change.
-        Rows, Cols  uint32
+  // Bytes going to the shell's stdin.
+  Stdin      []byte
+  // Indicates that stdin should be closed.
+  EOF        bool
+  // A dynamic update of the window size. The default value of 0 means no-change.
+  Rows, Cols uint32
 }
 
 type ServerShellPacket struct {
-        // Bytes coming from the shell's stdout.
-        Stdout      []byte
-        // Bytes coming from the shell's stderr.
-        Stderr      []byte
+  // Bytes coming from the shell's stdout.
+  Stdout []byte
+  // Bytes coming from the shell's stderr.
+  Stderr []byte
 }