From b1fe4fa4ce1defcdc7f28529d8920db1221261cf Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Wed, 18 Jul 2018 10:45:42 +0900 Subject: [PATCH] More errno stuff --- apps/compositor.c | 2 +- kernel/sys/syscall.c | 77 ++++++++++++++++++++++++------------------ libc/dirent/dir.c | 15 ++++++-- libc/pthread/pthread.c | 7 ++-- libc/stdio/stdio.c | 12 ++++++- libc/unistd/chdir.c | 3 +- libc/unistd/fstat.c | 7 ++-- libc/unistd/open.c | 2 ++ 8 files changed, 80 insertions(+), 45 deletions(-) diff --git a/apps/compositor.c b/apps/compositor.c index 3a67286c..a640dcfe 100644 --- a/apps/compositor.c +++ b/apps/compositor.c @@ -2000,7 +2000,7 @@ int main(int argc, char * argv[]) { mfd = open("/dev/mouse", O_RDONLY); kfd = open("/dev/kbd", O_RDONLY); amfd = open("/dev/absmouse", O_RDONLY); - if (amfd == -1) { + if (amfd < 0) { amfd = open("/dev/vmmouse", O_RDONLY); vmmouse = 1; } diff --git a/kernel/sys/syscall.c b/kernel/sys/syscall.c index dda332a5..5fd0d099 100644 --- a/kernel/sys/syscall.c +++ b/kernel/sys/syscall.c @@ -66,7 +66,7 @@ static int sys_read(int fd, char * ptr, int len) { node->offset += out; return (int)out; } - return -1; + return -EBADF; } static int sys_ioctl(int fd, int request, void * argp) { @@ -74,7 +74,7 @@ static int sys_ioctl(int fd, int request, void * argp) { PTR_VALIDATE(argp); return ioctl_fs(FD_ENTRY(fd), request, argp); } - return -1; + return -EBADF; } static int sys_readdir(int fd, int index, struct dirent * entry) { @@ -84,12 +84,12 @@ static int sys_readdir(int fd, int index, struct dirent * entry) { if (kentry) { memcpy(entry, kentry, sizeof *entry); free(kentry); - return 0; - } else { return 1; + } else { + return 0; } } - return -1; + return -EBADF; } static int sys_write(int fd, char * ptr, int len) { @@ -104,7 +104,7 @@ static int sys_write(int fd, char * ptr, int len) { node->offset += out; return out; } - return -1; + return -EBADF; } static int sys_waitpid(int pid, int * status, int options) { @@ -121,11 +121,13 @@ static int sys_open(const char * file, int flags, int mode) { if (node && !has_permission(node, 04)) { debug_print(WARNING, "access denied (read, sys_open, file=%s)", file); + close_fs(node); return -EACCES; } if (node && ((flags & O_RDWR) || (flags & O_APPEND) || (flags & O_WRONLY) || (flags & O_TRUNC))) { if (!has_permission(node, 02)) { debug_print(WARNING, "access denied (write, sys_open, file=%s)", file); + close_fs(node); return -EACCES; } } @@ -143,7 +145,7 @@ static int sys_open(const char * file, int flags, int mode) { } if (!node) { debug_print(NOTICE, "File does not exist; someone should be setting errno?"); - return -1; + return -ENOENT; } if (flags & O_APPEND) { node->offset = node->length; @@ -159,7 +161,7 @@ static int sys_access(const char * file, int flags) { PTR_VALIDATE(file); debug_print(INFO, "access(%s, 0x%x) from pid=%d", file, flags, getpid()); fs_node_t * node = kopen((char *)file, 0); - if (!node) return -1; + if (!node) return -ENOENT; close_fs(node); return 0; } @@ -170,7 +172,7 @@ static int sys_close(int fd) { FD_ENTRY(fd) = NULL; return 0; } - return -1; + return -EBADF; } static int sys_sbrk(int size) { @@ -255,8 +257,7 @@ static int sys_execve(const char * filename, char *const argv[], char *const env debug_print(INFO,"Executing..."); /* Discard envp */ - exec((char *)filename, argc, (char **)argv_, (char **)envp_); - return -1; + return exec((char *)filename, argc, (char **)argv_, (char **)envp_); } static int sys_seek(int fd, int offset, int whence) { @@ -277,7 +278,7 @@ static int sys_seek(int fd, int offset, int whence) { } return FD_ENTRY(fd)->offset; } - return -1; + return -EBADF; } static int stat_node(fs_node_t * fn, uintptr_t st) { @@ -337,11 +338,16 @@ static int sys_chmod(char * file, int mode) { PTR_VALIDATE(file); fs_node_t * fn = kopen(file, 0); if (fn) { + /* Can group members change bits? I think it's only owners. */ + if (current_process->user != 0 && current_process->user != fn->uid) { + close_fs(fn); + return -EPERM; + } result = chmod_fs(fn, mode); close_fs(fn); return result; } else { - return -1; + return -ENOENT; } } @@ -350,11 +356,16 @@ static int sys_chown(char * file, int uid, int gid) { PTR_VALIDATE(file); fs_node_t * fn = kopen(file, 0); if (fn) { + /* TODO: Owners can change groups... */ + if (current_process->user != 0) { + close_fs(fn); + return -EPERM; + } result = chown_fs(fn, uid, gid); close_fs(fn); return result; } else { - return -1; + return -ENOENT; } } @@ -364,7 +375,7 @@ static int sys_stat(int fd, uintptr_t st) { if (FD_CHECK(fd)) { return stat_node(FD_ENTRY(fd), st); } - return -1; + return -EBADF; } static int sys_mkpipe(void) { @@ -386,7 +397,7 @@ static int sys_setuid(user_t new_uid) { current_process->user = new_uid; return 0; } - return -1; + return -EPERM; } static int sys_uname(struct utsname * name) { @@ -413,7 +424,7 @@ static int sys_uname(struct utsname * name) { static int sys_signal(uint32_t signum, uintptr_t handler) { if (signum > NUMSIGNALS) { - return -1; + return -EINVAL; } uintptr_t old = current_process->signals.functions[signum]; current_process->signals.functions[signum] = handler; @@ -430,7 +441,7 @@ static void inspect_memory (uintptr_t vaddr) { static int sys_reboot(void) { debug_print(NOTICE, "[kernel] Reboot requested from process %d by user #%d", current_process->id, current_process->user); if (current_process->user != USER_ROOT_UID) { - return -1; + return -EPERM; } else { debug_print(NOTICE, "[kernel] Good bye!"); /* Goodbye, cruel world */ @@ -452,7 +463,7 @@ static int sys_chdir(char * newdir) { if (chd) { if ((chd->flags & FS_DIRECTORY) == 0) { close_fs(chd); - return -1; + return -ENOTDIR; } close_fs(chd); free(current_process->wd_name); @@ -460,7 +471,7 @@ static int sys_chdir(char * newdir) { memcpy(current_process->wd_name, path, strlen(path) + 1); return 0; } else { - return -1; + return -ENOENT; } } @@ -478,13 +489,13 @@ static int sys_sethostname(char * new_hostname) { PTR_VALIDATE(new_hostname); size_t len = strlen(new_hostname) + 1; if (len > 256) { - return 1; + return -ENAMETOOLONG; } hostname_len = len; memcpy(hostname, new_hostname, hostname_len); return 0; } else { - return 1; + return -EPERM; } } @@ -548,7 +559,7 @@ static int sys_sysfunc(int fn, char ** args) { PTR_VALIDATE(args[0]); fs_node_t * file = kopen((char *)args[0], 0); if (!file) { - return -1; + return -EINVAL; } size_t length = file->length; uint8_t * buffer = malloc(length); @@ -572,7 +583,7 @@ static int sys_sysfunc(int fn, char ** args) { fs_node_t * tty = FD_ENTRY(0); return create_kernel_tasklet(debug_hook, "[kttydebug]", tty); } else { - return -1; + return -EINVAL; } case 8: debug_print(NOTICE, "Loading module %s.", args[0]); @@ -698,7 +709,7 @@ static int sys_sysfunc(int fn, char ** args) { debug_print(ERROR, "Bad system function %d", fn); break; } - return -1; /* Bad system function or access failure */ + return -EINVAL; /* Bad system function or access failure */ } static int sys_sleepabs(unsigned long seconds, unsigned long subseconds) { @@ -736,8 +747,8 @@ static int sys_fork(void) { } static int sys_clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) { - if (!new_stack || !PTR_INRANGE(new_stack)) return -1; - if (!thread_func || !PTR_INRANGE(thread_func)) return -1; + if (!new_stack || !PTR_INRANGE(new_stack)) return -EINVAL; + if (!thread_func || !PTR_INRANGE(thread_func)) return -EINVAL; return (int)clone(new_stack, thread_func, arg); } @@ -767,10 +778,10 @@ static int sys_gettimeofday(struct timeval * tv, void * tz) { static int sys_openpty(int * master, int * slave, char * name, void * _ign0, void * size) { /* We require a place to put these when we are done. */ - if (!master || !slave) return -1; - if (master && !PTR_INRANGE(master)) return -1; - if (slave && !PTR_INRANGE(slave)) return -1; - if (size && !PTR_INRANGE(size)) return -1; + if (!master || !slave) return -EINVAL; + if (master && !PTR_INRANGE(master)) return -EINVAL; + if (slave && !PTR_INRANGE(slave)) return -EINVAL; + if (size && !PTR_INRANGE(size)) return -EINVAL; /* Create a new pseudo terminal */ fs_node_t * fs_master; @@ -854,7 +865,7 @@ static int sys_lstat(char * file, uintptr_t st) { static int sys_fswait(int c, int fds[]) { PTR_VALIDATE(fds); for (int i = 0; i < c; ++i) { - if (!FD_CHECK(fds[i])) return -1; + if (!FD_CHECK(fds[i])) return -EBADF; } fs_node_t ** nodes = malloc(sizeof(fs_node_t *)*(c+1)); for (int i = 0; i < c; ++i) { @@ -870,7 +881,7 @@ static int sys_fswait(int c, int fds[]) { static int sys_fswait_timeout(int c, int fds[], int timeout) { PTR_VALIDATE(fds); for (int i = 0; i < c; ++i) { - if (!FD_CHECK(fds[i])) return -1; + if (!FD_CHECK(fds[i])) return -EBADF; } fs_node_t ** nodes = malloc(sizeof(fs_node_t *)*(c+1)); for (int i = 0; i < c; ++i) { diff --git a/libc/dirent/dir.c b/libc/dirent/dir.c index fc04442e..f6c4e2f6 100644 --- a/libc/dirent/dir.c +++ b/libc/dirent/dir.c @@ -2,11 +2,13 @@ #include #include #include +#include #include DIR * opendir (const char * dirname) { int fd = open(dirname, O_RDONLY); - if (fd == -1) { + if (fd < 0) { + errno = -fd; return NULL; } @@ -20,7 +22,7 @@ int closedir (DIR * dir) { if (dir && (dir->fd != -1)) { return close(dir->fd); } else { - return -1; + return -EBADF; } } @@ -28,7 +30,14 @@ struct dirent * readdir (DIR * dirp) { static struct dirent ent; int ret = syscall_readdir(dirp->fd, ++dirp->cur_entry, &ent); - if (ret != 0) { + if (ret < 0) { + errno = -ret; + memset(&ent, 0, sizeof(struct dirent)); + return NULL; + } + + if (ret == 0) { + /* end of directory */ memset(&ent, 0, sizeof(struct dirent)); return NULL; } diff --git a/libc/pthread/pthread.c b/libc/pthread/pthread.c index 765195ef..419f5816 100644 --- a/libc/pthread/pthread.c +++ b/libc/pthread/pthread.c @@ -7,14 +7,15 @@ #include #include #include +#include #define PTHREAD_STACK_SIZE 0x100000 int clone(uintptr_t a,uintptr_t b,void* c) { - return syscall_clone(a,b,c); + __sets_errno(syscall_clone(a,b,c)); } int gettid() { - return syscall_gettid(); + return syscall_gettid(); /* never fails */ } int pthread_create(pthread_t * thread, pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) { @@ -26,7 +27,7 @@ int pthread_create(pthread_t * thread, pthread_attr_t * attr, void *(*start_rout } int pthread_kill(pthread_t thread, int sig) { - return kill(thread.id, sig); + __sets_errno(kill(thread.id, sig)); } void pthread_exit(void * value) { diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index 1665dbca..4f6e7d2a 100644 --- a/libc/stdio/stdio.c +++ b/libc/stdio/stdio.c @@ -4,6 +4,7 @@ #include #include #include +#include #include <_xlog.h> @@ -179,6 +180,7 @@ FILE * fopen(const char *path, const char *mode) { int fd = syscall_open(path, flags, mask); if (fd < 0) { + errno = -fd; return NULL; } @@ -212,6 +214,7 @@ FILE * freopen(const char *path, const char *mode, FILE * stream) { stream->ungetc = -1; stream->eof = 0; if (fd < 0) { + errno = -fd; return NULL; } } @@ -265,6 +268,7 @@ int fseek(FILE * stream, long offset, int whence) { int resp = syscall_lseek(stream->fd,offset,whence); if (resp < 0) { + errno = -resp; return -1; } return 0; @@ -277,7 +281,12 @@ long ftell(FILE * stream) { stream->available = 0; stream->ungetc = -1; stream->eof = 0; - return syscall_lseek(stream->fd, 0, SEEK_CUR); + long resp = syscall_lseek(stream->fd, 0, SEEK_CUR); + if (resp < 0) { + errno = -resp; + return -1; + } + return resp; } size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream) { @@ -300,6 +309,7 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE * stream) { for (size_t i = 0; i < nmemb; ++i) { int r = syscall_write(stream->fd, tracking, size); if (r < 0) { + errno = -r; _XLOG("write error in fwrite"); return -1; } diff --git a/libc/unistd/chdir.c b/libc/unistd/chdir.c index a1e37882..f1dbe949 100644 --- a/libc/unistd/chdir.c +++ b/libc/unistd/chdir.c @@ -1,9 +1,10 @@ #include #include +#include DEFN_SYSCALL1(chdir, 28, char *); int chdir(const char *path) { - return syscall_chdir((char*)path); + __sets_errno(syscall_chdir((char*)path)); } diff --git a/libc/unistd/fstat.c b/libc/unistd/fstat.c index f8b2f95d..5a2b27cd 100644 --- a/libc/unistd/fstat.c +++ b/libc/unistd/fstat.c @@ -1,10 +1,11 @@ #include #include #include +#include +#include -DEFN_SYSCALL2(fstat, 15, int, void *); +DEFN_SYSCALL2(fstat, SYS_STAT, int, void *); int fstat(int file, struct stat *st) { - syscall_fstat(file, st); - return 0; + __sets_errno(syscall_fstat(file, st)); } diff --git a/libc/unistd/open.c b/libc/unistd/open.c index 1812e373..615da433 100644 --- a/libc/unistd/open.c +++ b/libc/unistd/open.c @@ -17,6 +17,7 @@ int open(const char *name, int flags, ...) { result = syscall_open(name, flags, mode); if (result == -1) { + /* Not sure this is necessary */ if (flags & O_CREAT) { errno = EACCES; } else { @@ -24,6 +25,7 @@ int open(const char *name, int flags, ...) { } } else if (result < 0) { errno = -result; + result = -1; } return result; }