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.