syscalls needed for doom (tell/eof/draw_fb) + minor fixes, compiler shut up etc
This commit is contained in:
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* @author xamidev <xamidev@riseup.net>
|
||||
* @brief System call handling
|
||||
* @license GPL-3.0-only
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "sched/scheduler.h"
|
||||
#include <arch/x86.h>
|
||||
#include <kernel.h>
|
||||
#include <stddef.h>
|
||||
#include <io/term/term.h>
|
||||
#include <sched/process.h>
|
||||
#include <io/kbd/ps2.h>
|
||||
#include <fs/initfs.h>
|
||||
#include <string/string.h>
|
||||
|
||||
extern struct process* current_process;
|
||||
|
||||
// Return fd on success, -errno on error
|
||||
int sys_open(const char* filename, int flags)
|
||||
{
|
||||
if (tar_exists(filename) < 0) {
|
||||
return -ENOENT; // file doesn't exist..
|
||||
}
|
||||
// file exists here!
|
||||
if (current_process->next_free_fd >= FDT_MAX) {
|
||||
return -EMFILE;
|
||||
}
|
||||
int fd = current_process->next_free_fd++;
|
||||
current_process->fdt[fd].fd = fd;
|
||||
current_process->fdt[fd].open = true;
|
||||
current_process->fdt[fd].cursor = 0;
|
||||
strncpy(current_process->fdt[fd].filename, filename, PROCESS_NAME_MAX - 1);
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Return 0 on success, -EBADFD if invalid FD
|
||||
int sys_close(int fd)
|
||||
{
|
||||
if (fd < 0 || fd >= FDT_MAX) {
|
||||
return -EBADFD;
|
||||
}
|
||||
|
||||
if (!current_process->fdt[fd].open) {
|
||||
return -EBADFD; // FD not opened in the first place
|
||||
}
|
||||
|
||||
current_process->fdt[fd].open = false;
|
||||
current_process->fdt[fd].filename[0] = '\0';
|
||||
current_process->fdt[fd].cursor = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Should return the number of bytes read
|
||||
int sys_read(unsigned int fd, char* buf, size_t count)
|
||||
{
|
||||
size_t i;
|
||||
switch (fd) {
|
||||
case 0: //read from stdin (keyboard)
|
||||
for (i=0; i<count; i++) {
|
||||
buf[i] = keyboard_getchar();
|
||||
}
|
||||
return i;
|
||||
case 1: // from stdout
|
||||
case 2: // from stderr
|
||||
return -EBADFD;
|
||||
default: // from an open file?
|
||||
if (current_process->fdt[fd].open == false) {
|
||||
return -EBADFD; // File descriptor wasn't open
|
||||
}
|
||||
// Here fd refers to a valid opened file..
|
||||
int sz = tar_read(current_process->fdt[fd].filename, buf, count,
|
||||
current_process->fdt[fd].cursor);
|
||||
if (sz == 0) {
|
||||
return -ENOENT;
|
||||
} else {
|
||||
current_process->fdt[fd].cursor += sz;
|
||||
return sz;
|
||||
}
|
||||
}
|
||||
|
||||
return -EBADFD;
|
||||
}
|
||||
|
||||
// TODO: Should have a return value: number of bytes written on success, -1 on error (errno set)
|
||||
int sys_write(unsigned int fd, const char* buf, size_t count)
|
||||
{
|
||||
switch (fd) {
|
||||
case 1: //stdout
|
||||
case 2: //stderr
|
||||
for (size_t i=0; i<count; i++) {
|
||||
internal_putc(buf[i], NULL);
|
||||
}
|
||||
return count;
|
||||
default:
|
||||
return -EBADFD;
|
||||
}
|
||||
}
|
||||
|
||||
int sys_exit(int error_code)
|
||||
{
|
||||
current_process->status = DEAD;
|
||||
DEBUG("(pid=%u, name=%s)", current_process->pid, current_process->name);
|
||||
return error_code;
|
||||
}
|
||||
|
||||
/*
|
||||
* syscall_handler - System call dispatcher
|
||||
* @regs: CPU state
|
||||
*
|
||||
* This function is called from the interrupt dispatcher,
|
||||
* when an interrupt 0x80 is emitted from userland.
|
||||
*
|
||||
* It switches control to the syscall number provided
|
||||
* in %rax.
|
||||
*
|
||||
* We try to follow the System V convention here:
|
||||
* - syscall number in %rax
|
||||
* - args in %rdi, %rsi, %rdx, %r10, %r8, %r9
|
||||
* - return value (if any) in %rax
|
||||
*
|
||||
* Return:
|
||||
* <regs> - CPU state after system call
|
||||
*/
|
||||
struct cpu_status* syscall_handler(struct cpu_status* regs)
|
||||
{
|
||||
switch (regs->rax)
|
||||
{
|
||||
case 0:
|
||||
DEBUG("sys_read(fd=%u, buf=%p, count=%u)", regs->rdi, regs->rsi, regs->rdx);
|
||||
regs->rax = sys_read(regs->rdi, (char*)regs->rsi, regs->rdx);
|
||||
break;
|
||||
case 1:
|
||||
DEBUG("sys_write(fd=%u, buf=%p, count=%u)", regs->rdi, regs->rsi, regs->rdx);
|
||||
regs->rax = sys_write(regs->rdi, (char*)regs->rsi, regs->rdx);
|
||||
break;
|
||||
case 2:
|
||||
DEBUG("sys_open(filename=%s, flags=%u)", regs->rdi, regs->rsi);
|
||||
regs->rax = sys_open((const char*)regs->rdi, regs->rsi);
|
||||
break;
|
||||
case 3:
|
||||
DEBUG("sys_close(fd=%u)", regs->rdi);
|
||||
regs->rax = sys_close(regs->rdi);
|
||||
break;
|
||||
case 60:
|
||||
DEBUG("sys_exit(error_code=%d)", regs->rdi);
|
||||
regs->rax = sys_exit(regs->rdi);
|
||||
break;
|
||||
default:
|
||||
DEBUG("Bad syscall! (rax=%p, rdi=%p, rsi=%p, rdx=%p)",
|
||||
regs->rax, regs->rdi, regs->rsi, regs->rdx);
|
||||
regs->rax = 0xbad515ca11;
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG("returned rax=%p (%u)", regs->rax, regs->rax);
|
||||
|
||||
return regs;
|
||||
}
|
||||
Reference in New Issue
Block a user