1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 10:27:36 +00:00

Implement fork()!

This is quite cool! The syscall entry point plumbs the register dump
down to sys$fork(), which uses it to set up the child process's TSS
in order to resume execution right after the int 0x80 fork() call. :^)

This works pretty well, although there is some problem with the kernel
alias mappings used to clone the parent process's regions. If I disable
the MM::release_page_directory() code, there's no problem. Probably there's
a premature freeing of a physical page somehow.
This commit is contained in:
Andreas Kling 2018-11-02 20:41:58 +01:00
parent 10b666f69a
commit 8accc92c3c
16 changed files with 228 additions and 78 deletions

1
Userland/.gitignore vendored
View file

@ -16,3 +16,4 @@ tst
mm
kill
tty
ft

View file

@ -14,6 +14,7 @@ OBJS = \
tst.o \
mm.o \
kill.o \
ft.o \
tty.o
APPS = \
@ -32,6 +33,7 @@ APPS = \
tst \
mm \
kill \
ft \
tty
ARCH_FLAGS =
@ -91,6 +93,9 @@ clear: clear.o
tst: tst.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
ft: ft.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
mm: mm.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a

14
Userland/ft.cpp Normal file
View file

@ -0,0 +1,14 @@
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
printf("Testing fork()...\n");
pid_t pid = fork();
if (!pid) {
printf("child, pid=%d\n", getpid());
} else {
printf("parent, child pid=%d\n", pid);
}
return 0;
}

View file

@ -32,6 +32,13 @@ static int sh_pwd(int, const char**)
return 0;
}
static int sh_fork(int, const char**)
{
pid_t pid = fork();
printf("getpid()=%d, fork()=%d\n", getpid(), pid);
return 0;
}
static int sh_exit(int, const char**)
{
printf("Good-bye!\n");
@ -94,6 +101,11 @@ static bool handle_builtin(int argc, const char** argv, int& retval)
retval = sh_exit(argc, argv);
return true;
}
if (!strcmp(argv[0], "fork")) {
retval = sh_fork(argc, argv);
return true;
}
return false;
}