diff --git a/lib/libc/core/CMakeLists.txt b/lib/libc/core/CMakeLists.txt index 5a2c280..e6a89d5 100644 --- a/lib/libc/core/CMakeLists.txt +++ b/lib/libc/core/CMakeLists.txt @@ -1,4 +1,4 @@ -set(source_dirs assert stdio stdlib string errno ctype wctype) +set(source_dirs assert stdio stdlib string errno ctype wctype unistd) foreach (dir ${source_dirs}) file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c) diff --git a/lib/libc/core/unistd/fork.c b/lib/libc/core/unistd/fork.c new file mode 100644 index 0000000..373a122 --- /dev/null +++ b/lib/libc/core/unistd/fork.c @@ -0,0 +1,24 @@ +#include +#include +#include + +pid_t fork(void) +{ + kern_handle_t new_task = KERN_HANDLE_INVALID, + new_space = KERN_HANDLE_INVALID; + kern_status_t status = task_duplicate(&new_task, &new_space); + if (status != KERN_OK) { + return __set_errno(__errno_from_kern_status(status)); + } + + if (new_task == KERN_HANDLE_INVALID) { + /* child task */ + return 0; + } + + tid_t child = 0; + task_config_get(new_task, TASK_CFG_ID, &child, sizeof child); + + /* parent task */ + return child; +}