os.File.ReadAt/WriteAt

R=r
DELTA=84  (81 added, 0 deleted, 3 changed)
OCL=34006
CL=34006
diff --git a/src/pkg/os/file.go b/src/pkg/os/file.go
index 958a823..c9c0078 100644
--- a/src/pkg/os/file.go
+++ b/src/pkg/os/file.go
@@ -115,7 +115,7 @@
 // It returns the number of bytes read and an Error, if any.
 // EOF is signaled by a zero count with err set to EOF.
 // TODO(r): Add Pread, Pwrite (maybe ReadAt, WriteAt).
-func (file *File) Read(b []byte) (ret int, err Error) {
+func (file *File) Read(b []byte) (n int, err Error) {
 	if file == nil {
 		return 0, EINVAL
 	}
@@ -132,10 +132,31 @@
 	return n, err
 }
 
+// ReadAt 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 EOF.
+// ReadAt always returns a non-nil Error when n != len(b).
+func (file *File) ReadAt(b []byte, off int64) (n int, err Error) {
+	if file == nil {
+		return 0, EINVAL;
+	}
+	for len(b) > 0 {
+		m, e := syscall.Pread(file.fd, b, off);
+		n += m;
+		if e != 0 {
+			err = &PathError{"read", file.name, Errno(e)};
+			break;
+		}
+		b = b[m:len(b)];
+		off += int64(m);
+	}
+	return;
+}
+
 // Write writes len(b) bytes to the File.
 // It returns the number of bytes written and an Error, if any.
-// If the byte count differs from len(b), it usually implies an error occurred.
-func (file *File) Write(b []byte) (ret int, err Error) {
+// Write returns a non-nil Error when n != len(b).
+func (file *File) Write(b []byte) (n int, err Error) {
 	if file == nil {
 		return 0, EINVAL
 	}
@@ -157,6 +178,26 @@
 	return n, err
 }
 
+// WriteAt writes len(b) bytes to the File starting at byte offset off.
+// It returns the number of bytes written and an Error, if any.
+// WriteAt returns a non-nil Error when n != len(b).
+func (file *File) WriteAt(b []byte, off int64) (n int, err Error) {
+	if file == nil {
+		return 0, EINVAL;
+	}
+	for len(b) > 0 {
+		m, e := syscall.Pwrite(file.fd, b, off);
+		n += m;
+		if e != 0 {
+			err = &PathError{"write", file.name, Errno(e)};
+			break;
+		}
+		b = b[m:len(b)];
+		off += int64(m);
+	}
+	return;
+}
+
 // Seek sets the offset for the next Read or Write on file to offset, interpreted
 // according to whence: 0 means relative to the origin of the file, 1 means
 // relative to the current offset, and 2 means relative to the end.