BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / commit / d41a53cbc7d055b1c00cf0a339dbed6925f4f02c / task / syscall.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
diff --git a/task/syscall.c b/task/syscall.c
new file mode 100644
index 0000000..d43542d
--- /dev/null
+++ b/task/syscall.c
@@ -0,0 +1,96 @@
+/*
+ * This file handles system calls.  Every system call gets passed to the
+ * syscall_handler() function, which decides which Kernel function to run.
+ * There is an array of syscalls, which are indexed numerically, these are the
+ * syscall numbers.
+ */
+
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include "task.h"
+#include "../screen.h"
+
+/* List of syscalls */
+void *syscalls[] = {
+	/* Tasking */
+	[SYSCALL_DBGPRINTF] = dbgprintf,
+	[SYSCALL_CLONE]     = clone,
+	[SYSCALL_EXIT]      = exit,
+	[SYSCALL_GETPID]    = getpid,
+	[SYSCALL_GETUID]    = getuid,
+	[SYSCALL_SETUID]    = setuid,
+	[SYSCALL_GETEUID]   = geteuid,
+	[SYSCALL_SETEUID]   = seteuid,
+	[SYSCALL_GETGID]    = getgid,
+	[SYSCALL_SETGID]    = setgid,
+	[SYSCALL_GETEGID]   = getegid,
+	[SYSCALL_SETEGID]   = setegid,
+	[SYSCALL_EXECVE]    = execve,
+	[SYSCALL_WAITPID]   = waitpid,
+	[SYSCALL_TGKILL]    = tgkill,
+	[SYSCALL_KILL]      = kill,
+	[SYSCALL_TIME]      = time,
+	[SYSCALL_TIMES]     = times,
+	[SYSCALL_SLEEP]     = sleep,
+
+	/* Files */
+	[SYSCALL_OPEN]     = open,
+	[SYSCALL_CLOSE]    = close,
+	[SYSCALL_READ]     = read,
+	[SYSCALL_WRITE]    = write,
+	[SYSCALL_IOCTL]    = ioctl,
+	[SYSCALL_LSEEK]    = lseek,
+	[SYSCALL_STAT]     = stat,
+	[SYSCALL_GETDENTS] = getdents,
+	[SYSCALL_MKDIR]    = mkdir,
+	[SYSCALL_RMDIR]    = rmdir,
+	[SYSCALL_MKNOD]    = mknod,
+	[SYSCALL_RENAME]   = rename,
+	[SYSCALL_DUP]      = dup,
+	[SYSCALL_DUP2]     = dup2,
+	[SYSCALL_ISATTY]   = isatty,
+
+	/* File System */
+	[SYSCALL_MOUNT]  = mount,
+	[SYSCALL_CHDIR]  = chdir,
+	[SYSCALL_CHROOT] = chroot,
+	[SYSCALL_GETCWD] = getcwd,
+
+	/* Memory */
+	[SYSCALL_MMAP] = mmap,
+
+	/* Messaging */
+	[SYSCALL_NB_SEND_MSG] = nb_send_msg,
+	[SYSCALL_SEND_MSG]    = send_msg,
+	[SYSCALL_NB_RECV_MSG] = nb_recv_msg,
+	[SYSCALL_RECV_MSG]    = recv_msg,
+};
+
+/* Handle a syscall */
+void
+syscall_handler(InterruptFrame *frame)
+{
+	if (frame->eax >= sizeof(syscalls)/sizeof(syscalls[0])) {
+		frame->eax = -EINVAL;
+		return;
+	}
+	void *handler = syscalls[frame->eax];
+	int ret;
+	current->inSyscall = 1;
+
+	size_t num;
+	int *val = (int *) frame->esi;
+	if (!verify_access(val, frame->ecx * sizeof(int), PROT_READ)) {
+		frame->eax = -EINVAL;
+		return;
+	}
+	/* Push args onto stack */
+	for (num = frame->ecx; num; num--)
+		asm volatile("pushl %0" :: "r" (val[num - 1]));
+	/* Call handler */
+	asm volatile("call *%1" : "=a" (ret) : "r" (handler));
+
+	frame->eax = ret;
+	current->inSyscall = 0;
+}