lib: Fix x/lib for go1.6

There are 2 changes in go1.6 that affect x/lib.

The signal package was changed wrt writing to broken pipes.
Basically we'll get a SIGPIPE when writing to a broken os.Stdout.
The fix is to detect the SIGPIPE-based failure, and handle it
appropriately in IgnoreClosedPipeError mode.

The utf8.FullRune function was also re-implemented to be faster.
As a side-effect, this also fixed some bugs with the original
implementation.  The bug causes differing behavior under go1.5 vs
go1.6, but thankfully only affects a particular test case, which
isn't actually that important.  The fix is to comment-out the
test case, which is updated to work for go1.6.  Once we've
switched over, we'll uncomment the test case.

https://go-review.googlesource.com/#/c/16940/4/src/unicode/utf8/utf8.go@a142

Issue https://v.io/i/1165

Change-Id: Id7095ac112e465ea1eeb7823fb2b693116bab290
diff --git a/gosh/cmd.go b/gosh/cmd.go
index 25ea76a..e7b7e22 100644
--- a/gosh/cmd.go
+++ b/gosh/cmd.go
@@ -298,16 +298,15 @@
 // IgnoreClosedPipeError handles this case. gosh.Pipeline sets this option to
 // true, so that by default the pipeline above will succeed, but will fail on
 // any other error. Note that the exec package always returns an ExitError if
-// the child process exited with a non-zero exit code; the closed pipe error is
-// only returned if the child process exited with a zero exit code, and Write on
-// the io.MultiWriter in the parent process received the closed pipe error.
+// the child process exited with a non-zero exit code, or died due to a signal;
+// io.ErrClosedPipe and os.PathError are only returned if the child process
+// exited with a zero exit code, and Write on the io.MultiWriter in the parent
+// process received the closed pipe error.
 //
-// TODO(toddw): We could adopt the convention that exit code 141 indicates
-// "closed pipe", and use IgnoreClosedPipeError to also ignore that case. We
-// choose 141 because it's 128 + 13, where SIGPIPE is 13, and there is an
-// existing convention for this. By default Go programs ignore SIGPIPE, so we
-// might also want to add code to InitChildMain to exit the program with 141 if
-// it receives SIGPIPE.
+// Starting in go 1.6, by default all go programs will exit with SIGPIPE if they
+// try to write to a broken os.Stdout or os.Stderr. This is the behavior we
+// want; it means that normal go programs will behave as expected wrt
+// IgnoreClosedPipeError, and gosh.Pipeline will work by default.
 
 var sep = strings.Repeat("-", 40)
 
@@ -506,8 +505,18 @@
 		return true
 	}
 	// Closed pipe on os.Pipe; mirrors logic in os/exec/exec_posix.go.
-	if pe, ok := err.(*os.PathError); ok && pe.Op == "write" && pe.Path == "|1" && pe.Err == syscall.EPIPE {
-		return true
+	if pe, ok := err.(*os.PathError); ok {
+		if pe.Op == "write" && pe.Path == "|1" && pe.Err == syscall.EPIPE {
+			return true
+		}
+	}
+	// Process exited due to a SIGPIPE signal.
+	if ee, ok := err.(*exec.ExitError); ok {
+		if ws, ok := ee.ProcessState.Sys().(syscall.WaitStatus); ok {
+			if ws.Signaled() && ws.Signal() == syscall.SIGPIPE {
+				return true
+			}
+		}
 	}
 	return false
 }
diff --git a/textutil/utf8_test.go b/textutil/utf8_test.go
index 8175e62..264334d 100644
--- a/textutil/utf8_test.go
+++ b/textutil/utf8_test.go
@@ -35,7 +35,10 @@
 		{"\uFFFD", []rune{'\uFFFD'}, nil},
 		{"a\uFFFDb", []rune{'a', '\uFFFD', 'b'}, nil},
 		{"\x80", []rune{'\uFFFD'}, nil},
-		{"\xFF", nil, []rune{'\uFFFD'}},
+		// TODO(toddw): Enable the below line when we've switched to go1.6+.  It
+		// fails in go1.5 because of a bugfix that changed this behavior.
+		// https://go-review.googlesource.com/#/c/16940/4/src/unicode/utf8/utf8.go@a142
+		// {"\xFF", []rune{'\uFFFD'}, nil},
 		{"a\x80b", []rune{'a', '\uFFFD', 'b'}, nil},
 		{"a\xFFb", []rune{'a', '\uFFFD', 'b'}, nil},
 		// Multi-byte full runes.