diff --git a/inc/proc/process.h b/inc/proc/process.h index 2ffbcd6..127a189 100644 --- a/inc/proc/process.h +++ b/inc/proc/process.h @@ -28,6 +28,13 @@ typedef enum { PROCESS_BLOCK_ENUM_SIZE } process_blockers_E; +typedef enum { + PROCESS_SIGNAL_START, // SIGSTART + PROCESS_SIGNAL_PAUSE, // SIGPAUSE + PROCESS_SIGNAL_KILL, // SIGKILL + PROCESS_SIGNAL_PFAULT, // SIGPFAULT +} process_signals_E; + typedef struct process_T process_T; struct process_T { char name [128]; @@ -57,6 +64,8 @@ struct process_T { void process_kernel_spawn (elf_executable_T* executable); pid_t process_spawn (pid_t parent, string_t name, elf_executable_T* executable, void* buffer); +void process_signal (process_T* process, process_signals_E signal); +bool process_is_child_of (process_T* process, process_T* parent); int32_t process_get_thread_id (process_T* process); void process_clear_thread_id (process_T* process, uint32_t id); void process_pause_pid (pid_t pid); diff --git a/src/boot/kmain.c b/src/boot/kmain.c index fe56624..1ed065e 100644 --- a/src/boot/kmain.c +++ b/src/boot/kmain.c @@ -69,12 +69,13 @@ void kmain(boot_info_T boot_info) { syscall_perform(SYSCALL_PROCESS_CREATE, (uint64_t)"/initrd/shell.elf", 0, (uint64_t)&pid, 0); process_T* process = scheduler_get_process(pid); - thread_start(process->threads); scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0); g_tty->output = &process->stdin; process->stdout = &g_tty->input; + syscall_perform(SYSCALL_PROCESS_SIGNAL, pid, PROCESS_SIGNAL_START, 0, 0); + CORE_HALT_FOREVER } diff --git a/src/platform/syscall.c b/src/platform/syscall.c index 48fc890..5161426 100644 --- a/src/platform/syscall.c +++ b/src/platform/syscall.c @@ -245,6 +245,24 @@ void syscall_handle_nx_pcreate(cpu_state_T* state) { state->rax = STATUS_SUCCESS; } +void syscall_handle_nx_psignal(cpu_state_T* state) { + pid_t pid = (pid_t)state->rdi; // arg1 + uint64_t signal = state->rsi; // arg2 + + if (pid == PROCESS_NONE) { + state->rax = STATUS_RESOURCE_NOT_AVAILABLE; + return; + } + + process_T* process = scheduler_get_process(pid); + if (!process_is_child_of(process, scheduler_get_current_process())) { + state->rax = STATUS_PERMISSION_DENIED; + return; + } + + process_signal(scheduler_get_process(pid), signal); + state->rax = STATUS_SUCCESS; +} cpu_state_T* syscall_handle(cpu_state_T* state) { cpu_state_T* return_state = state; @@ -303,6 +321,10 @@ cpu_state_T* syscall_handle(cpu_state_T* state) { syscall_handle_nx_pcreate(state); break; } + case SYSCALL_PROCESS_SIGNAL: { + syscall_handle_nx_psignal(state); + break; + } } break; } diff --git a/src/proc/process.c b/src/proc/process.c index e40363b..302fb45 100644 --- a/src/proc/process.c +++ b/src/proc/process.c @@ -52,6 +52,33 @@ pid_t process_spawn(pid_t parent, string_t name, elf_executable_T* executable, v return scheduler_register_process(process); } +void process_signal(process_T* process, process_signals_E signal) { + switch (signal) { + case PROCESS_SIGNAL_START: { + process_start(process); + break; + } + case PROCESS_SIGNAL_PAUSE: { + process_pause(process); + break; + } + case PROCESS_SIGNAL_KILL: { + process_kill(process); + break; + } + default: break; + } +} + +bool process_is_child_of(process_T* process, process_T* parent) { + process_T* tmp = process->parent; + while (tmp != NULL) { + if (tmp == parent) return true; + tmp = tmp->parent; + } + return false; +} + int32_t process_get_thread_id(process_T* process) { for (int i = 0; i < MAX_THREADS_PER_PROCESS; i++) { if (!bitmap_get(&process->thread_ids, i)) {