From 9160fd0d47483a87a16664e26f9128af569665cf Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 31 Oct 2018 10:14:56 +0100 Subject: [PATCH] More LibC portability work while trying to get figlet building. --- Kernel/Syscall.cpp | 2 ++ Kernel/Syscall.h | 1 + Kernel/Task.cpp | 11 +++++++++++ Kernel/Task.h | 1 + LibC/alloca.h | 4 ++++ LibC/ctype.h | 33 +++++++++++++++++++++++++++++++- LibC/stdio.cpp | 16 ++++++++++++++++ LibC/stdlib.h | 1 + LibC/string.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ LibC/string.h | 5 +++++ LibC/unistd.cpp | 8 +++++++- LibC/unistd.h | 1 + 12 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 LibC/alloca.h diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index ba2021c9a2..67b0ff992c 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -63,6 +63,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) return current->sys$get_dir_entries((int)arg1, (void*)arg2, (size_t)arg3); case Syscall::PosixLstat: return current->sys$lstat((const char*)arg1, (Unix::stat*)arg2); + case Syscall::PosixStat: + return current->sys$stat((const char*)arg1, (Unix::stat*)arg2); case Syscall::PosixGetcwd: return current->sys$getcwd((char*)arg1, (size_t)arg2); case Syscall::PosixOpen: diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index db6c2b56b5..9f0d8de243 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -38,6 +38,7 @@ enum Function { PosixReadlink = 0x2006, PosixWrite = 0x2007, PosixTtynameR = 0x2008, + PosixStat = 0x2009, }; void initialize(); diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 0512289cfe..07f9f8cc77 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -851,6 +851,17 @@ int Task::sys$lstat(const char* path, Unix::stat* statbuf) return 0; } +int Task::sys$stat(const char* path, Unix::stat* statbuf) +{ + VALIDATE_USER_BUFFER(statbuf, sizeof(Unix::stat)); + int error; + auto handle = VirtualFileSystem::the().open(move(path), error, 0, cwdInode()); + if (!handle) + return error; + handle->stat(statbuf); + return 0; +} + int Task::sys$readlink(const char* path, char* buffer, size_t size) { VALIDATE_USER_BUFFER(path, strlen(path)); diff --git a/Kernel/Task.h b/Kernel/Task.h index 60d7d74767..c86b501792 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -93,6 +93,7 @@ public: ssize_t sys$read(int fd, void* outbuf, size_t nread); ssize_t sys$write(int fd, const void*, size_t); int sys$lstat(const char*, Unix::stat*); + int sys$stat(const char*, Unix::stat*); int sys$seek(int fd, int offset); int sys$kill(pid_t pid, int sig); int sys$geterror() { return m_error; } diff --git a/LibC/alloca.h b/LibC/alloca.h new file mode 100644 index 0000000000..0813019304 --- /dev/null +++ b/LibC/alloca.h @@ -0,0 +1,4 @@ +#pragma once + +#define alloca __builtin_alloca + diff --git a/LibC/ctype.h b/LibC/ctype.h index a69bbfdea9..961881ceca 100644 --- a/LibC/ctype.h +++ b/LibC/ctype.h @@ -1,4 +1,35 @@ #pragma once -#define isascii(c) (((c) & ~0x7f) == 0) +inline int isascii(int ch) +{ + return (ch & ~0x7f) == 0; +} +inline int isspace(int ch) +{ + return ch == ' ' || ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' == '\v'; +} + +inline int islower(int c) +{ + return c >= 'a' && c <= 'z'; +} + +inline int isupper(int c) +{ + return c >= 'A' && c <= 'Z'; +} + +inline int tolower(int c) +{ + if (isupper(c)) + return c | 0x20; + return c; +} + +inline int toupper(int c) +{ + if (islower(c)) + return c & ~0x20; + return c; +} diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp index af36176079..09f3a463b6 100644 --- a/LibC/stdio.cpp +++ b/LibC/stdio.cpp @@ -20,6 +20,22 @@ static void sys_putch(char*&, char ch) putchar(ch); } +static FILE* __current_stream = nullptr; +static void stream_putch(char*&, char ch) +{ + write(__current_stream->fd, &ch, 1); +} + +int fprintf(FILE* fp, const char* fmt, ...) +{ + __current_stream = fp; + va_list ap; + va_start(ap, fmt); + int ret = printfInternal(stream_putch, nullptr, fmt, ap); + va_end(ap); + return ret; +} + int printf(const char* fmt, ...) { va_list ap; diff --git a/LibC/stdlib.h b/LibC/stdlib.h index 0f88c6edf4..4b6b8c7765 100644 --- a/LibC/stdlib.h +++ b/LibC/stdlib.h @@ -10,6 +10,7 @@ void free(void*); void* calloc(size_t nmemb, size_t); void* realloc(void *ptr, size_t); + void exit(int status); void abort(); diff --git a/LibC/string.cpp b/LibC/string.cpp index a48e1c2a4f..a7c8b2a5ea 100644 --- a/LibC/string.cpp +++ b/LibC/string.cpp @@ -40,6 +40,53 @@ void memcpy(void* dest, const void* src, size_t n) *(bdest++) = *(bsrc++); } +char* strcpy(char* dest, const char *src) +{ + char* originalDest = dest; + while ((*dest++ = *src++) != '\0'); + return originalDest; +} + +char* strncpy(char* dest, const char* src, size_t n) +{ + size_t i; + for (i = 0; i < n && src[i] != '\0'; ++i) + dest[i] = src[i]; + for ( ; i < n; ++i) + dest[i] = '\0'; + return dest; +} + +char* strchr(const char* str, int c) +{ + if (!str) + return nullptr; + char* ptr = (char*)str; + while (*ptr != c) + ++ptr; + return ptr; +} + +char* strcat(char *dest, const char *src) +{ + size_t destLength = strlen(dest); + size_t i; + for (i = 0 ; src[i] != '\0' ; i++) + dest[destLength + i] = src[i]; + dest[destLength + i] = '\0'; + return dest; +} + +char* strncat(char *dest, const char *src, size_t n) +{ + size_t destLength = strlen(dest); + size_t i; + for (i = 0 ; i < n && src[i] != '\0' ; i++) + dest[destLength + i] = src[i]; + dest[destLength + i] = '\0'; + return dest; +} + const char* strerror(int errnum) { switch (errnum) { diff --git a/LibC/string.h b/LibC/string.h index 42e3678293..8d7f2a3f31 100644 --- a/LibC/string.h +++ b/LibC/string.h @@ -9,6 +9,11 @@ size_t strlen(const char*); int strcmp(const char*, const char*); int memcmp(const void*, const void*, size_t); void memcpy(void*, const void*, size_t); +char* strcpy(char* dest, const char* src); +char* strncpy(char* dest, const char* src, size_t); +char* strchr(const char*, int c); +char* strcat(char *dest, const char *src); +char* strncat(char *dest, const char *src, size_t); const char* strerror(int errnum); __END_DECLS diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index 271c4347fa..65e959edb3 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -64,12 +64,18 @@ pid_t waitpid(pid_t waitee, int* wstatus, int options) __RETURN_WITH_ERRNO(rc, rc, -1); } -int lstat(const char* path, stat* statbuf) +int lstat(const char* path, struct stat* statbuf) { int rc = Syscall::invoke(Syscall::PosixLstat, (dword)path, (dword)statbuf); __RETURN_WITH_ERRNO(rc, rc, -1); } +int stat(const char* path, struct stat* statbuf) +{ + int rc = Syscall::invoke(Syscall::PosixStat, (dword)path, (dword)statbuf); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + int chdir(const char* path) { int rc = Syscall::invoke(Syscall::PosixChdir, (dword)path); diff --git a/LibC/unistd.h b/LibC/unistd.h index b0397c6aa9..97b3f0df42 100644 --- a/LibC/unistd.h +++ b/LibC/unistd.h @@ -16,6 +16,7 @@ pid_t waitpid(pid_t, int* wstatus, int options); int chdir(const char* path); char* getcwd(char* buffer, size_t size); int lstat(const char* path, struct stat* statbuf); +int stat(const char* path, struct stat* statbuf); int sleep(unsigned seconds); int gethostname(char*, size_t); ssize_t readlink(const char* path, char* buffer, size_t);