diff options
Diffstat (limited to 'kernel.soso/syscalls.c')
-rw-r--r-- | kernel.soso/syscalls.c | 983 |
1 files changed, 0 insertions, 983 deletions
diff --git a/kernel.soso/syscalls.c b/kernel.soso/syscalls.c deleted file mode 100644 index 8b72941f..00000000 --- a/kernel.soso/syscalls.c +++ /dev/null @@ -1,983 +0,0 @@ -#include "syscalls.h" -#include "fs.h" -#include "process.h" -#include "screen.h" -#include "alloc.h" -#include "pipe.h" -#include "debugprint.h" -#include "timer.h" -#include "sleep.h" -#include "ttydriver.h" -#include "spinlock.h" -#include "message.h" -#include "commonuser.h" -#include "syscalltable.h" -#include "isr.h" -#include "sharedmemory.h" - - -/************** - * All of syscall entered with interrupts disabled! - * A syscall can enable interrupts if it is needed. - * - **************/ - -static void handleSyscall(Registers* regs); - -static void* gSyscallTable[SYSCALL_COUNT]; - - -int syscall_open(const char *pathname, int flags); -int syscall_close(int fd); -int syscall_read(int fd, void *buf, int nbytes); -int syscall_write(int fd, void *buf, int nbytes); -int syscall_lseek(int fd, int offset, int whence); -int syscall_stat(const char *path, struct stat *buf); -int syscall_fstat(int fd, struct stat *buf); -int syscall_ioctl(int fd, int32 request, void *arg); -int syscall_exit(int status); -void* syscall_sbrk(uint32 increment); -int syscall_fork(); -int syscall_getpid(); -int syscall_execute(const char *path, char *const argv[], char *const envp[]); -int syscall_execve(const char *path, char *const argv[], char *const envp[]); -int syscall_wait(int *wstatus); -int syscall_kill(int pid, int sig); -int syscall_mount(const char *source, const char *target, const char *fsType, unsigned long flags, void *data); -int syscall_unmount(const char *target); -int syscall_mkdir(const char *path, uint32 mode); -int syscall_rmdir(const char *path); -int syscall_getdents(int fd, char *buf, int nbytes); -int syscall_getWorkingDirectory(char *buf, int size); -int syscall_setWorkingDirectory(const char *path); -int syscall_managePipe(const char *pipeName, int operation, int data); -int syscall_readDir(int fd, void *dirent, int index); -int syscall_getUptimeMilliseconds(); -int syscall_sleepMilliseconds(int ms); -int syscall_executeOnTTY(const char *path, char *const argv[], char *const envp[], const char *ttyPath); -int syscall_manageMessage(int command, void* message); -void* syscall_mmap(void *addr, int length, int flags, int fd, int offset); -int syscall_munmap(void *addr, int length); -int syscall_shm_open(const char *name, int oflag, int mode); -int syscall_shm_unlink(const char *name); -int syscall_ftruncate(int fd, int size); -int syscall_posix_openpt(int flags); -int syscall_ptsname_r(int fd, char *buf, int buflen); - - -void initialiseSyscalls() { - memset((uint8*)gSyscallTable, 0, sizeof(void*) * SYSCALL_COUNT); - - gSyscallTable[SYS_open] = syscall_open; - gSyscallTable[SYS_close] = syscall_close; - gSyscallTable[SYS_read] = syscall_read; - gSyscallTable[SYS_write] = syscall_write; - gSyscallTable[SYS_lseek] = syscall_lseek; - gSyscallTable[SYS_stat] = syscall_stat; - gSyscallTable[SYS_fstat] = syscall_fstat; - gSyscallTable[SYS_ioctl] = syscall_ioctl; - gSyscallTable[SYS_exit] = syscall_exit; - gSyscallTable[SYS_sbrk] = syscall_sbrk; - gSyscallTable[SYS_fork] = syscall_fork; - gSyscallTable[SYS_getpid] = syscall_getpid; - - gSyscallTable[SYS_execute] = syscall_execute; - gSyscallTable[SYS_execve] = syscall_execve; - gSyscallTable[SYS_wait] = syscall_wait; - gSyscallTable[SYS_kill] = syscall_kill; - gSyscallTable[SYS_mount] = syscall_mount; - gSyscallTable[SYS_unmount] = syscall_unmount; - gSyscallTable[SYS_mkdir] = syscall_mkdir; - gSyscallTable[SYS_rmdir] = syscall_rmdir; - gSyscallTable[SYS_getdents] = syscall_getdents; - gSyscallTable[SYS_getWorkingDirectory] = syscall_getWorkingDirectory; - gSyscallTable[SYS_setWorkingDirectory] = syscall_setWorkingDirectory; - gSyscallTable[SYS_managePipe] = syscall_managePipe; - gSyscallTable[SYS_readDir] = syscall_readDir; - gSyscallTable[SYS_getUptimeMilliseconds] = syscall_getUptimeMilliseconds; - gSyscallTable[SYS_sleepMilliseconds] = syscall_sleepMilliseconds; - gSyscallTable[SYS_executeOnTTY] = syscall_executeOnTTY; - gSyscallTable[SYS_manageMessage] = syscall_manageMessage; - gSyscallTable[SYS_UNUSED] = NULL; - gSyscallTable[SYS_mmap] = syscall_mmap; - gSyscallTable[SYS_munmap] = syscall_munmap; - gSyscallTable[SYS_shm_open] = syscall_shm_open; - gSyscallTable[SYS_shm_unlink] = syscall_shm_unlink; - gSyscallTable[SYS_ftruncate] = syscall_ftruncate; - gSyscallTable[SYS_posix_openpt] = syscall_posix_openpt; - gSyscallTable[SYS_ptsname_r] = syscall_ptsname_r; - - // Register our syscall handler. - registerInterruptHandler (0x80, &handleSyscall); -} - -static void handleSyscall(Registers* regs) { - if (regs->eax >= SYSCALL_COUNT) { - return; - } - - void *location = gSyscallTable[regs->eax]; - - if (NULL == location) { - regs->eax = -1; - return; - } - - //printkf("We are in syscall_handler\n"); - //Screen_PrintInterruptsEnabled(); - - //I think it is better to enable interrupts in syscall implementations if it is needed. - - int ret; - asm volatile (" \ - pushl %1; \ - pushl %2; \ - pushl %3; \ - pushl %4; \ - pushl %5; \ - call *%6; \ - popl %%ebx; \ - popl %%ebx; \ - popl %%ebx; \ - popl %%ebx; \ - popl %%ebx; \ - " : "=a" (ret) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (location)); - regs->eax = ret; -} - -int syscall_open(const char *pathname, int flags) { - Process* process = getCurrentThread()->owner; - if (process) { - //printkf("open():[%s]\n", pathname); - FileSystemNode* node = getFileSystemNodeAbsoluteOrRelative(pathname, process); - if (node) { - //printkf("open():node:[%s]\n", node->name); - File* file = open_fs(node, flags); - - if (file) { - return file->fd; - } - } - } - - return -1; -} - -int syscall_close(int fd) { - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - close_fs(file); - - return 0; - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_read(int fd, void *buf, int nbytes) { - //printkf("syscall_read: begin - nbytes:%d\n", nbytes); - - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - //Debug_PrintF("syscall_read(%d): %s\n", process->pid, buf); - - //enableInterrupts(); - - //Each handler is free to enable interrupts. - //We don't enable them here. - - return read_fs(file, nbytes, buf); - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_write(int fd, void *buf, int nbytes) { - Process* process = getCurrentThread()->owner; - if (process) { - //printkf("syscall_write() called from process: %d. fd:%d\n", process->pid, fd); - - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - /* - for (int i = 0; i < nbytes; ++i) { - Debug_PrintF("pid:%d syscall_write:buf[%d]=%c\n", process->pid, i, ((char*)buf)[i]); - } - */ - - uint32 writeResult = write_fs(file, nbytes, buf); - - return writeResult; - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_lseek(int fd, int offset, int whence) { - Process* process = getCurrentThread()->owner; - if (process) { - //printkf("syscall_lseek() called from process: %d. fd:%d\n", process->pid, fd); - - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - return lseek_fs(file, offset, whence); - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_stat(const char *path, struct stat *buf) { - Process* process = getCurrentThread()->owner; - if (process) { - //printkf("syscall_stat() called from process: %d. path:%s\n", process->pid, path); - - FileSystemNode* node = getFileSystemNodeAbsoluteOrRelative(path, process); - - if (node) { - return stat_fs(node, buf); - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_fstat(int fd, struct stat *buf) { - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - return stat_fs(file->node, buf); - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_ioctl(int fd, int32 request, void *arg) { - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - return ioctl_fs(file, request, arg); - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_exit(int status) { - Process* process = getCurrentThread()->owner; - if (process) { - printkf("syscall_exit(%d)\n", status); - printkf("process pid: %d\n", process->pid); - if (process->parent) { - printkf("process parent pid: %d\n", process->parent->pid); - printkf("writing %d to %p\n", 1, &process->parent->childExitStatusPresent); - process->parent->childExitStatusPresent = 1; - printkf("writing %d to %x\n", status, &process->parent->childExitStatus); - process->parent->childExitStatus = status; - } - - destroyProcess(process); - - waitForSchedule(); - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -void* syscall_sbrk(uint32 increment) { - //printkf("syscall_sbrk() !!! inc:%d\n", increment); - - Process* process = getCurrentThread()->owner; - if (process) { - return sbrk(process, increment); - } - else { - PANIC("Process is NULL!\n"); - } - - return (void*)-1; -} - -int syscall_fork() { - //Not implemented - - return -1; -} - -int syscall_getpid() { - Process* process = getCurrentThread()->owner; - if (process) { - return process->pid; - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -//NON-posix -int syscall_execute(const char *path, char *const argv[], char *const envp[]) { - int result = -1; - - printkf("syscall_execute: %s\n", path); - Process* process = getCurrentThread()->owner; - if (process) { - printkf("found current process\n"); - FileSystemNode* node = getFileSystemNodeAbsoluteOrRelative(path, process); - if (node) { - File* f = open_fs(node, 0); - if (f) { - printkf("file found\n"); - void* image = kmalloc(node->length); - - //printkf("executing %s and its %d bytes\n", filename, node->length); - - int32 bytesRead = read_fs(f, node->length, image); - - //printkf("syscall_execute: read_fs returned %d bytes\n", bytesRead); - - if (bytesRead > 0) { - printkf("creating user process from ELF data\n"); - Process* newProcess = createUserProcessFromElfData("userProcess", image, argv, envp, process, NULL); - - if (newProcess) { - result = newProcess->pid; - } - } - close_fs(f); - - kfree(image); - } - - } - } - else { - PANIC("Process is NULL!\n"); - } - - return result; -} - -int syscall_executeOnTTY(const char *path, char *const argv[], char *const envp[], const char *ttyPath) { - int result = -1; - - Process* process = getCurrentThread()->owner; - if (process) { - FileSystemNode* node = getFileSystemNodeAbsoluteOrRelative(path, process); - FileSystemNode* ttyNode = getFileSystemNodeAbsoluteOrRelative(ttyPath, process); - if (node && ttyNode) { - File* f = open_fs(node, 0); - if (f) { - void* image = kmalloc(node->length); - - //printkf("executing %s and its %d bytes\n", filename, node->length); - - int32 bytesRead = read_fs(f, node->length, image); - - //printkf("syscall_execute: read_fs returned %d bytes\n", bytesRead); - - if (bytesRead > 0) { - Process* newProcess = createUserProcessFromElfData("userProcess", image, argv, envp, process, ttyNode); - - if (newProcess) { - result = newProcess->pid; - } - } - close_fs(f); - - kfree(image); - } - - } - } - else { - PANIC("Process is NULL!\n"); - } - - return result; -} - -int syscall_execve(const char *path, char *const argv[], char *const envp[]) { - Process* callingProcess = getCurrentThread()->owner; - - FileSystemNode* node = getFileSystemNode(path); - if (node) { - File* f = open_fs(node, 0); - if (f) { - void* image = kmalloc(node->length); - - if (read_fs(f, node->length, image) > 0) { - disableInterrupts(); //just in case if a file operation left interrupts enabled. - - Process* newProcess = createUserProcessEx("fromExecve", callingProcess->pid, 0, NULL, image, argv, envp, NULL, callingProcess->tty); - - close_fs(f); - - kfree(image); - - if (newProcess) { - destroyProcess(callingProcess); - - waitForSchedule(); - - //unreachable - } - } - - close_fs(f); - - kfree(image); - } - } - - - //if it all goes well, this line is unreachable - return 0; -} - -int syscall_wait(int *wstatus) { - //TODO: return pid of exited child. implement with sendsignal - Thread* currentThread = getCurrentThread(); - - Process* process = currentThread->owner; - if (process) { - printkf("wait: I am %d at %x\n", process->pid, process); - Thread* thread = getMainKernelThread(); - while (thread) { - printkf("wait: checking %d at %x\n", thread->owner->pid, thread->owner); - printkf("wait: parent is %d at %x\n", thread->owner->parent->pid, thread->owner->parent); - if (process == thread->owner->parent) { - //We have a child process - printkf("wait: d\n"); - - currentThread->state = TS_WAITCHILD; - - enableInterrupts(); - while (currentThread->state == TS_WAITCHILD); - - if (process->childExitStatusPresent) { - printkf("wait: reading from %x: %d\n", &process->childExitStatus, process->childExitStatus); - return process->childExitStatus; - } - break; - } - - thread = thread->next; - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_kill(int pid, int sig) { - Process* selfProcess = getCurrentThread()->owner; - - Thread* thread = getMainKernelThread(); - while (thread) { - if (pid == thread->owner->pid) { - //We have found the process - - //TODO if (sig==KILL) - { - destroyProcess(thread->owner); - - if (thread->owner == selfProcess) { - waitForSchedule(); - } - else { - return 0; - } - } - break; - } - - thread = thread->next; - } - - return -1; -} - -int syscall_mount(const char *source, const char *target, const char *fsType, unsigned long flags, void *data) { // non-posix - BOOL result = mountFileSystem(source, target, fsType, flags, data); - - if (TRUE == result) { - return 0;//on success - } - - return -1;//on error -} - -int syscall_unmount(const char *target) { // non-posix - FileSystemNode* targetNode = getFileSystemNode(target); - - if (targetNode) { - if (targetNode->nodeType == FT_MountPoint) { - targetNode->nodeType = FT_Directory; - - targetNode->mountPoint = NULL; - - //TODO: check conditions, maybe busy. make clean up. - - return 0;//on success - } - } - - return -1;//on error -} - -int syscall_mkdir(const char *path, uint32 mode) { - char parentPath[128]; - const char* name = NULL; - int length = strlen(path); - for (int i = length - 1; i >= 0; --i) { - if (path[i] == '/') { - name = path + i + 1; - strncpy(parentPath, path, i); - parentPath[i] = '\0'; - break; - } - } - - if (strlen(parentPath) == 0) { - parentPath[0] = '/'; - parentPath[1] = '\0'; - } - - if (strlen(name) == 0) { - return -1; - } - - //printkf("mkdir: parent:[%s] name:[%s]\n", parentPath, name); - - FileSystemNode* targetNode = getFileSystemNode(parentPath); - - if (targetNode) { - BOOL success = mkdir_fs(targetNode, name, mode); - if (success) { - return 0;//on success - } - } - - return -1;//on error -} - -int syscall_rmdir(const char *path) { - //TODO: - //return 0;//on success - - return -1;//on error -} - -int syscall_getdents(int fd, char *buf, int nbytes) { - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - //printkf("syscall_getdents(%d): %s\n", process->pid, buf); - - int byteCounter = 0; - - int index = 0; - FileSystemDirent* dirent = readdir_fs(file->node, index); - - while (NULL != dirent && (byteCounter + sizeof(FileSystemDirent) <= nbytes)) { - memcpy((uint8*)buf + byteCounter, (uint8*)dirent, sizeof(FileSystemDirent)); - - byteCounter += sizeof(FileSystemDirent); - - index += 1; - dirent = readdir_fs(file->node, index); - } - - return byteCounter; - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1;//on error -} - -int syscall_readDir(int fd, void *dirent, int index) { - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - FileSystemDirent* direntFs = readdir_fs(file->node, index); - - if (direntFs) { - memcpy((uint8*)dirent, (uint8*)direntFs, sizeof(FileSystemDirent)); - - return 1; - } - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1;//on error -} - -int syscall_getWorkingDirectory(char *buf, int size) { - Process* process = getCurrentThread()->owner; - if (process) { - if (process->workingDirectory) { - return getFileSystemNodePath(process->workingDirectory, buf, size); - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1;//on error -} - -int syscall_setWorkingDirectory(const char *path) { - Process* process = getCurrentThread()->owner; - if (process) { - FileSystemNode* node = getFileSystemNodeAbsoluteOrRelative(path, process); - - if (node) { - process->workingDirectory = node; - - return 0; //success - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1;//on error -} - -int syscall_managePipe(const char *pipeName, int operation, int data) { - int result = -1; - - switch (operation) { - case 0: - result = existsPipe(pipeName); - break; - case 1: - result = createPipe(pipeName, data); - break; - case 2: - result = destroyPipe(pipeName); - break; - } - - return result; -} - -int syscall_getUptimeMilliseconds() { - return getUptimeMilliseconds(); -} - -int syscall_sleepMilliseconds(int ms) { - Thread* thread = getCurrentThread(); - - sleepMilliseconds(thread, (uint32)ms); - - return 0; -} - -int syscall_manageMessage(int command, void* message) { - Thread* thread = getCurrentThread(); - - int result = -1; - - switch (command) { - case 0: - result = getMessageQueueCount(thread); - break; - case 1: - sendMesage(thread, (SosoMessage*)message); - result = 0; - break; - case 2: - //make blocking - result = getNextMessage(thread, (SosoMessage*)message); - break; - default: - break; - } - - return result; -} - -void* syscall_mmap(void *addr, int length, int flags, int fd, int offset) { - if (addr) { - //Mapping to a specified address is not implemented - - return (void*)-1; - } - - Process* process = getCurrentThread()->owner; - - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - void* ret = mmap_fs(file, length, offset, flags); - - if (ret) { - return ret; - } - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return (void*)-1; -} - -int syscall_munmap(void *addr, int length) { - //TODO: fd - - /* - Process* process = getCurrentThread()->owner; - - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - if (munmap_fs(file, addr, length)) { - return 0;//on success - } - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - */ - - return -1; -} - -#define O_CREAT 0x200 - -int syscall_shm_open(const char *name, int oflag, int mode) { - FileSystemNode* node = NULL; - - if ((oflag & O_CREAT) == O_CREAT) { - node = createSharedMemory(name); - } - else { - node = getSharedMemoryNode(name); - } - - if (node) { - File* file = open_fs(node, oflag); - - if (file) { - return file->fd; - } - } - - return -1; -} - -int syscall_shm_unlink(const char *name) { - return -1; -} - -int syscall_ftruncate(int fd, int size) { - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - return ftruncate_fs(file, size); - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_posix_openpt(int flags) { - Process* process = getCurrentThread()->owner; - if (process) { - FileSystemNode* node = createPseudoTerminal(); - if (node) { - File* file = open_fs(node, flags); - - if (file) { - return file->fd; - } - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1; -} - -int syscall_ptsname_r(int fd, char *buf, int buflen) { - Process* process = getCurrentThread()->owner; - if (process) { - if (fd < MAX_OPENED_FILES) { - File* file = process->fd[fd]; - - if (file) { - /* - int result = getSlavePath(file->node, buf, buflen); - - if (result > 0) { - return 0; //return 0 on success - } - */ - } - else { - //TODO: error invalid fd - } - } - else { - //TODO: error invalid fd - } - } - else { - PANIC("Process is NULL!\n"); - } - - return -1;//on error -} |