diff --git a/src/arch/x86_64/syscall.asm b/src/arch/x86_64/syscall.asm index 4eec5bfd..f18d27ff 100644 --- a/src/arch/x86_64/syscall.asm +++ b/src/arch/x86_64/syscall.asm @@ -5,7 +5,8 @@ extern syscall_libc_log extern syscall_mmap extern syscall_arch_ctl extern syscall_gettid -func_count equ 4 +extern syscall_open +func_count equ 5 func_table: @@ -13,6 +14,7 @@ func_table: dq syscall_mmap dq syscall_arch_ctl dq syscall_gettid + dq syscall_open section .text global asm_syscall_entry diff --git a/src/include/errno.h b/src/include/errno.h index 57fd616c..d2c73fd8 100644 --- a/src/include/errno.h +++ b/src/include/errno.h @@ -1,14 +1,139 @@ #ifndef _ERRNO_H_INCLUDE #define _ERRNO_H_INCLUDE -#define ENOTDIR 1 -#define ENODEV 2 -#define ENOMEM 3 -#define EINVAL 4 -#define ENOSYS 5 -#define EEXIST 6 -#define ENOENT 7 -#define EACCES 8 -#define EAGAIN 9 +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define ENOTBLK 15 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define ETXTBSY 26 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 35 +#define ENAMETOOLONG 36 +#define ENOLCK 37 +#define ENOSYS 38 +#define ENOTEMPTY 39 +#define ELOOP 40 +#define EWOULDBLOCK EAGAIN +#define ENOMSG 42 +#define EIDRM 43 +#define ECHRNG 44 +#define EL2NSYNC 45 +#define EL3HLT 46 +#define EL3RST 47 +#define ELNRNG 48 +#define EUNATCH 49 +#define ENOCSI 50 +#define EL2HLT 51 +#define EBADE 52 +#define EBADR 53 +#define EXFULL 54 +#define ENOANO 55 +#define EBADRQC 56 +#define EBADSLT 57 +#define EDEADLOCK EDEADLK +#define EBFONT 59 +#define ENOSTR 60 +#define ENODATA 61 +#define ETIME 62 +#define ENOSR 63 +#define ENONET 64 +#define ENOPKG 65 +#define EREMOTE 66 +#define ENOLINK 67 +#define EADV 68 +#define ESRMNT 69 +#define ECOMM 70 +#define EPROTO 71 +#define EMULTIHOP 72 +#define EDOTDOT 73 +#define EBADMSG 74 +#define EOVERFLOW 75 +#define ENOTUNIQ 76 +#define EBADFD 77 +#define EREMCHG 78 +#define ELIBACC 79 +#define ELIBBAD 80 +#define ELIBSCN 81 +#define ELIBMAX 82 +#define ELIBEXEC 83 +#define EILSEQ 84 +#define ERESTART 85 +#define ESTRPIPE 86 +#define EUSERS 87 +#define ENOTSOCK 88 +#define EDESTADDRREQ 89 +#define EMSGSIZE 90 +#define EPROTOTYPE 91 +#define ENOPROTOOPT 92 +#define EPROTONOSUPPORT 93 +#define ESOCKTNOSUPPORT 94 +#define EOPNOTSUPP 95 +#define ENOTSUP EOPNOTSUPP +#define EPFNOSUPPORT 96 +#define EAFNOSUPPORT 97 +#define EADDRINUSE 98 +#define EADDRNOTAVAIL 99 +#define ENETDOWN 100 +#define ENETUNREACH 101 +#define ENETRESET 102 +#define ECONNABORTED 103 +#define ECONNRESET 104 +#define ENOBUFS 105 +#define EISCONN 106 +#define ENOTCONN 107 +#define ESHUTDOWN 108 +#define ETOOMANYREFS 109 +#define ETIMEDOUT 110 +#define ECONNREFUSED 111 +#define EHOSTDOWN 112 +#define EHOSTUNREACH 113 +#define EALREADY 114 +#define EINPROGRESS 115 +#define ESTALE 116 +#define EUCLEAN 117 +#define ENOTNAM 118 +#define ENAVAIL 119 +#define EISNAM 120 +#define EREMOTEIO 121 +#define EDQUOT 122 +#define ENOMEDIUM 123 +#define EMEDIUMTYPE 124 +#define ECANCELED 125 +#define ENOKEY 126 +#define EKEYEXPIRED 127 +#define EKEYREVOKED 128 +#define EKEYREJECTED 129 +#define EOWNERDEAD 130 +#define ENOTRECOVERABLE 131 +#define ERFKILL 132 +#define EHWPOISON 133 #endif diff --git a/src/include/kernel/fd.h b/src/include/kernel/fd.h index 07cf236e..00f374eb 100644 --- a/src/include/kernel/fd.h +++ b/src/include/kernel/fd.h @@ -1,6 +1,11 @@ #ifndef _FD_H_INCLUDE #define _FD_H_INCLUDE +#include +#include + +#define FD_FLAGS_READ 1 +#define FD_FLAGS_WRITE 2 #define O_RDONLY 00 #define O_WRONLY 01 @@ -30,6 +35,7 @@ typedef struct { vnode_t* node; off_t offset; int flags; + int lock; } fd_t; diff --git a/src/include/kernel/sched.h b/src/include/kernel/sched.h index 423acf55..da10fa17 100644 --- a/src/include/kernel/sched.h +++ b/src/include/kernel/sched.h @@ -41,6 +41,7 @@ typedef struct _proc_t{ gid_t gid; uid_t uid; fd_t* fds; + int fdlock; size_t fdcount; off_t firstfreefd; vmm_context* context; diff --git a/src/include/string/strerror.c b/src/include/string/strerror.c index 7ff8d30e..d5449701 100644 --- a/src/include/string/strerror.c +++ b/src/include/string/strerror.c @@ -1,7 +1,7 @@ #include static char* strs[] = { - "No error", + "Unknown error", "Not a directory", "No such device", "Out of memory", @@ -12,5 +12,5 @@ static char* strs[] = { }; char* strerror(int errnum){ - return strs[errnum]; + return strs[0]; // FIXME 0 for now because ABI change } diff --git a/src/sys/sched/scheduler.c b/src/sys/sched/scheduler.c index 1c7dfa52..738aaae3 100644 --- a/src/sys/sched/scheduler.c +++ b/src/sys/sched/scheduler.c @@ -207,6 +207,8 @@ static void switch_thread(thread_t* thread){ vmm_switchcontext(thread->proc->context); } + + arch_getcls()->thread = thread; arch_setkernelstack(thread->kernelstack); @@ -335,6 +337,7 @@ void sched_runinit(){ printf("Open failed: %s\n", strerror(ret)); _panic("Could not load init", 0); } + char* argv[] = {"/sbin/init", NULL}; char* env[] = {NULL}; diff --git a/src/sys/syscalls/open.c b/src/sys/syscalls/open.c new file mode 100644 index 00000000..10b747a4 --- /dev/null +++ b/src/sys/syscalls/open.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +syscallret syscall_open(const char* pathname, int flags, mode_t mode){ + + syscallret retv; + retv.ret = -1; + + if(pathname > USER_SPACE_END){ + retv.errno = EFAULT; + return retv; + } + + const char* name = alloc(strlen(pathname) + 1); // XXX use an user specific strlen func + if(!name){ + retv.errno = ENOMEM; + return retv; + } + + strcpy(name, pathname); // XXX use an user specific strcpy + + proc_t* proc = arch_getcls()->thread->proc; + + spinlock_acquire(&proc->fdlock); + + fd_t* fd = NULL; + + // find fd to use + + for(uintmax_t i = 0; i < proc->fdcount; ++i){ + spinlock_acquire(&proc->fds[i].lock); + if(!proc->fds[i].node){ + fd = &proc->fds[i].node; + break; + } + spinlock_release(&proc->fds[i].lock); + } + + // resize table + + if(!fd){ + + fd_t* tmp = realloc(proc->fds, sizeof(fd_t)*proc->fdcount + 1); + + if(!tmp){ + spinlock_release(&proc->fdlock); + retv.errno = ENOMEM; + return retv; + } + + proc->fds = tmp; + + fd = &proc->fds[proc->fdcount]; + ++proc->fdcount; + spinlock_acquire(&fd->lock); + + } + + spinlock_release(&proc->fdlock); + + fd->flags = flags + 1; // 1 is added to make O_RDONLY etc easier to lookup + fd->offset = 0; + + vnode_t* file; + + size_t ret = vfs_open(&file, + *name == '/' ? proc->root : proc->cwd, + *name == '/' ? name + 1 : name + ); + + if(ret == ENOENT && (flags & O_CREAT)){ + printf("O_CREAT NOT SUPPORTED YET!\n"); + retv.errno = ENOENT; + goto _fail; + } + else if(ret){ + retv.errno = ret; + goto _fail; + } + + if((flags & O_DIRECTORY) && (file->st.st_mode & MAKETYPE(TYPE_DIR)) == 0){ + retv.errno = ENOTDIR; + goto _fail; + } + + + fd->node = file; + + spinlock_release(&fd->lock); + + free(name); + retv.errno = 0; + retv.ret = ((uintptr_t)fd - (uintptr_t)proc->fds) / sizeof(fd_t); + + return retv; + + _fail: + + if(file) + vfs_close(file); + spinlock_release(&fd->lock); + fd->node = NULL; + free(name); + return retv; + +}