diff --git a/fs/vfs/main.c b/fs/vfs/main.c
index 6ce5c402ff95e68f47fa30710f90066353f39994..95bc04b82ab94ff2c671f0d4434af9287c5da944 100755
--- a/fs/vfs/main.c
+++ b/fs/vfs/main.c
@@ -174,7 +174,7 @@ typedef uint64_t off64_t;
 off_t lseek64(int fd, off64_t offset, int whence)
     __attribute__((alias("lseek")));
 
-ssize_t read(int fd, void *buf, size_t count)
+ssize_t pread(int fd, void *buf, size_t count, off_t offset)
 {
 	struct task *t = main_task;
 	struct iovec iov = {
@@ -189,7 +189,7 @@ ssize_t read(int fd, void *buf, size_t count)
 	if ((fp = task_getfp(t, fd)) == NULL)
 		goto out_errno;
 
-	error = sys_read(fp, &iov, 1, &bytes);
+	error = sys_read(fp, &iov, 1, offset, &bytes);
 	if (error)
 		goto out_errno;
 
@@ -199,7 +199,12 @@ out_errno:
 	return -1;
 }
 
-ssize_t write(int fd, const void *buf, size_t count)
+ssize_t read(int fd, void *buf, size_t count)
+{
+	return pread(fd, buf, count, -1);
+}
+
+ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset)
 {
 	struct task *t = main_task;
 	struct iovec iov = {
@@ -214,7 +219,7 @@ ssize_t write(int fd, const void *buf, size_t count)
 	if ((fp = task_getfp(t, fd)) == NULL)
 		goto out_errno;
 
-	error = sys_write(fp, &iov, 1, &bytes);
+	error = sys_write(fp, &iov, 1, offset, &bytes);
 	if (error)
 		goto out_errno;
 	return bytes;
@@ -223,7 +228,12 @@ out_errno:
 	return -1;
 }
 
-ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
+ssize_t write(int fd, const void *buf, size_t count)
+{
+	return pwrite(fd, buf, count, -1);
+}
+
+ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 	struct task *t = main_task;
 	file_t fp;
@@ -234,7 +244,7 @@ ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
 	if ((fp = task_getfp(t, fd)) == NULL)
 		goto out_errno;
 
-	error = sys_read(fp, (struct iovec *)iov, iovcnt, &bytes);
+	error = sys_read(fp, (struct iovec *)iov, iovcnt, offset, &bytes);
 	if (error)
 		goto out_errno;
 
@@ -244,7 +254,12 @@ out_errno:
 	return -1;
 }
 
-ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
+ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
+{
+	return preadv(fd, iov, iovcnt, -1);
+}
+
+ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
 	struct task *t = main_task;
 	file_t fp;
@@ -255,7 +270,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
 	if ((fp = task_getfp(t, fd)) == NULL)
 		goto out_errno;
 
-	error = sys_write(fp, (struct iovec *)iov, iovcnt, &bytes);
+	error = sys_write(fp, (struct iovec *)iov, iovcnt, offset, &bytes);
 	if (error)
 		goto out_errno;
 	return bytes;
@@ -264,6 +279,11 @@ out_errno:
 	return -1;
 }
 
+ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
+{
+	return pwritev(fd, iov, iovcnt, -1);
+}
+
 #if 0
 static int
 fs_ioctl(struct task *t, struct ioctl_msg *msg)
diff --git a/fs/vfs/vfs.h b/fs/vfs/vfs.h
index e22a0bf14f85f746a852c921df1658e499c39f79..35d399d926654829a0d3304794e000be64f0c09a 100755
--- a/fs/vfs/vfs.h
+++ b/fs/vfs/vfs.h
@@ -97,8 +97,10 @@ extern const struct vfssw vfssw[];
 __BEGIN_DECLS
 int	 sys_open(char *path, int flags, mode_t mode, file_t *pfp);
 int	 sys_close(file_t fp);
-int	 sys_read(file_t fp, struct iovec *iov, size_t niov, size_t *count);
-int	 sys_write(file_t fp, struct iovec *iov, size_t niov, size_t *count);
+int	 sys_read(file_t fp, struct iovec *iov, size_t niov,
+		off_t offset, size_t *count);
+int	 sys_write(file_t fp, struct iovec *iov, size_t niov,
+		off_t offset, size_t *count);
 int	 sys_lseek(file_t fp, off_t off, int type, off_t * cur_off);
 int	 sys_ioctl(file_t fp, u_long request, void *buf);
 int	 sys_fstat(file_t fp, struct stat *st);
diff --git a/fs/vfs/vfs_syscalls.c b/fs/vfs/vfs_syscalls.c
index 27bcd37cbba1ef0d9f4a053f90bc042593758d27..d9c7cdef521db04443aef8d39cfe1c6301283fd9 100755
--- a/fs/vfs/vfs_syscalls.c
+++ b/fs/vfs/vfs_syscalls.c
@@ -171,7 +171,8 @@ sys_close(file_t fp)
 }
 
 int
-sys_read(file_t fp, struct iovec *iov, size_t niov, size_t *count)
+sys_read(file_t fp, struct iovec *iov, size_t niov,
+		off_t offset, size_t *count)
 {
 	struct vnode *vp = fp->f_vnode;
 	struct uio *uio = NULL;
@@ -196,18 +197,23 @@ sys_read(file_t fp, struct iovec *iov, size_t niov, size_t *count)
 
 	vn_lock(vp);
 	uio->uio_rw = UIO_READ;
-	uio->uio_offset = fp->f_offset;
+	if (offset == -1)
+		uio->uio_offset = fp->f_offset;
+	else
+		uio->uio_offset = offset;
 	error = VOP_READ(vp, uio, 0);
 	if (!error) {
 		*count = bytes - uio->uio_resid;
-		fp->f_offset += *count;
+		if (offset == -1)
+			fp->f_offset += *count;
 	}
 	vn_unlock(vp);
 	return error;
 }
 
 int
-sys_write(file_t fp, struct iovec *iov, size_t niov, size_t *count)
+sys_write(file_t fp, struct iovec *iov, size_t niov,
+		off_t offset, size_t *count)
 {
 	struct vnode *vp = fp->f_vnode;
 	struct uio *uio = NULL;
@@ -235,11 +241,15 @@ sys_write(file_t fp, struct iovec *iov, size_t niov, size_t *count)
 
 	vn_lock(vp);
 	uio->uio_rw = UIO_WRITE;
-	uio->uio_offset = fp->f_offset;
+	if (offset == -1)
+		uio->uio_offset = fp->f_offset;
+	else
+		uio->uio_offset = offset;
 	error = VOP_WRITE(vp, uio, ioflags);
 	if (!error) {
 		*count = bytes - uio->uio_resid;
-		fp->f_offset += *count;
+		if (offset == -1)
+			fp->f_offset += *count;
 	}
 	vn_unlock(vp);
 	return error;
diff --git a/runtime.cc b/runtime.cc
index 28d22c9779fc1d1a01ce3ceef0f88c5017384b84..a4b37cf00c782ed4a2e8ab79dd9aba2cbd6d07a1 100644
--- a/runtime.cc
+++ b/runtime.cc
@@ -207,16 +207,6 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout)
     UNIMPLEMENTED("poll");
 }
 
-ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
-{
-    UNIMPLEMENTED("preadv");
-}
-
-ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
-{
-    UNIMPLEMENTED("pwritev");
-}
-
 int fileno(FILE *fp)
 {
     UNIMPLEMENTED("fileno");