[crt] Implement the entry point, exit(), and atexit()
authorcoderain <coderain@sdf.org>
Fri, 13 Oct 2017 22:26:03 +0000 (00:26 +0200)
committercoderain <coderain@sdf.org>
Fri, 13 Oct 2017 22:26:03 +0000 (00:26 +0200)
crt/include/stdlib.h
crt/src/crt0.c [new file with mode: 0644]
crt/src/exit.c [new file with mode: 0644]
kernel/include/process.h
sdk/process.h

index 1578e6802adadcfc9aa93839051faeac3a4beb9b..e1310ba87d341abeb3b954839e2c3ffebd720da9 100644 (file)
@@ -37,4 +37,9 @@ void *realloc(void *ptr, size_t size);
 void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
 void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
 
+#define ATEXIT_MAX 32
+
+int atexit(void (*function)(void));
+void __attribute__((__noreturn__)) exit(int status);
+
 #endif
diff --git a/crt/src/crt0.c b/crt/src/crt0.c
new file mode 100644 (file)
index 0000000..15f3b1f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * crt0.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <monolithium.h>
+
+int main(int argc, char **argv);
+
+void process_startup(process_params_t *params)
+{
+    int argc = 1;
+    char *ptr;
+    int space = 1;
+
+    for (ptr = params->command_line; *ptr; ptr++)
+    {
+        if (space != (isspace(*ptr) != 0))
+        {
+            argc++;
+            space = !space;
+        }
+    }
+
+    char **argv = (char**)__builtin_alloca(argc * sizeof(char*));
+    argc = 0;
+
+    for (ptr = strtok(params->command_line, " \t\r\n\v\f"); ptr != NULL; ptr = strtok(NULL, " \t\r\n\v\f"))
+    {
+        if (*ptr) argv[argc++] = ptr;
+    }
+
+    argv[argc] = NULL;
+
+    int exit_code = main(argc, argv);
+    exit(exit_code);
+}
diff --git a/crt/src/exit.c b/crt/src/exit.c
new file mode 100644 (file)
index 0000000..51b2fe7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * exit.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <monolithium.h>
+
+static void (*atexit_functions[ATEXIT_MAX])(void);
+static int num_atexit_functions = 0;
+
+int atexit(void (*function)(void))
+{
+    if (num_atexit_functions == ATEXIT_MAX) return 1;
+    atexit_functions[num_atexit_functions++] = function;
+    return 0;
+}
+
+void __attribute__((__noreturn__)) exit(int status)
+{
+    while (num_atexit_functions) atexit_functions[--num_atexit_functions]();
+
+    syscall_terminate(INVALID_HANDLE, status);
+    for (;;);
+}
index 73a0fd0cf47109d630d7232752b9a30e194bfdf7..1c9804aa250f95c94f3b7529e4556cbac41cdc95 100644 (file)
@@ -74,16 +74,9 @@ typedef struct process process_t;
 extern process_t *kernel_process;
 
 process_t *get_current_process();
-sysret_t syscall_open_process(dword_t pid, handle_t *handle);
 void init_user_stack(uintptr_t *stack_pointer, process_params_t *parameters);
-sysret_t syscall_create_process(const char *path, dword_t flags, process_params_t *parameters, handle_t *process_handle, handle_t *thread_handle);
 void process_cleanup(object_t *proc);
 void destroy_process(process_t *process);
-sysret_t syscall_terminate(handle_t handle, dword_t exit_code);
-sysret_t syscall_get_process_id();
-sysret_t syscall_query_process(handle_t handle, process_info_t info_type, void *buffer, dword_t size);
-sysret_t syscall_enum_processes(dword_t *pid_array, dword_t *count);
-sysret_t syscall_wait_process(handle_t handle, dword_t timeout);
 process_t *switch_process(process_t *new_process);
 void process_init();
 
index b5fba551643bee7ca6a7103fd0d3cefd5b44213e..6490ec0aa46d768351d096d5fc404659de1ce6c1 100644 (file)
@@ -48,4 +48,12 @@ typedef struct
     handle_t standard_error;
 } process_params_t;
 
+sysret_t syscall_open_process(dword_t pid, handle_t *handle);
+sysret_t syscall_create_process(const char *path, dword_t flags, process_params_t *parameters, handle_t *process_handle, handle_t *thread_handle);
+sysret_t syscall_terminate(handle_t handle, dword_t exit_code);
+sysret_t syscall_get_process_id();
+sysret_t syscall_query_process(handle_t handle, process_info_t info_type, void *buffer, dword_t size);
+sysret_t syscall_enum_processes(dword_t *pid_array, dword_t *count);
+sysret_t syscall_wait_process(handle_t handle, dword_t timeout);
+
 #endif