Kernel/syscalls: Modify sys_write to accept a file descriptor and write to it

Previously, sys_write only wrote to the tty. Now, it uses the VFS interface, as it should.
This commit is contained in:
apio 2022-10-11 21:06:12 +02:00
parent e764647133
commit 12cf37d0a7
5 changed files with 63 additions and 9 deletions

View File

@ -24,7 +24,7 @@ namespace Syscall
void sys_exit(Context* context, int status);
void sys_yield(Context* context);
void sys_sleep(Context* context, uint64_t ms);
void sys_write(Context* context, const char* addr, size_t size);
void sys_write(Context* context, int fd, size_t size, const char* addr);
void sys_paint(Context* context, uint64_t x, uint64_t y, uint64_t w, uint64_t h, uint64_t col);
void sys_rand(Context* context);
void sys_getversion(Context* context, char* buffer, size_t max);

View File

@ -18,7 +18,7 @@ void Syscall::entry(Context* context)
sys_sleep(context, context->rdi);
break;
case SYS_write: // sys_write
sys_write(context, (const char*)context->rdi, context->rsi);
sys_write(context, (int)context->rdi, context->rsi, (const char*)context->rdx);
break;
case SYS_paint: sys_paint(context, context->rdi, context->rsi, context->rdx, context->r10, context->r8); break;
case SYS_rand: sys_rand(context); break;

View File

@ -8,12 +8,44 @@
#include "thread/Scheduler.h"
#include "thread/Task.h"
#define OPEN_READ 1
#define OPEN_WRITE 2
#define STDIO_FAIL(function, error) kwarnln("%s failed with %s", #function, #error)
void sys_write(Context* context, const char* addr, size_t size)
void sys_write(Context* context, int fd, size_t size, const char* addr)
{
context->rax = size;
TextRenderer::write(addr, size);
if (!addr)
{
STDIO_FAIL(write, EINVAL);
context->rax = -EINVAL; // FIXME: This should probably return EFAULT.
return;
}
if (fd >= TASK_MAX_FDS || fd < 0)
{
kwarnln("file descriptor %d is outside the valid range", fd);
STDIO_FAIL(write, EBADF);
context->rax = -EBADF;
return;
}
Task* current_task = Scheduler::current_task();
if (!current_task->files[fd].is_open())
{
kwarnln("file descriptor %d is not open", fd);
STDIO_FAIL(write, EBADF);
context->rax = -EBADF;
return;
}
if (!current_task->files[fd].can_write())
{
kwarnln("file descriptor %d is not open for writing", fd);
STDIO_FAIL(write, EBADF);
context->rax = -EBADF;
return;
}
ssize_t result = current_task->files[fd].write(size, addr);
context->rax = (size_t)result;
return;
}
void sys_open(Context* context, const char* filename, int flags)
@ -24,12 +56,14 @@ void sys_open(Context* context, const char* filename, int flags)
{
if (!current_task->files[fd].is_open()) break;
}
if (fd == TASK_MAX_FDS)
{
STDIO_FAIL(open, EMFILE);
context->rax = -EMFILE;
return;
}
VFS::Node* node = VFS::resolve_path(filename);
if (!node)
{
@ -37,9 +71,23 @@ void sys_open(Context* context, const char* filename, int flags)
context->rax = -ENOENT;
return;
}
kdbgln("open(): opening %s, allocated file descriptor %d", filename, fd);
current_task->files[fd].open(node,
(bool)flags); // FIXME: Implement more flags. (right now, 1 is can_read, 0 is not)
bool can_read = (flags & OPEN_READ) > 0;
bool can_write = (flags & OPEN_WRITE) > 0;
if (!can_read && !can_write)
{
STDIO_FAIL(open, EINVAL);
context->rax = -EINVAL;
return;
}
kdbgln("open(): opening %s %s, allocated file descriptor %d", filename,
(can_read && can_write) ? "rw"
: can_read ? "r-"
: "-w",
fd);
current_task->files[fd].open(node, can_read, can_write);
context->rax = fd;
return;
}

View File

@ -16,6 +16,7 @@ extern "C"
unsigned int sleep(unsigned int);
ssize_t read(int, void*, size_t);
ssize_t write(int, const void*, size_t);
int close(int);
#ifdef __cplusplus

View File

@ -37,7 +37,6 @@ extern "C"
case SYS_exit:
case SYS_close:
case SYS_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break;
case SYS_write:
case SYS_munmap:
case SYS_open:
case SYS_getversion: {
@ -46,6 +45,7 @@ extern "C"
result = __luna_syscall2(number, arg0, arg1);
break;
}
case SYS_write:
case SYS_read:
case SYS_mmap: {
arg arg0 = va_arg(ap, arg);
@ -80,6 +80,11 @@ extern "C"
return syscall(SYS_read, fd, count, buf); // yes, our read() syscall is in the wrong order.
}
ssize_t write(int fd, const void* buf, size_t count)
{
return syscall(SYS_write, fd, count, buf); // yes, our read() syscall is in the wrong order.
}
int close(int fd)
{
return (int)syscall(SYS_close, fd);