diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index f6d5f7c0..ed1793c1 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -25,6 +25,7 @@ extern syscall_pipe2 extern syscall_isatty extern syscall_faccessat extern syscall_unlinkat +extern syscall_ioctl syscalltab: dq syscall_print dq syscall_mmap @@ -52,7 +53,8 @@ dq syscall_pipe2 dq syscall_isatty dq syscall_faccessat dq syscall_unlinkat -syscallcount equ 26 +dq syscall_ioctl +syscallcount equ 27 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/fs/devfs.c b/kernel-src/fs/devfs.c index 82bccb5a..cb58a032 100644 --- a/kernel-src/fs/devfs.c +++ b/kernel-src/fs/devfs.c @@ -191,6 +191,14 @@ int devfs_isatty(vnode_t *node) { return devnode->devops->isatty ? devnode->devops->isatty(devnode->attr.rdevminor) : ENOTTY; } +int devfs_ioctl(vnode_t *node, unsigned long request, void *arg, int *ret) { + devnode_t *devnode = (devnode_t *)node; + if (devnode->master) + devnode = devnode->master; + + return devnode->devops->ioctl ? devnode->devops->ioctl(devnode->attr.rdevminor, request, arg, ret) : ENOTTY; +} + int devfs_inactive(vnode_t *node) { VOP_LOCK(node); devnode_t *devnode = (devnode_t *)node; @@ -313,7 +321,8 @@ static vops_t vnops = { .mmap = devfs_mmap, .munmap = devfs_munmap, .getdents = devfs_getdents, - .isatty = devfs_isatty + .isatty = devfs_isatty, + .ioctl = devfs_ioctl }; static void ctor(scache_t *cache, void *obj) { diff --git a/kernel-src/include/kernel/devfs.h b/kernel-src/include/kernel/devfs.h index ede5e7a7..5d747eab 100644 --- a/kernel-src/include/kernel/devfs.h +++ b/kernel-src/include/kernel/devfs.h @@ -17,6 +17,7 @@ typedef struct { int (*mmap)(int minor, void *addr, uintmax_t offset, int flags); int (*munmap)(int minor, void *addr, uintmax_t offset, int flags); int (*isatty)(int minor); + int (*ioctl)(int minor, unsigned long request, void *arg, int *result); } devops_t; typedef struct devnode_t { diff --git a/kernel-src/include/kernel/vfs.h b/kernel-src/include/kernel/vfs.h index 0b7de81e..4f713f83 100644 --- a/kernel-src/include/kernel/vfs.h +++ b/kernel-src/include/kernel/vfs.h @@ -92,6 +92,7 @@ typedef struct vops_t { int (*munmap)(vnode_t *node, void *addr, uintmax_t offset, int flags, cred_t *cred); int (*getdents)(vnode_t *node, dent_t *buffer, size_t count, uintmax_t offset, size_t *readcount); int (*isatty)(vnode_t *node); + int (*ioctl)(vnode_t *node, unsigned long request, void *arg, int *result); } vops_t; #define VFS_MOUNT(vfs, mp, b, d) (vfs)->ops->mount(vfs, mp, b, d) @@ -120,6 +121,7 @@ typedef struct vops_t { #define VOP_GETDENTS(v, b, c, o, rc) (v)->ops->getdents(v, b, c, o, rc) #define VOP_POLL(v, p) (v)->ops->poll(v, p) #define VOP_ISATTY(v) ((v)->ops->isatty ? (v)->ops->isatty(v) : ENOTTY) +#define VOP_IOCTL(v, r, a, rp) ((v)->ops->ioctl ? (v)->ops->ioctl(v, r, a, rp) : ENOTTY) #define VOP_HOLD(v) __atomic_add_fetch(&(v)->refcount, 1, __ATOMIC_SEQ_CST) #define VOP_RELEASE(v) {\ if (__atomic_sub_fetch(&(v)->refcount, 1, __ATOMIC_SEQ_CST) == 0) {\ diff --git a/kernel-src/sys/syscalls/ioctl.c b/kernel-src/sys/syscalls/ioctl.c new file mode 100644 index 00000000..8563876a --- /dev/null +++ b/kernel-src/sys/syscalls/ioctl.c @@ -0,0 +1,23 @@ +#include +#include +#include + +syscallret_t syscall_ioctl(context_t *, int fd, unsigned long request, void *arg) { + syscallret_t ret = { + .ret = -1 + }; + + file_t *file = fd_get(fd); + if (file == NULL) { + ret.errno = EBADF; + return ret; + } + + int r = 0; + ret.errno = VOP_IOCTL(file->vnode, request, arg, &r); + ret.ret = ret.errno ? -1 : r; + + fd_release(file); + + return ret; +} diff --git a/kernel-src/sys/syscalls/pipe2.c b/kernel-src/sys/syscalls/pipe2.c index ac3a0206..99cf2370 100644 --- a/kernel-src/sys/syscalls/pipe2.c +++ b/kernel-src/sys/syscalls/pipe2.c @@ -46,7 +46,6 @@ syscallret_t syscall_pipe2(context_t *, int flags) { ret.errno = 0; ret.ret = (uint64_t)readfd | ((uint64_t)writefd << 32); - printf("pipe2: readfd %d writefd %d wrefcount %d\n", readfd, writefd, writefile->refcount); return ret; diff --git a/kernel-src/sys/syscalls/seek.c b/kernel-src/sys/syscalls/seek.c index bfcf15e5..0cf6b737 100644 --- a/kernel-src/sys/syscalls/seek.c +++ b/kernel-src/sys/syscalls/seek.c @@ -58,7 +58,6 @@ syscallret_t syscall_seek(context_t *context, int fd, off_t offset, int whence) } } - printf("ret: new %lu old %lu whence %d\n", newoffset, file->offset, whence); file->offset = newoffset; ret.ret = newoffset; ret.errno = 0; diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index c72c9c5c..c51da5b8 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -133,10 +133,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..f72940e +index 0000000..8c06e96 --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,260 @@ +@@ -0,0 +1,267 @@ +#include +#include +#include @@ -192,6 +192,13 @@ index 0000000..f72940e + return 0; + } + ++ int sys_ioctl(int fd, unsigned long request, void *arg, int *result) { ++ long ret; ++ long err = syscall(SYSCALL_IOCTL, &ret, fd, request, (uint64_t)arg); ++ *result = ret; ++ return err; ++ } ++ + int sys_unlinkat(int fd, const char *path, int flags) { + long ret; + return syscall(SYSCALL_UNLINKAT, &ret, fd, (uint64_t)path, flags); @@ -416,10 +423,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..89e809e +index 0000000..294c8ab --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,49 @@ +@@ -0,0 +1,50 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -449,6 +456,7 @@ index 0000000..89e809e +#define SYSCALL_ISATTY 23 +#define SYSCALL_FACCESSAT 24 +#define SYSCALL_UNLINKAT 25 ++#define SYSCALL_IOCTL 26 + +#include +#include