diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 1d46323c..c80c4097 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -3,12 +3,14 @@ extern syscall_print extern syscall_mmap extern syscall_openat extern syscall_read +extern syscall_seek syscalltab: dq syscall_print dq syscall_mmap dq syscall_openat dq syscall_read -syscallcount equ 4 +dq syscall_seek +syscallcount equ 5 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/sys/syscalls/seek.c b/kernel-src/sys/syscalls/seek.c new file mode 100644 index 00000000..ec5d2cd5 --- /dev/null +++ b/kernel-src/sys/syscalls/seek.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +syscallret_t syscall_seek(context_t *context, int fd, off_t offset, int whence) { + syscallret_t ret = { + .ret = -1 + }; + + if (whence > 2) { + ret.errno = EINVAL; + return ret; + } + + file_t *file = fd_get(fd); + if (file == NULL) { + ret.errno = EBADF; + return ret; + } + + if (file->vnode->type == V_TYPE_SOCKET || file->vnode->type == V_TYPE_FIFO) { + ret.errno = ESPIPE; + goto cleanup; + } + + // TODO device check seek + + switch (whence) { + case SEEK_SET: + file->offset = offset; + break; + case SEEK_CUR: { + uintmax_t newoffset = file->offset + offset; + if (offset > 0 && newoffset < file->offset) { + ret.errno = EOVERFLOW; + goto cleanup; + } + if (offset < 0 && newoffset > file->offset) { + ret.errno = EINVAL; + goto cleanup; + } + file->offset = newoffset; + break; + } + case SEEK_END: { + vattr_t attr; + VOP_LOCK(file->vnode); + ret.errno = VOP_GETATTR(file->vnode, &attr, &_cpu()->thread->proc->cred); + VOP_UNLOCK(file->vnode); + if (ret.errno) + goto cleanup; + file->offset = attr.size; + break; + } + } + + ret.ret = file->offset; + ret.errno = 0; + + cleanup: + fd_release(file); + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index 23ebe55d..4235a9a0 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -113,10 +113,10 @@ index 0000000..e5b087a + diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp new file mode 100644 -index 0000000..80a5884 +index 0000000..b92f59e --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,148 @@ +@@ -0,0 +1,151 @@ +#include +#include +#include @@ -237,7 +237,10 @@ index 0000000..80a5884 + return ENOSYS; + } + int sys_seek(int fd, off_t offset, int whence, off_t *new_offset) { -+ return ENOSYS; ++ long ret = 0; ++ long error = syscall(SYSCALL_SEEK, &ret, fd, offset, whence); ++ *new_offset = ret; ++ return error; + } + + int sys_close(int fd) { @@ -284,10 +287,10 @@ index 0000000..990eca0 +#endif diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h new file mode 100644 -index 0000000..17c0045 +index 0000000..1947f70 --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,27 @@ +@@ -0,0 +1,28 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -295,6 +298,7 @@ index 0000000..17c0045 +#define SYSCALL_MMAP 1 +#define SYSCALL_OPENAT 2 +#define SYSCALL_READ 3 ++#define SYSCALL_SEEK 4 + +#include +#include