mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 10:40:00 +00:00
fd子系统
This commit is contained in:
@@ -18,6 +18,13 @@ typedef unsigned long long usize;
|
||||
#define CLEONOS_SIGCONT 18ULL
|
||||
#define CLEONOS_SIGSTOP 19ULL
|
||||
|
||||
#define CLEONOS_O_RDONLY 0x0000ULL
|
||||
#define CLEONOS_O_WRONLY 0x0001ULL
|
||||
#define CLEONOS_O_RDWR 0x0002ULL
|
||||
#define CLEONOS_O_CREAT 0x0040ULL
|
||||
#define CLEONOS_O_TRUNC 0x0200ULL
|
||||
#define CLEONOS_O_APPEND 0x0400ULL
|
||||
|
||||
typedef struct cleonos_proc_snapshot {
|
||||
u64 pid;
|
||||
u64 ppid;
|
||||
@@ -107,6 +114,11 @@ typedef struct cleonos_proc_snapshot {
|
||||
#define CLEONOS_SYSCALL_STATS_ID_COUNT 69ULL
|
||||
#define CLEONOS_SYSCALL_STATS_RECENT_WINDOW 70ULL
|
||||
#define CLEONOS_SYSCALL_STATS_RECENT_ID 71ULL
|
||||
#define CLEONOS_SYSCALL_FD_OPEN 72ULL
|
||||
#define CLEONOS_SYSCALL_FD_READ 73ULL
|
||||
#define CLEONOS_SYSCALL_FD_WRITE 74ULL
|
||||
#define CLEONOS_SYSCALL_FD_CLOSE 75ULL
|
||||
#define CLEONOS_SYSCALL_FD_DUP 76ULL
|
||||
|
||||
u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
u64 cleonos_sys_log_write(const char *message, u64 length);
|
||||
@@ -180,5 +192,10 @@ u64 cleonos_sys_stats_total(void);
|
||||
u64 cleonos_sys_stats_id_count(u64 id);
|
||||
u64 cleonos_sys_stats_recent_window(void);
|
||||
u64 cleonos_sys_stats_recent_id(u64 id);
|
||||
u64 cleonos_sys_fd_open(const char *path, u64 flags, u64 mode);
|
||||
u64 cleonos_sys_fd_read(u64 fd, void *out_buffer, u64 size);
|
||||
u64 cleonos_sys_fd_write(u64 fd, const void *buffer, u64 size);
|
||||
u64 cleonos_sys_fd_close(u64 fd);
|
||||
u64 cleonos_sys_fd_dup(u64 fd);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -310,3 +310,23 @@ u64 cleonos_sys_stats_recent_window(void) {
|
||||
u64 cleonos_sys_stats_recent_id(u64 id) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_STATS_RECENT_ID, id, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fd_open(const char *path, u64 flags, u64 mode) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FD_OPEN, (u64)path, flags, mode);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fd_read(u64 fd, void *out_buffer, u64 size) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FD_READ, fd, (u64)out_buffer, size);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fd_write(u64 fd, const void *buffer, u64 size) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FD_WRITE, fd, (u64)buffer, size);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fd_close(u64 fd) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FD_CLOSE, fd, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fd_dup(u64 fd) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FD_DUP, fd, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,11 @@ clks_bool clks_exec_spawn_path(const char *path, u64 *out_pid);
|
||||
clks_bool clks_exec_spawn_pathv(const char *path, const char *argv_line, const char *env_line, u64 *out_pid);
|
||||
u64 clks_exec_wait_pid(u64 pid, u64 *out_status);
|
||||
clks_bool clks_exec_request_exit(u64 status);
|
||||
u64 clks_exec_fd_open(const char *path, u64 flags, u64 mode);
|
||||
u64 clks_exec_fd_read(u64 fd, void *out_buffer, u64 size);
|
||||
u64 clks_exec_fd_write(u64 fd, const void *buffer, u64 size);
|
||||
u64 clks_exec_fd_close(u64 fd);
|
||||
u64 clks_exec_fd_dup(u64 fd);
|
||||
u64 clks_exec_current_pid(void);
|
||||
u32 clks_exec_current_tty(void);
|
||||
u64 clks_exec_current_argc(void);
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
#define CLKS_SYSCALL_STATS_ID_COUNT 69ULL
|
||||
#define CLKS_SYSCALL_STATS_RECENT_WINDOW 70ULL
|
||||
#define CLKS_SYSCALL_STATS_RECENT_ID 71ULL
|
||||
#define CLKS_SYSCALL_FD_OPEN 72ULL
|
||||
#define CLKS_SYSCALL_FD_READ 73ULL
|
||||
#define CLKS_SYSCALL_FD_WRITE 74ULL
|
||||
#define CLKS_SYSCALL_FD_CLOSE 75ULL
|
||||
#define CLKS_SYSCALL_FD_DUP 76ULL
|
||||
|
||||
void clks_syscall_init(void);
|
||||
u64 clks_syscall_dispatch(void *frame_ptr);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <clks/fs.h>
|
||||
#include <clks/heap.h>
|
||||
#include <clks/interrupts.h>
|
||||
#include <clks/keyboard.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/serial.h>
|
||||
#include <clks/string.h>
|
||||
@@ -18,6 +19,7 @@ typedef u64 (*clks_exec_entry_fn)(void);
|
||||
#define CLKS_EXEC_PATH_MAX 192U
|
||||
#define CLKS_EXEC_ARG_LINE_MAX 256U
|
||||
#define CLKS_EXEC_ENV_LINE_MAX 512U
|
||||
#define CLKS_EXEC_FD_MAX 32U
|
||||
#define CLKS_EXEC_MAX_ARGS 24U
|
||||
#define CLKS_EXEC_MAX_ENVS 24U
|
||||
#define CLKS_EXEC_ITEM_MAX 128U
|
||||
@@ -25,6 +27,19 @@ typedef u64 (*clks_exec_entry_fn)(void);
|
||||
#define CLKS_EXEC_DEFAULT_KILL_SIGNAL CLKS_EXEC_SIGNAL_TERM
|
||||
#define CLKS_EXEC_KERNEL_ADDR_BASE 0xFFFF800000000000ULL
|
||||
#define CLKS_EXEC_UNWIND_CTX_BYTES 56ULL
|
||||
#define CLKS_EXEC_FD_ACCESS_MASK 0x3ULL
|
||||
#define CLKS_EXEC_O_RDONLY 0x0000ULL
|
||||
#define CLKS_EXEC_O_WRONLY 0x0001ULL
|
||||
#define CLKS_EXEC_O_RDWR 0x0002ULL
|
||||
#define CLKS_EXEC_O_CREAT 0x0040ULL
|
||||
#define CLKS_EXEC_O_TRUNC 0x0200ULL
|
||||
#define CLKS_EXEC_O_APPEND 0x0400ULL
|
||||
|
||||
enum clks_exec_fd_kind {
|
||||
CLKS_EXEC_FD_KIND_NONE = 0,
|
||||
CLKS_EXEC_FD_KIND_TTY = 1,
|
||||
CLKS_EXEC_FD_KIND_FILE = 2,
|
||||
};
|
||||
|
||||
enum clks_exec_proc_state {
|
||||
CLKS_EXEC_PROC_UNUSED = 0,
|
||||
@@ -34,6 +49,15 @@ enum clks_exec_proc_state {
|
||||
CLKS_EXEC_PROC_STOPPED = 4,
|
||||
};
|
||||
|
||||
struct clks_exec_fd_entry {
|
||||
clks_bool used;
|
||||
enum clks_exec_fd_kind kind;
|
||||
u64 flags;
|
||||
u64 offset;
|
||||
u32 tty_index;
|
||||
char path[CLKS_EXEC_PATH_MAX];
|
||||
};
|
||||
|
||||
struct clks_exec_proc_record {
|
||||
clks_bool used;
|
||||
enum clks_exec_proc_state state;
|
||||
@@ -57,6 +81,7 @@ struct clks_exec_proc_record {
|
||||
u64 last_fault_vector;
|
||||
u64 last_fault_error;
|
||||
u64 last_fault_rip;
|
||||
struct clks_exec_fd_entry fds[CLKS_EXEC_FD_MAX];
|
||||
};
|
||||
|
||||
#if defined(CLKS_ARCH_X86_64)
|
||||
@@ -81,6 +106,8 @@ static u64 clks_exec_image_begin_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_image_end_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u32 clks_exec_pid_stack_depth = 0U;
|
||||
|
||||
static struct clks_exec_proc_record *clks_exec_current_proc(void);
|
||||
|
||||
static void clks_exec_serial_write_hex64(u64 value) {
|
||||
int nibble;
|
||||
|
||||
@@ -424,6 +451,188 @@ static u64 clks_exec_alloc_pid(void) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_fd_access_mode_valid(u64 flags) {
|
||||
u64 mode = flags & CLKS_EXEC_FD_ACCESS_MASK;
|
||||
return (mode == CLKS_EXEC_O_RDONLY || mode == CLKS_EXEC_O_WRONLY || mode == CLKS_EXEC_O_RDWR) ? CLKS_TRUE
|
||||
: CLKS_FALSE;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_fd_can_read(u64 flags) {
|
||||
u64 mode = flags & CLKS_EXEC_FD_ACCESS_MASK;
|
||||
return (mode == CLKS_EXEC_O_RDONLY || mode == CLKS_EXEC_O_RDWR) ? CLKS_TRUE : CLKS_FALSE;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_fd_can_write(u64 flags) {
|
||||
u64 mode = flags & CLKS_EXEC_FD_ACCESS_MASK;
|
||||
return (mode == CLKS_EXEC_O_WRONLY || mode == CLKS_EXEC_O_RDWR) ? CLKS_TRUE : CLKS_FALSE;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_path_is_dev_tty(const char *path) {
|
||||
return (path != CLKS_NULL && clks_strcmp(path, "/dev/tty") == 0) ? CLKS_TRUE : CLKS_FALSE;
|
||||
}
|
||||
|
||||
static void clks_exec_fd_init_defaults(struct clks_exec_proc_record *proc) {
|
||||
if (proc == CLKS_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
clks_memset(proc->fds, 0, sizeof(proc->fds));
|
||||
|
||||
proc->fds[0].used = CLKS_TRUE;
|
||||
proc->fds[0].kind = CLKS_EXEC_FD_KIND_TTY;
|
||||
proc->fds[0].flags = CLKS_EXEC_O_RDONLY;
|
||||
proc->fds[0].offset = 0ULL;
|
||||
proc->fds[0].tty_index = proc->tty_index;
|
||||
proc->fds[0].path[0] = '\0';
|
||||
|
||||
proc->fds[1].used = CLKS_TRUE;
|
||||
proc->fds[1].kind = CLKS_EXEC_FD_KIND_TTY;
|
||||
proc->fds[1].flags = CLKS_EXEC_O_WRONLY;
|
||||
proc->fds[1].offset = 0ULL;
|
||||
proc->fds[1].tty_index = proc->tty_index;
|
||||
proc->fds[1].path[0] = '\0';
|
||||
|
||||
proc->fds[2].used = CLKS_TRUE;
|
||||
proc->fds[2].kind = CLKS_EXEC_FD_KIND_TTY;
|
||||
proc->fds[2].flags = CLKS_EXEC_O_WRONLY;
|
||||
proc->fds[2].offset = 0ULL;
|
||||
proc->fds[2].tty_index = proc->tty_index;
|
||||
proc->fds[2].path[0] = '\0';
|
||||
}
|
||||
|
||||
static i32 clks_exec_fd_find_free(struct clks_exec_proc_record *proc) {
|
||||
u32 i;
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0U; i < CLKS_EXEC_FD_MAX; i++) {
|
||||
if (proc->fds[i].used == CLKS_FALSE) {
|
||||
return (i32)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct clks_exec_fd_entry *clks_exec_fd_lookup(struct clks_exec_proc_record *proc, u64 fd) {
|
||||
if (proc == CLKS_NULL || fd >= CLKS_EXEC_FD_MAX) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
if (proc->fds[(u32)fd].used == CLKS_FALSE) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
return &proc->fds[(u32)fd];
|
||||
}
|
||||
|
||||
static u64 clks_exec_fd_file_read(struct clks_exec_fd_entry *entry, void *out_buffer, u64 size) {
|
||||
const void *file_data;
|
||||
u64 file_size = 0ULL;
|
||||
u64 read_len;
|
||||
|
||||
if (entry == CLKS_NULL || out_buffer == CLKS_NULL || size == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
file_data = clks_fs_read_all(entry->path, &file_size);
|
||||
|
||||
if (file_data == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (entry->offset >= file_size) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
read_len = file_size - entry->offset;
|
||||
|
||||
if (read_len > size) {
|
||||
read_len = size;
|
||||
}
|
||||
|
||||
clks_memcpy(out_buffer, (const u8 *)file_data + (usize)entry->offset, (usize)read_len);
|
||||
entry->offset += read_len;
|
||||
return read_len;
|
||||
}
|
||||
|
||||
static u64 clks_exec_fd_file_write(struct clks_exec_fd_entry *entry, const void *buffer, u64 size) {
|
||||
const void *old_data = CLKS_NULL;
|
||||
u64 old_size = 0ULL;
|
||||
u64 write_pos;
|
||||
u64 new_size;
|
||||
void *merged = CLKS_NULL;
|
||||
clks_bool ok;
|
||||
|
||||
if (entry == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (size == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (buffer == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if ((entry->flags & CLKS_EXEC_O_APPEND) != 0ULL) {
|
||||
if (clks_fs_append(entry->path, buffer, size) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
entry->offset += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
old_data = clks_fs_read_all(entry->path, &old_size);
|
||||
|
||||
if (old_data == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
write_pos = entry->offset;
|
||||
|
||||
if (write_pos > (0xFFFFFFFFFFFFFFFFULL - size)) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
new_size = write_pos + size;
|
||||
|
||||
if (new_size < old_size) {
|
||||
new_size = old_size;
|
||||
}
|
||||
|
||||
if (new_size == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
merged = clks_kmalloc((usize)new_size);
|
||||
|
||||
if (merged == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
clks_memset(merged, 0, (usize)new_size);
|
||||
|
||||
if (old_size > 0ULL) {
|
||||
clks_memcpy(merged, old_data, (usize)old_size);
|
||||
}
|
||||
|
||||
clks_memcpy((u8 *)merged + (usize)write_pos, buffer, (usize)size);
|
||||
ok = clks_fs_write_all(entry->path, merged, new_size);
|
||||
clks_kfree(merged);
|
||||
|
||||
if (ok == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
entry->offset = write_pos + size;
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct clks_exec_proc_record *clks_exec_prepare_proc_record(i32 slot,
|
||||
u64 pid,
|
||||
const char *path,
|
||||
@@ -461,6 +670,7 @@ static struct clks_exec_proc_record *clks_exec_prepare_proc_record(i32 slot,
|
||||
proc->last_fault_vector = 0ULL;
|
||||
proc->last_fault_error = 0ULL;
|
||||
proc->last_fault_rip = 0ULL;
|
||||
clks_exec_fd_init_defaults(proc);
|
||||
|
||||
if (proc->argc < CLKS_EXEC_MAX_ARGS) {
|
||||
clks_exec_copy_path(proc->argv_items[proc->argc], CLKS_EXEC_ITEM_MAX, path);
|
||||
@@ -965,6 +1175,215 @@ clks_bool clks_exec_request_exit(u64 status) {
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
u64 clks_exec_fd_open(const char *path, u64 flags, u64 mode) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
struct clks_fs_node_info info;
|
||||
i32 fd_slot;
|
||||
u8 empty_payload = 0U;
|
||||
|
||||
(void)mode;
|
||||
|
||||
if (proc == CLKS_NULL || path == CLKS_NULL || path[0] != '/') {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_strlen(path) >= CLKS_EXEC_PATH_MAX) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_exec_fd_access_mode_valid(flags) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (((flags & CLKS_EXEC_O_TRUNC) != 0ULL || (flags & CLKS_EXEC_O_APPEND) != 0ULL) &&
|
||||
clks_exec_fd_can_write(flags) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
fd_slot = clks_exec_fd_find_free(proc);
|
||||
|
||||
if (fd_slot < 0) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_exec_path_is_dev_tty(path) == CLKS_TRUE) {
|
||||
struct clks_exec_fd_entry *entry = &proc->fds[(u32)fd_slot];
|
||||
|
||||
clks_memset(entry, 0, sizeof(*entry));
|
||||
entry->used = CLKS_TRUE;
|
||||
entry->kind = CLKS_EXEC_FD_KIND_TTY;
|
||||
entry->flags = flags;
|
||||
entry->offset = 0ULL;
|
||||
entry->tty_index = proc->tty_index;
|
||||
entry->path[0] = '\0';
|
||||
return (u64)fd_slot;
|
||||
}
|
||||
|
||||
if (clks_fs_stat(path, &info) == CLKS_FALSE) {
|
||||
if ((flags & CLKS_EXEC_O_CREAT) == 0ULL || clks_exec_fd_can_write(flags) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_fs_write_all(path, &empty_payload, 0ULL) == CLKS_FALSE || clks_fs_stat(path, &info) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.type != CLKS_FS_NODE_FILE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if ((flags & CLKS_EXEC_O_TRUNC) != 0ULL) {
|
||||
if (clks_fs_write_all(path, &empty_payload, 0ULL) == CLKS_FALSE || clks_fs_stat(path, &info) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct clks_exec_fd_entry *entry = &proc->fds[(u32)fd_slot];
|
||||
|
||||
clks_memset(entry, 0, sizeof(*entry));
|
||||
entry->used = CLKS_TRUE;
|
||||
entry->kind = CLKS_EXEC_FD_KIND_FILE;
|
||||
entry->flags = flags;
|
||||
entry->offset = ((flags & CLKS_EXEC_O_APPEND) != 0ULL) ? info.size : 0ULL;
|
||||
entry->tty_index = proc->tty_index;
|
||||
clks_exec_copy_path(entry->path, sizeof(entry->path), path);
|
||||
}
|
||||
|
||||
return (u64)fd_slot;
|
||||
}
|
||||
|
||||
u64 clks_exec_fd_read(u64 fd, void *out_buffer, u64 size) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
struct clks_exec_fd_entry *entry;
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (size == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (out_buffer == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
entry = clks_exec_fd_lookup(proc, fd);
|
||||
|
||||
if (entry == CLKS_NULL || clks_exec_fd_can_read(entry->flags) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (entry->kind == CLKS_EXEC_FD_KIND_TTY) {
|
||||
u64 count = 0ULL;
|
||||
char *dst = (char *)out_buffer;
|
||||
|
||||
while (count < size) {
|
||||
char ch;
|
||||
|
||||
if (clks_keyboard_pop_char_for_tty(entry->tty_index, &ch) == CLKS_FALSE) {
|
||||
break;
|
||||
}
|
||||
|
||||
dst[count] = ch;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
if (entry->kind == CLKS_EXEC_FD_KIND_FILE) {
|
||||
return clks_exec_fd_file_read(entry, out_buffer, size);
|
||||
}
|
||||
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
u64 clks_exec_fd_write(u64 fd, const void *buffer, u64 size) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
struct clks_exec_fd_entry *entry;
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (size == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (buffer == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
entry = clks_exec_fd_lookup(proc, fd);
|
||||
|
||||
if (entry == CLKS_NULL || clks_exec_fd_can_write(entry->flags) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (entry->kind == CLKS_EXEC_FD_KIND_TTY) {
|
||||
u64 i;
|
||||
const char *src = (const char *)buffer;
|
||||
|
||||
for (i = 0ULL; i < size; i++) {
|
||||
clks_tty_write_char(src[i]);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
if (entry->kind == CLKS_EXEC_FD_KIND_FILE) {
|
||||
return clks_exec_fd_file_write(entry, buffer, size);
|
||||
}
|
||||
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
u64 clks_exec_fd_close(u64 fd) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
struct clks_exec_fd_entry *entry;
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
entry = clks_exec_fd_lookup(proc, fd);
|
||||
|
||||
if (entry == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
clks_memset(entry, 0, sizeof(*entry));
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
u64 clks_exec_fd_dup(u64 fd) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
struct clks_exec_fd_entry *entry;
|
||||
i32 fd_slot;
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
entry = clks_exec_fd_lookup(proc, fd);
|
||||
|
||||
if (entry == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
fd_slot = clks_exec_fd_find_free(proc);
|
||||
|
||||
if (fd_slot < 0) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
proc->fds[(u32)fd_slot] = *entry;
|
||||
return (u64)fd_slot;
|
||||
}
|
||||
|
||||
u64 clks_exec_current_pid(void) {
|
||||
i32 depth_index = clks_exec_current_depth_index();
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define CLKS_SYSCALL_KDBG_STACK_WINDOW_BYTES (128ULL * 1024ULL)
|
||||
#define CLKS_SYSCALL_KERNEL_SYMBOL_FILE "/system/kernel.sym"
|
||||
#define CLKS_SYSCALL_KERNEL_ADDR_BASE 0xFFFF800000000000ULL
|
||||
#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_STATS_RECENT_ID
|
||||
#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_FD_DUP
|
||||
#define CLKS_SYSCALL_STATS_RING_SIZE 256U
|
||||
|
||||
struct clks_syscall_frame {
|
||||
@@ -210,6 +210,40 @@ static u64 clks_syscall_kbd_get_char(void) {
|
||||
return (u64)(u8)ch;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fd_open(u64 arg0, u64 arg1, u64 arg2) {
|
||||
char path[CLKS_SYSCALL_PATH_MAX];
|
||||
|
||||
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return clks_exec_fd_open(path, arg1, arg2);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fd_read(u64 arg0, u64 arg1, u64 arg2) {
|
||||
if (arg2 > 0ULL && arg1 == 0ULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return clks_exec_fd_read(arg0, (void *)arg1, arg2);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fd_write(u64 arg0, u64 arg1, u64 arg2) {
|
||||
if (arg2 > 0ULL && arg1 == 0ULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return clks_exec_fd_write(arg0, (const void *)arg1, arg2);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fd_close(u64 arg0) {
|
||||
return clks_exec_fd_close(arg0);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fd_dup(u64 arg0) {
|
||||
return clks_exec_fd_dup(arg0);
|
||||
}
|
||||
|
||||
static clks_bool clks_syscall_procfs_is_root(const char *path) {
|
||||
return (path != CLKS_NULL && clks_strcmp(path, "/proc") == 0) ? CLKS_TRUE : CLKS_FALSE;
|
||||
}
|
||||
@@ -1786,6 +1820,16 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
||||
return clks_syscall_stats_recent_window();
|
||||
case CLKS_SYSCALL_STATS_RECENT_ID:
|
||||
return clks_syscall_stats_recent_id(frame->rbx);
|
||||
case CLKS_SYSCALL_FD_OPEN:
|
||||
return clks_syscall_fd_open(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_FD_READ:
|
||||
return clks_syscall_fd_read(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_FD_WRITE:
|
||||
return clks_syscall_fd_write(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_FD_CLOSE:
|
||||
return clks_syscall_fd_close(frame->rbx);
|
||||
case CLKS_SYSCALL_FD_DUP:
|
||||
return clks_syscall_fd_dup(frame->rbx);
|
||||
default:
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
- `/proc/<pid>`:指定 PID 快照文本
|
||||
- `/proc` 为只读;写入类 syscall 不支持。
|
||||
|
||||
## 4. Syscall 列表(0~71)
|
||||
## 4. Syscall 列表(0~76)
|
||||
|
||||
### 0 `CLEONOS_SYSCALL_LOG_WRITE`
|
||||
|
||||
@@ -557,6 +557,53 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
- `arg0`: `u64 id`
|
||||
- 返回:指定 syscall ID 在“最近窗口”中的出现次数(ID 越界返回 `0`)
|
||||
|
||||
### 72 `CLEONOS_SYSCALL_FD_OPEN`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `const char *path`
|
||||
- `arg1`: `u64 flags`
|
||||
- `arg2`: `u64 mode`(当前保留)
|
||||
- 返回:成功返回 `fd`,失败返回 `-1`
|
||||
- 说明:
|
||||
- 当前支持普通文件与 `/dev/tty`。
|
||||
- 默认进程会预置 `fd 0/1/2`(stdin/stdout/stderr)。
|
||||
- 标志位兼容子集:`O_RDONLY/O_WRONLY/O_RDWR/O_CREAT/O_TRUNC/O_APPEND`。
|
||||
|
||||
### 73 `CLEONOS_SYSCALL_FD_READ`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `u64 fd`
|
||||
- `arg1`: `void *out_buffer`
|
||||
- `arg2`: `u64 size`
|
||||
- 返回:读取字节数;错误返回 `-1`
|
||||
- 说明:
|
||||
- 对 `tty fd`(如 stdin)为非阻塞读取:无输入时返回 `0`。
|
||||
- 对文件 fd 为顺序读取,内部维护偏移。
|
||||
|
||||
### 74 `CLEONOS_SYSCALL_FD_WRITE`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `u64 fd`
|
||||
- `arg1`: `const void *buffer`
|
||||
- `arg2`: `u64 size`
|
||||
- 返回:写入字节数;错误返回 `-1`
|
||||
- 说明:
|
||||
- `tty fd` 输出到终端。
|
||||
- 文件 fd 支持顺序写;`O_APPEND` 下始终追加。
|
||||
|
||||
### 75 `CLEONOS_SYSCALL_FD_CLOSE`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `u64 fd`
|
||||
- 返回:成功 `0`,失败 `-1`
|
||||
|
||||
### 76 `CLEONOS_SYSCALL_FD_DUP`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `u64 oldfd`
|
||||
- 返回:新 fd;失败 `-1`
|
||||
- 说明:当前为“按值复制”语义(复制 flags/offset/目标对象)。
|
||||
|
||||
## 5. 用户态封装函数
|
||||
|
||||
用户态封装位于:
|
||||
@@ -581,6 +628,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
- `cleonos_sys_proc_count()` / `cleonos_sys_proc_pid_at()` / `cleonos_sys_proc_snapshot()` / `cleonos_sys_proc_kill()`
|
||||
- `cleonos_sys_kdbg_sym()` / `cleonos_sys_kdbg_bt()` / `cleonos_sys_kdbg_regs()`
|
||||
- `cleonos_sys_stats_total()` / `cleonos_sys_stats_id_count()` / `cleonos_sys_stats_recent_window()` / `cleonos_sys_stats_recent_id()`
|
||||
- `cleonos_sys_fd_open()` / `cleonos_sys_fd_read()` / `cleonos_sys_fd_write()` / `cleonos_sys_fd_close()` / `cleonos_sys_fd_dup()`
|
||||
|
||||
## 6. 开发注意事项
|
||||
|
||||
@@ -591,6 +639,6 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
|
||||
## 7. Wine 兼容说明
|
||||
|
||||
- `wine/cleonos_wine_lib/runner.py` 目前以 syscall `0..67` 为主,新增 ID 需同步适配后才能完整观测统计类接口。
|
||||
- `wine/cleonos_wine_lib/runner.py` 目前以 syscall `0..67` 为主;`68..76`(stats/fd)需同步适配后才能完整覆盖。
|
||||
- Wine 在运行时崩溃场景下会生成与内核一致格式的“信号编码退出状态”,可通过 `WAITPID` 读取。
|
||||
- Wine 当前音频 syscall 为占位实现:`AUDIO_AVAILABLE=0`,`AUDIO_PLAY_TONE=0`,`AUDIO_STOP=1`。
|
||||
|
||||
Reference in New Issue
Block a user