summaryrefslogtreecommitdiff
path: root/Userland/sh.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-11-02 20:41:58 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-11-02 20:41:58 +0100
commit8accc92c3c060e5f3d236bc6ee7de90e64900ace (patch)
treeea21dadcddee2d8cf0bcb3d8259ef1684a7e5ce0 /Userland/sh.cpp
parent10b666f69a610c0bdc5bd60efd1d7d2bf499707d (diff)
downloadserenity-8accc92c3c060e5f3d236bc6ee7de90e64900ace.zip
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.
Diffstat (limited to 'Userland/sh.cpp')
-rw-r--r--Userland/sh.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/Userland/sh.cpp b/Userland/sh.cpp
index 524658e27f..6efa9ce4de 100644
--- a/Userland/sh.cpp
+++ b/Userland/sh.cpp
@@ -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;
}