#include "timer.h" // Need access to current tick usually, but we pass it in wake_check
#include "spinlock.h"
#include "utils.h"
+#include "errno.h"
#include "hal/cpu.h"
#if defined(__i386__)
#include "arch/x86/usermode.h"
}
int process_waitpid(int pid, int* status_out, uint32_t options) {
- if (!current_process) return -1;
+ if (!current_process) return -ECHILD;
const uint32_t WNOHANG = 1U;
if (!found_child) {
spin_unlock_irqrestore(&sched_lock, flags);
- return -1;
+ return -ECHILD;
}
if ((options & WNOHANG) != 0) {
}
static int fd_close(int fd) {
- if (!current_process) return -1;
- if (fd < 0 || fd >= PROCESS_MAX_FILES) return -1;
+ if (!current_process) return -EBADF;
+ if (fd < 0 || fd >= PROCESS_MAX_FILES) return -EBADF;
struct file* f = current_process->files[fd];
- if (!f) return -1;
+ if (!f) return -EBADF;
current_process->files[fd] = NULL;
if (f->refcount > 0) {
static int syscall_open_impl(const char* user_path, uint32_t flags) {
(void)flags;
- if (!user_path) return -1;
+ if (!user_path) return -EFAULT;
char path[128];
for (size_t i = 0; i < sizeof(path); i++) {
if (copy_from_user(&path[i], &user_path[i], 1) < 0) {
- return -1;
+ return -EFAULT;
}
if (path[i] == 0) break;
if (i + 1 == sizeof(path)) {
}
fs_node_t* node = vfs_lookup(path);
- if (!node) return -1;
- if (node->flags != FS_FILE) return -1;
+ if (!node) return -ENOENT;
+ if (node->flags != FS_FILE && node->flags != FS_CHARDEVICE) return -EINVAL;
struct file* f = (struct file*)kmalloc(sizeof(*f));
- if (!f) return -1;
+ if (!f) return -ENOMEM;
f->node = node;
f->offset = 0;
f->flags = 0;
int fd = fd_alloc(f);
if (fd < 0) {
kfree(f);
- return -1;
+ return -EMFILE;
}
return fd;
}
static int syscall_read_impl(int fd, void* user_buf, uint32_t len) {
- if (len > 1024 * 1024) return -1;
- if (user_range_ok(user_buf, (size_t)len) == 0) return -1;
+ if (len > 1024 * 1024) return -EINVAL;
+ if (user_range_ok(user_buf, (size_t)len) == 0) return -EFAULT;
if (fd == 0 && (!current_process || !current_process->files[0])) {
return tty_read(user_buf, len);
}
- if ((fd == 1 || fd == 2) && (!current_process || !current_process->files[fd])) return -1;
+ if ((fd == 1 || fd == 2) && (!current_process || !current_process->files[fd])) return -EBADF;
struct file* f = fd_get(fd);
- if (!f || !f->node) return -1;
+ if (!f || !f->node) return -EBADF;
uint8_t kbuf[256];
uint32_t total = 0;
if (rd == 0) break;
if (copy_to_user((uint8_t*)user_buf + total, kbuf, rd) < 0) {
- return -1;
+ return -EFAULT;
}
f->offset += rd;
uint32_t options = regs->edx;
if (user_status && user_range_ok(user_status, sizeof(int)) == 0) {
- regs->eax = (uint32_t)-1;
+ regs->eax = (uint32_t)-EFAULT;
return;
}
int status = 0;
int retpid = process_waitpid(pid, &status, options);
if (retpid < 0) {
- regs->eax = (uint32_t)-1;
+ regs->eax = (uint32_t)retpid;
return;
}
if (user_status) {
if (copy_to_user(user_status, &status, sizeof(status)) < 0) {
- regs->eax = (uint32_t)-1;
+ regs->eax = (uint32_t)-EFAULT;
return;
}
}
return;
}
- regs->eax = (uint32_t)-1;
+ regs->eax = (uint32_t)-ENOSYS;
}
void syscall_init(void) {
#include "spinlock.h"
#include "uart_console.h"
#include "uaccess.h"
+#include "errno.h"
#include "hal/cpu.h"
}
int tty_write(const void* user_buf, uint32_t len) {
- if (!user_buf) return -1;
- if (len > 1024 * 1024) return -1;
- if (user_range_ok(user_buf, (size_t)len) == 0) return -1;
+ if (!user_buf) return -EFAULT;
+ if (len > 1024 * 1024) return -EINVAL;
+ if (user_range_ok(user_buf, (size_t)len) == 0) return -EFAULT;
char kbuf[256];
uint32_t remaining = len;
uint32_t chunk = remaining;
if (chunk > sizeof(kbuf)) chunk = (uint32_t)sizeof(kbuf);
- if (copy_from_user(kbuf, (const void*)up, (size_t)chunk) < 0) return -1;
+ if (copy_from_user(kbuf, (const void*)up, (size_t)chunk) < 0) return -EFAULT;
for (uint32_t i = 0; i < chunk; i++) {
uart_put_char(kbuf[i]);
}
int tty_read(void* user_buf, uint32_t len) {
- if (!user_buf) return -1;
- if (len > 1024 * 1024) return -1;
- if (user_range_ok(user_buf, (size_t)len) == 0) return -1;
- if (!current_process) return -1;
+ if (!user_buf) return -EFAULT;
+ if (len > 1024 * 1024) return -EINVAL;
+ if (user_range_ok(user_buf, (size_t)len) == 0) return -EFAULT;
+ if (!current_process) return -ECHILD;
while (1) {
uintptr_t flags = spin_lock_irqsave(&tty_lock);
spin_unlock_irqrestore(&tty_lock, flags);
- if (copy_to_user((uint8_t*)user_buf + total, kbuf, (size_t)chunk) < 0) return -1;
+ if (copy_to_user((uint8_t*)user_buf + total, kbuf, (size_t)chunk) < 0) return -EFAULT;
total += chunk;
flags = spin_lock_irqsave(&tty_lock);