BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / blob / 1628fcfdfdf2978ed9ccac96ee7d13bb3dc43a01 / task / syscall.c

// Related

Orion

Barry Adding pipes e59e4fe (2 years, 4 months ago)
/*
 * 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_SIGNAL]      = signal,
	[SYSCALL_SIGPROCMASK] = sigprocmask,
	[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,
	[SYSCALL_PIPE]     = pipe,

	/* 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;
}