aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/include/sys/filedesc.h7
-rw-r--r--sys/include/sys/syscall.h1
-rw-r--r--sys/kern/kern_filedesc.c59
-rw-r--r--sys/kern/kern_syscall.c1
4 files changed, 67 insertions, 1 deletions
diff --git a/sys/include/sys/filedesc.h b/sys/include/sys/filedesc.h
index 70b297d..83c32ee 100644
--- a/sys/include/sys/filedesc.h
+++ b/sys/include/sys/filedesc.h
@@ -39,6 +39,10 @@
#define O_WRONLY 0x00001
#define O_RDWR 0x00002
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
struct proc;
struct filedesc {
@@ -56,11 +60,12 @@ void fd_close_fdnum(struct proc *td, int fdno);
ssize_t write(int fd, const void *buf, size_t count);
int open(const char *pathname, int oflag);
int read(int fd, void *buf, size_t count);
+off_t lseek(int fd, off_t offset, int whence);
uint64_t sys_write(struct syscall_args *args);
uint64_t sys_open(struct syscall_args *args);
uint64_t sys_close(struct syscall_args *args);
uint64_t sys_read(struct syscall_args *args);
+uint64_t sys_lseek(struct syscall_args *args);
#endif
-
#endif
diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h
index ae2438f..8ebc2da 100644
--- a/sys/include/sys/syscall.h
+++ b/sys/include/sys/syscall.h
@@ -42,6 +42,7 @@ enum {
SYS_open,
SYS_close,
SYS_read,
+ SYS_lseek,
__MAX_SYSCALLS
};
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,
};