summaryrefslogtreecommitdiff
path: root/sched
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-30 20:46:36 +0100
committerAnton Kling <anton@kling.gg>2023-10-30 21:49:48 +0100
commitecf1e4c6c6efc3edeb006ff120ac60a191ddce50 (patch)
treedb5e312704d43ec8ff0a81bc87c9a1cdf6b01970 /sched
parentc7a07bf214ef9b3fabc15c8e70f696ede9644c2c (diff)
Kernel/LibC: Add signals and support for custom signal handlers to processes.
Diffstat (limited to 'sched')
-rw-r--r--sched/scheduler.c65
-rw-r--r--sched/scheduler.h12
2 files changed, 68 insertions, 9 deletions
diff --git a/sched/scheduler.c b/sched/scheduler.c
index ed85f9b..a6ace7d 100644
--- a/sched/scheduler.c
+++ b/sched/scheduler.c
@@ -19,6 +19,14 @@ extern uint32_t read_eip(void);
process_t *get_current_task(void) { return current_task; }
+void set_signal_handler(int sig, void (*handler)(int)) {
+ if (sig >= 20 || sig < 0)
+ return;
+ if (9 == sig)
+ return;
+ current_task->signal_handlers[sig] = handler;
+}
+
process_t *create_process(process_t *p) {
process_t *r;
r = ksbrk(sizeof(process_t));
@@ -37,9 +45,15 @@ process_t *create_process(process_t *p) {
r->cr3 = (p) ? clone_directory(get_active_pagedirectory())
: get_active_pagedirectory();
r->next = 0;
+ r->incoming_signal = 0;
r->parent = p;
r->child = NULL;
r->halt_list = NULL;
+
+ mmu_allocate_region((void *)(0x80000000 - 0x1000), 0x1000, MMU_FLAG_RW,
+ r->cr3);
+ r->signal_handler_stack = 0x80000000;
+
strcpy(r->current_working_directory, "/");
r->data_segment_end = (p) ? p->data_segment_end : NULL;
memset((void *)r->halts, 0, 2 * sizeof(uint32_t));
@@ -50,6 +64,8 @@ process_t *create_process(process_t *p) {
r->file_descriptors[i]->reference_count++;
}
}
+ if (i < 20)
+ r->signal_handlers[i] = NULL;
r->read_halt_inode[i] = NULL;
r->write_halt_inode[i] = NULL;
r->disconnect_halt_inode[i] = NULL;
@@ -132,7 +148,8 @@ void exit(int status) {
}
uint32_t setup_stack(uint32_t stack_pointer, int argc, char **argv) {
- mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW);
+ mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW,
+ NULL);
flush_tlb();
uint32_t ptr = stack_pointer;
@@ -244,6 +261,8 @@ process_t *next_task(process_t *c) {
c = c->next;
if (!c)
c = ready_queue;
+ if (c->incoming_signal)
+ break;
if (c->sleep_until > pit_num_ms())
continue;
if (is_halted(c) || c->dead)
@@ -271,6 +290,25 @@ int task_save_state(void) {
return 1;
}
+int kill(pid_t pid, int sig) {
+ process_t *p = current_task;
+ p = p->next;
+ if (!p)
+ p = ready_queue;
+ for (; p->pid != pid;) {
+ if (p == current_task)
+ break;
+ p = p->next;
+ if (!p)
+ p = ready_queue;
+ }
+ if (p->pid != pid)
+ return -ESRCH;
+ p->incoming_signal = sig;
+ return 0;
+}
+
+void jump_signal_handler(void *func, uint32_t esp);
void switch_task() {
if (!current_task)
return;
@@ -283,15 +321,32 @@ void switch_task() {
active_directory = current_task->cr3;
- asm(" \
+ if (current_task->incoming_signal) {
+ uint8_t sig = current_task->incoming_signal;
+ current_task->incoming_signal = 0;
+ asm("mov %0, %%cr3" ::"r"(current_task->cr3->physical_address));
+
+ void *handler = current_task->signal_handlers[sig];
+ if (9 == sig) {
+ klog("Task recieved SIGKILL", LOG_NOTE);
+ exit(0);
+ }
+ if (!handler) {
+ klog("Task recieved unhandeled signal. Killing process.", LOG_WARN);
+ exit(1);
+ }
+ jump_signal_handler(handler, current_task->signal_handler_stack);
+ } else {
+ asm(" \
mov %0, %%esp; \
mov %1, %%ebp; \
mov %2, %%ecx; \
mov %3, %%cr3; \
mov $0x1, %%eax; \
jmp *%%ecx" ::"r"(current_task->esp),
- "r"(current_task->ebp), "r"(current_task->eip),
- "r"(current_task->cr3->physical_address));
+ "r"(current_task->ebp), "r"(current_task->eip),
+ "r"(current_task->cr3->physical_address));
+ }
}
MemoryMap **get_free_map(void) {
@@ -318,7 +373,7 @@ void *allocate_virtual_user_memory(size_t length, int prot, int flags) {
if ((void *)-1 == rc)
return (void *)-1;
- mmu_allocate_region(rc, length, MMU_FLAG_RW);
+ mmu_allocate_region(rc, length, MMU_FLAG_RW, NULL);
return rc;
}
diff --git a/sched/scheduler.h b/sched/scheduler.h
index 7df7c40..fc92ff3 100644
--- a/sched/scheduler.h
+++ b/sched/scheduler.h
@@ -4,6 +4,7 @@
#include <fs/vfs.h>
#include <halts.h>
#include <mmu.h>
+#include <signal.h>
#define MAX_PATH 256
#define KEYBOARD_HALT 0
@@ -19,6 +20,8 @@ void *mmap(void *addr, size_t length, int prot, int flags, int fd,
size_t offset);
int munmap(void *addr, size_t length);
int msync(void *addr, size_t length, int flags);
+int kill(pid_t pid, int sig);
+void set_signal_handler(int sig, void (*handler)(int));
typedef struct {
void *u_address;
@@ -34,25 +37,26 @@ struct Process {
char program_name[100];
char current_working_directory[MAX_PATH];
uint32_t eip, esp, ebp;
+ uint8_t incoming_signal;
+ uint32_t signal_handler_stack;
+ void *signal_handlers[20];
PageDirectory *cr3;
vfs_fd_t *file_descriptors[100];
vfs_inode_t *read_halt_inode[100];
vfs_inode_t *write_halt_inode[100];
vfs_inode_t *disconnect_halt_inode[100];
- // struct vfs_fd_t ** file_descriptors;
uint32_t halts[2];
struct Halt *halt_list;
void *data_segment_end;
- // uint32_t *halts;
process_t *next;
process_t *parent;
+ // TODO: Create a linkedlist of childs so that the parent process
+ // can do stuff such as reap zombies and get status.
process_t *child;
MemoryMap *maps[100];
uint32_t sleep_until;
int child_rc;
int dead;
- // FIXME: Create a linkedlisti of childs so that the parent process
- // can do stuff such as reap zombies and get status.
};
process_t *get_current_task(void);