]> Cypherpunks repositories - gostls13.git/commitdiff
os: do not assume syscall i/o funcs return n=0 on error
authorRuss Cox <rsc@golang.org>
Tue, 28 Oct 2014 19:00:13 +0000 (15:00 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 28 Oct 2014 19:00:13 +0000 (15:00 -0400)
Fixes #9007.

LGTM=iant, r
R=r, iant
CC=golang-codereviews
https://golang.org/cl/160670043

src/os/dir_unix.go
src/os/file.go
src/os/file_plan9.go
src/os/file_posix.go
src/os/file_unix.go
src/os/file_windows.go

index d353e405e54178088608408609ede466248fcfbb..589db85274077b2e09ddd1596be40cd2f9d1ebbc 100644 (file)
@@ -36,7 +36,7 @@ func (f *File) readdirnames(n int) (names []string, err error) {
                if d.bufp >= d.nbuf {
                        d.bufp = 0
                        var errno error
-                       d.nbuf, errno = syscall.ReadDirent(f.fd, d.buf)
+                       d.nbuf, errno = fixCount(syscall.ReadDirent(f.fd, d.buf))
                        if errno != nil {
                                return names, NewSyscallError("readdirent", errno)
                        }
index b4a745801621585eaf6197b678d286da2c839c2c..e12428cbe129cf0615ea8cba2eb1c43256d9020f 100644 (file)
@@ -255,3 +255,12 @@ var lstat = Lstat
 func Rename(oldpath, newpath string) error {
        return rename(oldpath, newpath)
 }
+
+// Many functions in package syscall return a count of -1 instead of 0.
+// Using fixCount(call()) instead of call() corrects the count.
+func fixCount(n int, err error) (int, error) {
+       if n < 0 {
+               n = 0
+       }
+       return n, err
+}
index a804b81973135590061f07cd00db17c7a1a3e12b..22860e20af7e94b4ed99b6c2979b55ffca923922 100644 (file)
@@ -244,14 +244,14 @@ func (f *File) Sync() (err error) {
 // read reads up to len(b) bytes from the File.
 // It returns the number of bytes read and an error, if any.
 func (f *File) read(b []byte) (n int, err error) {
-       return syscall.Read(f.fd, b)
+       return fixCount(syscall.Read(f.fd, b))
 }
 
 // pread reads len(b) bytes from the File starting at byte offset off.
 // It returns the number of bytes read and the error, if any.
 // EOF is signaled by a zero count with err set to nil.
 func (f *File) pread(b []byte, off int64) (n int, err error) {
-       return syscall.Pread(f.fd, b, off)
+       return fixCount(syscall.Pread(f.fd, b, off))
 }
 
 // write writes len(b) bytes to the File.
@@ -259,10 +259,7 @@ func (f *File) pread(b []byte, off int64) (n int, err error) {
 // Since Plan 9 preserves message boundaries, never allow
 // a zero-byte write.
 func (f *File) write(b []byte) (n int, err error) {
-       if len(b) == 0 {
-               return 0, nil
-       }
-       return syscall.Write(f.fd, b)
+       return fixCount(syscall.Write(f.fd, b))
 }
 
 // pwrite writes len(b) bytes to the File starting at byte offset off.
@@ -273,7 +270,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) {
        if len(b) == 0 {
                return 0, nil
        }
-       return syscall.Pwrite(f.fd, b, off)
+       return fixCount(syscall.Pwrite(f.fd, b, off))
 }
 
 // seek sets the offset for the next Read or Write on file to offset, interpreted
index 9cff7e5bcc65b69d2564e9ac0b7f15b72436cbe5..fbb3b5e4d816d856107796a3f18dcabbf8404169 100644 (file)
@@ -18,7 +18,7 @@ func sigpipe() // implemented in package runtime
 func Readlink(name string) (string, error) {
        for len := 128; ; len *= 2 {
                b := make([]byte, len)
-               n, e := syscall.Readlink(name, b)
+               n, e := fixCount(syscall.Readlink(name, b))
                if e != nil {
                        return "", &PathError{"readlink", name, e}
                }
index bba0d9c0f685b3b142132ca1fc55b8472de2bb55..4e413fbe848f8240de02e0400f94de31d94cfd26 100644 (file)
@@ -187,7 +187,7 @@ func (f *File) read(b []byte) (n int, err error) {
        if needsMaxRW && len(b) > maxRW {
                b = b[:maxRW]
        }
-       return syscall.Read(f.fd, b)
+       return fixCount(syscall.Read(f.fd, b))
 }
 
 // pread reads len(b) bytes from the File starting at byte offset off.
@@ -197,7 +197,7 @@ func (f *File) pread(b []byte, off int64) (n int, err error) {
        if needsMaxRW && len(b) > maxRW {
                b = b[:maxRW]
        }
-       return syscall.Pread(f.fd, b, off)
+       return fixCount(syscall.Pread(f.fd, b, off))
 }
 
 // write writes len(b) bytes to the File.
@@ -208,7 +208,7 @@ func (f *File) write(b []byte) (n int, err error) {
                if needsMaxRW && len(bcap) > maxRW {
                        bcap = bcap[:maxRW]
                }
-               m, err := syscall.Write(f.fd, bcap)
+               m, err := fixCount(syscall.Write(f.fd, bcap))
                n += m
 
                // If the syscall wrote some data but not all (short write)
@@ -234,7 +234,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) {
        if needsMaxRW && len(b) > maxRW {
                b = b[:maxRW]
        }
-       return syscall.Pwrite(f.fd, b, off)
+       return fixCount(syscall.Pwrite(f.fd, b, off))
 }
 
 // seek sets the offset for the next Read or Write on file to offset, interpreted
@@ -242,7 +242,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) {
 // relative to the current offset, and 2 means relative to the end.
 // It returns the new offset and an error, if any.
 func (f *File) seek(offset int64, whence int) (ret int64, err error) {
-       return syscall.Seek(f.fd, offset, whence)
+       return fixCount(syscall.Seek(f.fd, offset, whence))
 }
 
 // Truncate changes the size of the named file.
index e78d4abf642e0e47d38591e330a68a88ac0bcc9c..3b5519390ba338dce0e1a3cebbb6905027564ddb 100644 (file)
@@ -295,7 +295,7 @@ func (f *File) read(b []byte) (n int, err error) {
        if f.isConsole {
                return f.readConsole(b)
        }
-       return syscall.Read(f.fd, b)
+       return fixCount(syscall.Read(f.fd, b))
 }
 
 // pread reads len(b) bytes from the File starting at byte offset off.
@@ -376,7 +376,7 @@ func (f *File) write(b []byte) (n int, err error) {
        if f.isConsole {
                return f.writeConsole(b)
        }
-       return syscall.Write(f.fd, b)
+       return fixCount(syscall.Write(f.fd, b))
 }
 
 // pwrite writes len(b) bytes to the File starting at byte offset off.