Explorar el Código

feat(gblibc): set errno for syscalls

greatbridf hace 2 años
padre
commit
0c919f05e7

+ 1 - 0
gblibc/include/string.h

@@ -30,6 +30,7 @@ char* strrchr(const char* str, int character);
 char* strchrnul(const char* str, int character);
 size_t strcspn(const char* str1, const char* str2);
 char* strstr(const char* str1, const char* str2);
+char* strpbrk(const char* str1, const char* str2);
 
 char* strcpy(char* dst, const char* src);
 char* strncpy(char* dst, const char* src, size_t n);

+ 7 - 1
gblibc/src/dirent.c

@@ -1,3 +1,4 @@
+#include <errno.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <string.h>
@@ -62,8 +63,13 @@ struct dirent* readdir(DIR* dirp)
         sizeof(dirp->buffer)
     );
 
-    if (dirp->blen <= 0)
+    if (dirp->blen <= 0) {
+        if (dirp->blen < 0) {
+            errno = -dirp->blen;
+            dirp->blen = 0;
+        }
         return NULL;
+    }
 
 fill:
     dirp->bpos = fill_dirent(&dirp->dent, dirp->buffer, dirp->bpos);

+ 7 - 1
gblibc/src/fcntl.c

@@ -1,7 +1,13 @@
+#include <errno.h>
 #include <fcntl.h>
 #include <syscall.h>
 
 int open(const char* filename, int flags, ...)
 {
-    return syscall2(SYS_open, (uint32_t)filename, flags);
+    int ret = syscall2(SYS_open, (uint32_t)filename, flags);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }

+ 13 - 4
gblibc/src/stdio.c

@@ -368,10 +368,19 @@ int sprintf(char* buf, const char* fmt, ...)
 
 int puts(const char* str)
 {
-    int len = strlen(str);
-    write(STDOUT_FILENO, str, len);
-    write(STDOUT_FILENO, "\n", 1);
-    return len + 1;
+    int len = 0;
+
+    int ret = write(STDOUT_FILENO, str, strlen(str));
+    if (ret < 0)
+        return EOF;
+    len += ret;
+
+    ret = write(STDOUT_FILENO, "\n", 1);
+    if (ret < 0)
+        return EOF;
+    len += ret;
+
+    return len;
 }
 
 char* gets(char* buf)

+ 8 - 0
gblibc/src/string.c

@@ -205,6 +205,14 @@ char* strstr(const char* str1, const char* str2)
     return NULL;
 }
 
+char* strpbrk(const char* str1, const char* str2)
+{
+    size_t n = strcspn(str1, str2);
+    if (str1[n])
+        return (char*)str1 + n;
+    return NULL;
+}
+
 char* strerror(int errnum)
 {
     switch (errnum) {

+ 99 - 16
gblibc/src/unistd.c

@@ -1,36 +1,68 @@
+#include <errno.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <syscall.h>
 
 ssize_t read(int fd, void* buf, size_t count)
 {
-    return syscall3(SYS_read, fd, (uint32_t)buf, count);
+    ssize_t ret = syscall3(SYS_read, fd, (uint32_t)buf, count);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 ssize_t write(int fd, const void* buf, size_t count)
 {
-    return syscall3(SYS_write, fd, (uint32_t)buf, count);
+    ssize_t ret = syscall3(SYS_write, fd, (uint32_t)buf, count);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 int dup(int oldfd)
 {
-    return syscall1(SYS_dup, oldfd);
+    int ret = syscall1(SYS_dup, oldfd);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 int dup2(int oldfd, int newfd)
 {
-    return syscall2(SYS_dup2, oldfd, newfd);
+    int ret = syscall2(SYS_dup2, oldfd, newfd);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 int pipe(int pipefd[2])
 {
-    return syscall1(SYS_pipe, (uint32_t)pipefd);
+    int ret = syscall1(SYS_pipe, (uint32_t)pipefd);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 int close(int fd)
 {
-    return syscall1(SYS_close, fd);
+    int ret = syscall1(SYS_close, fd);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 _Noreturn void _exit(int code)
@@ -42,12 +74,22 @@ _Noreturn void _exit(int code)
 
 pid_t fork(void)
 {
-    return syscall0(SYS_fork);
+    pid_t ret = syscall0(SYS_fork);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 int execve(const char* pathname, char* const argv[], char* const envp[])
 {
-    return syscall3(SYS_execve, (uint32_t)pathname, (uint32_t)argv, (uint32_t)envp);
+    int ret = syscall3(SYS_execve, (uint32_t)pathname, (uint32_t)argv, (uint32_t)envp);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 unsigned int sleep(unsigned int seconds)
@@ -57,37 +99,72 @@ unsigned int sleep(unsigned int seconds)
 
 int chdir(const char* path)
 {
-    return syscall1(SYS_chdir, (uint32_t)path);
+    int ret = syscall1(SYS_chdir, (uint32_t)path);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 char* getcwd(char* buf, size_t bufsize)
 {
-    return (char*)syscall2(SYS_getcwd, (uint32_t)buf, bufsize);
+    int ret = syscall2(SYS_getcwd, (uint32_t)buf, bufsize);
+    if (ret < 0) {
+        errno = -ret;
+        return NULL;
+    }
+    return buf;
 }
 
 pid_t getpid(void)
 {
-    return syscall0(SYS_getpid);
+    pid_t ret = syscall0(SYS_getpid);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 pid_t getppid(void)
 {
-    return syscall0(SYS_getppid);
+    pid_t ret = syscall0(SYS_getppid);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 int setpgid(pid_t pid, pid_t pgid)
 {
-    return syscall2(SYS_setpgid, pid, pgid);
+    int ret = syscall2(SYS_setpgid, pid, pgid);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 pid_t setsid(void)
 {
-    return syscall0(SYS_setsid);
+    pid_t ret = syscall0(SYS_setsid);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 pid_t getsid(pid_t pid)
 {
-    return syscall1(SYS_getsid, pid);
+    pid_t ret = syscall1(SYS_getsid, pid);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }
 
 pid_t tcgetpgrp(int fd)
@@ -103,7 +180,7 @@ int tcsetpgrp(int fd, pid_t pgrp)
 
 int ioctl(int fd, unsigned long request, ...)
 {
-    int ret = -1;
+    int ret = -EINVAL;
 
     va_list args;
     va_start(args, request);
@@ -120,5 +197,11 @@ int ioctl(int fd, unsigned long request, ...)
     }
 
     va_end(args);
+
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+
     return ret;
 }

+ 7 - 1
gblibc/src/wait.c

@@ -1,7 +1,13 @@
+#include <errno.h>
 #include <sys/wait.h>
 #include <syscall.h>
 
 pid_t wait(int* code)
 {
-    return syscall1(SYS_wait, (uint32_t)code);
+    int ret = syscall1(SYS_wait, (uint32_t)code);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
 }

+ 1 - 1
src/kernel/syscall.cpp

@@ -306,7 +306,7 @@ int _syscall_getcwd(interrupt_stack* data)
     strncpy(buf, current_process->pwd.c_str(), bufsize);
     buf[bufsize - 1] = 0;
 
-    return (uint32_t)buf;
+    return 0;
 }
 
 int _syscall_setsid(interrupt_stack*)