os: do not assume syscall.Write will write everything

Fixes #3323.

R=golang-dev, remyoudompheng, gri
CC=golang-dev
https://golang.org/cl/5837047
diff --git a/src/pkg/os/file_unix.go b/src/pkg/os/file_unix.go
index 6aa0280..6271c31 100644
--- a/src/pkg/os/file_unix.go
+++ b/src/pkg/os/file_unix.go
@@ -173,7 +173,21 @@
 // write writes len(b) bytes to the File.
 // It returns the number of bytes written and an error, if any.
 func (f *File) write(b []byte) (n int, err error) {
-	return syscall.Write(f.fd, b)
+	for {
+		m, err := syscall.Write(f.fd, b)
+		n += m
+
+		// If the syscall wrote some data but not all (short write)
+		// or it returned EINTR, then assume it stopped early for
+		// reasons that are uninteresting to the caller, and try again.
+		if 0 < m && m < len(b) || err == syscall.EINTR {
+			b = b[m:]
+			continue
+		}
+
+		return n, err
+	}
+	panic("not reached")
 }
 
 // pwrite writes len(b) bytes to the File starting at byte offset off.