diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-28 17:28:02 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-28 17:28:02 -0400 |
commit | d28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72 (patch) | |
tree | ce096652da2f8f9889bb377b80f6aafc9bf05788 /kernel/user.c | |
parent | clone pgdir (diff) | |
download | comus-d28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72.tar.gz comus-d28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72.tar.bz2 comus-d28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72.zip |
fork syscall
Diffstat (limited to '')
-rw-r--r-- | kernel/user.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/kernel/user.c b/kernel/user.c index fc1167d..f9b541c 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -230,6 +230,37 @@ fail: return 1; } +struct pcb *user_clone(struct pcb *pcb) +{ + struct pcb *child; + + if (pcb_alloc(&child)) + return NULL; + + // copy context + memcpy(&child->regs, &pcb->regs, sizeof(struct cpu_regs)); + child->memctx = mem_ctx_clone(pcb->memctx, true); + if (child->memctx == NULL) + return NULL; + + // set metadata + child->parent = pcb; + child->state = PROC_STATE_READY; + child->priority = pcb->priority; + child->ticks = 0; + + // copy heap + child->heap_start = pcb->heap_start; + child->heap_len = pcb->heap_len; + + // copy elf data + memcpy(&child->elf_header, &pcb->elf_header, sizeof(Elf64_Ehdr)); + memcpy(&child->elf_segments, &pcb->elf_segments, sizeof(Elf64_Ehdr)); + child->n_elf_segments = pcb->n_elf_segments; + + return child; +} + void user_cleanup(struct pcb *pcb) { if (pcb == NULL) |