summaryrefslogtreecommitdiff
path: root/kernel/user.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-28 17:28:02 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-28 17:28:02 -0400
commitd28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72 (patch)
treece096652da2f8f9889bb377b80f6aafc9bf05788 /kernel/user.c
parentclone pgdir (diff)
downloadcomus-d28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72.tar.gz
comus-d28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72.tar.bz2
comus-d28c5ba100cbc8a4ea6e4f4da16f5c8319a02a72.zip
fork syscall
Diffstat (limited to 'kernel/user.c')
-rw-r--r--kernel/user.c31
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)