about summary refs log blame commit diff stats
path: root/kernel.soso/syscalls.c
blob: 8b72941f9f919d9e0e5304240a946c8b63d31165 (plain) (tree)


































































                                                                                                               
                           












































                                                                             

                                            




                                              
                           



                       
                                             




















                                                                                                                          
                                                   
                                                 
                  
                                             
                                                                                      
                   
                                                        

                                              
                       







                                
                           
                                                 

                                    

                                         
                       



                               
                  


                                        
              


                                    
          





                                    
                                                 
                                                           

                                                 

                                    

                                         
                       








                                                                            
                  


                                        
              


                                    
          





                                    
                                                  
                                                 
                  
                                                                                        
 
                                    

                                         
                       
                  
                                                  







                                                                                                        
                  


                                        
              


                                    
          





                                    
                                                   
                                                 
                  
                                                                                        
 
                                    

                                         
                       

                                                      
                  


                                        
              


                                    
          





                                    
                                                      
                                                 
                  
                                                                                           


                                                                                  
                   


                                      
          





                                    
                                             
                                                 

                                    

                                         
                       

                                                
                  


                                        
              


                                    
          





                                    
                                                     
                                                 

                                    

                                         
                       

                                                    
                  


                                        
              


                                    
          





                                    
                              
                                                 
                  













                                                                                           
          





                                    
                                      
                                                        

                                                 
                  

                                        
          





                                    
                    




                     
                      
                                                 
                  

                            
          






                                    
                                                                               



                                                 
                  

                                                                                  
                   
                                       
                    


                                                    
                                                                                     


                                                                  
                                                                                     
 
                                    


                                                                                                                        
                                     









                                                 
          





                                    
                                                                                                         


                                                 
                  

                                                                                        
                              
                                       
                    

                                                    
                                                                                     


                                                                  
                                                                                     
 
                                    

                                                                                                                           
                                     









                                                 
          





                                    
                                                                              


                                                        
               
                                   
                

                                                
                                                      







                                                                                                                                                    
                                 


















                                                   
                                



                                                                 
                  

                                                                
                        

                                                                                                     
                                                   

















                                                                                                                    
          





                                    
                                    


                                                     

                                        

                                       
                                 


                                              
                                                   

                                      
                      











                              
                                                                                                                              

                                                                       
                         





                             
                                                       

                                                           

                                                    












                                                                
                                                  


                              

                                           






                                         
                                  



                             
                            


                  
                                                                  


                                                               
                     
                                                        
                      






                                 
                                     





                           
                                                     
                                                 

                                    

                                         
                       
                                                                           





                                                                         
                                                                                              









                                                                                                
                  


                                        
              


                                    
          





                                    
                                                      
                                                 

                                    

                                         
                       

                                                                           
                               




                                                                                       
                  


                                        
              


                                    
          





                                    
                                                      
                                                 

                                        


                                                                               
          





                                    
                                                   
                                                 
                  

                                                                                  
                   




                                             
          





                                    
                                                                       

                    
                        













                                            
                                     


                                   
                                       






                                          
                                                       



                                        
                      

















                                                               

                                                                           






                                                           

                                    

                                         
                       

                                                                 
                          


                               
                  


                                        
              


                                    
          





                                    
                                            




                                                 

                                    

                                         

                                                    


                                         
                  


                                        
              


                                    
          








                                    
                                                             

                                
                                       

                                        
          


                                         
               

                                          
                   






                            
                                          


              
                                         
                                                 

                                    

                                         
                       

                                                
                  


                                        
              


                                    
          





                                    
                                     
                                                 
                  
                                                      
                   

                                              
                       



                                
          





                                    
                                                      
                                                 

                                    

                                         
                       


                                                                   
                                 



                                                   
                  


                                        
              


                                    
          




                                    
#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
}