summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_filedesc.c59
-rw-r--r--sys/kern/kern_syscall.c1
2 files changed, 60 insertions, 0 deletions
diff --git a/sys/kern/kern_filedesc.c b/sys/kern/kern_filedesc.c
index 63ffa98..6cdc1ee 100644
--- a/sys/kern/kern_filedesc.c
+++ b/sys/kern/kern_filedesc.c
@@ -339,6 +339,54 @@ read(int fd, void *buf, size_t count)
}
/*
+ * Reposition the file offset
+ *
+ * @fd: File descriptor.
+ * @offset: Offset for the reposition
+ * @whence: SEEK_SET, SEEK_CUR, or SEEK_END
+ *
+ * TODO: Implement SEEK_END
+ */
+off_t
+lseek(int fd, off_t offset, int whence)
+{
+ struct filedesc *fd_desc;
+ struct vattr vattr;
+
+ fd_desc = fd_from_fdnum(this_td(), fd);
+
+ if (fd_desc == NULL) {
+ return -EBADF;
+ }
+
+ if (vfs_getattr(fd_desc->vnode, &vattr) != 0) {
+ return -1;
+ }
+
+ switch (whence) {
+ case SEEK_SET:
+ if (offset > vattr.size)
+ return -ESPIPE;
+
+ fd_desc->offset = offset;
+ break;
+ case SEEK_CUR:
+ if ((fd_desc->offset + offset) > vattr.size)
+ return -ESPIPE;
+
+ fd_desc->offset += offset;
+ break;
+ case SEEK_END:
+ /* TODO */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return fd_desc->offset;
+}
+
+/*
* arg0: int fd
* arg1: const void *buf
* arg2: count
@@ -418,3 +466,14 @@ sys_read(struct syscall_args *args)
}
return bytes_read;
}
+
+/*
+ * arg0: fd
+ * arg1: offset:
+ * arg2: whence
+ */
+uint64_t
+sys_lseek(struct syscall_args *args)
+{
+ return lseek(args->arg0, args->arg1, args->arg2);
+}
diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c
index 0f45469..a630195 100644
--- a/sys/kern/kern_syscall.c
+++ b/sys/kern/kern_syscall.c
@@ -46,4 +46,5 @@ uint64_t(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args) = {
sys_open,
sys_close,
sys_read,
+ sys_lseek,
};