diff options
author | Anton Kling <anton@kling.gg> | 2024-04-11 17:22:00 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-04-11 17:23:39 +0200 |
commit | ca082f686fd2dc7ee6f0284421f6212d6d4acee8 (patch) | |
tree | 493b1047661174816f0d1d300952e40e2846b24b /userland | |
parent | e25a47fcc4db09ab9b845a691297da67243e6049 (diff) |
bug fixes
Diffstat (limited to 'userland')
-rw-r--r-- | userland/libc/Makefile | 2 | ||||
-rw-r--r-- | userland/libc/assert.c | 6 | ||||
-rw-r--r-- | userland/libc/dirent/scandir.c | 15 | ||||
-rw-r--r-- | userland/libc/include/tb/sb.h | 23 | ||||
-rw-r--r-- | userland/libc/include/tb/sv.h | 32 | ||||
-rw-r--r-- | userland/libc/malloc/malloc.c | 56 | ||||
-rw-r--r-- | userland/libc/stdio/vfprintf.c | 3 | ||||
-rw-r--r-- | userland/libc/stdlib/realpath.c | 104 | ||||
-rw-r--r-- | userland/libc/tb/sb.c | 69 | ||||
-rw-r--r-- | userland/libc/tb/sv.c | 147 | ||||
-rw-r--r-- | userland/libgui/libgui.c | 14 | ||||
-rw-r--r-- | userland/terminal/term.c | 23 |
12 files changed, 408 insertions, 86 deletions
diff --git a/userland/libc/Makefile b/userland/libc/Makefile index b1291fa..29b37d9 100644 --- a/userland/libc/Makefile +++ b/userland/libc/Makefile @@ -3,7 +3,7 @@ AR="i686-sb-ar" AS="i686-sb-as" #CFLAGS = -ggdb -ffreestanding -O2 -Wall -Wextra -pedantic -Wimplicit-fallthrough -I./include/ -static -I../../include/ -Wno-int-conversion -Wno-unused-parameter -Wno-return-type CFLAGS = -ggdb -ffreestanding -Wall -Wextra -pedantic -Wimplicit-fallthrough -I./include/ -static -I../../include/ -Wno-int-conversion -Wno-unused-parameter -Wno-return-type -OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o sys/mman/munmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o unistd/ftruncate.o sys/socket/recvfrom.o sys/socket/sendto.o signal/kill.o signal/sigaction.o unistd/chdir.o unistd/getcwd.o stdio/getdelim.o stdio/getline.o unistd/isatty.o sys/socket/listen.o stdlib/realpath.o systemcall.o sys/random/randomfill.o fcntl/open.o unistd/write.o unistd/pwrite.o fcntl/open_process.o +OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o sys/mman/munmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o unistd/ftruncate.o sys/socket/recvfrom.o sys/socket/sendto.o signal/kill.o signal/sigaction.o unistd/chdir.o unistd/getcwd.o stdio/getdelim.o stdio/getline.o unistd/isatty.o sys/socket/listen.o stdlib/realpath.o systemcall.o sys/random/randomfill.o fcntl/open.o unistd/write.o unistd/pwrite.o fcntl/open_process.o tb/sb.o tb/sv.o all: libc.a %.o: %.c diff --git a/userland/libc/assert.c b/userland/libc/assert.c index 4082f64..6a3bd6e 100644 --- a/userland/libc/assert.c +++ b/userland/libc/assert.c @@ -2,8 +2,10 @@ #include <stdio.h> #include <stdlib.h> +int debug_printf(const char *fmt, ...); + void aFailed(char *f, int l) { - printf("Assert failed\n"); - printf("%s : %d\n", f, l); + debug_printf("Assert failed\n"); + debug_printf("%s : %d\n", f, l); exit(1); } diff --git a/userland/libc/dirent/scandir.c b/userland/libc/dirent/scandir.c index 945bc1f..564cbc8 100644 --- a/userland/libc/dirent/scandir.c +++ b/userland/libc/dirent/scandir.c @@ -2,11 +2,6 @@ #include <stdlib.h> #include <string.h> -int nop_sel(const struct dirent *unused) { - (void)unused; - return 1; -} - int nop_compar(const struct dirent **d1, const struct dirent **d2) { *d2 = *d1; return 0; @@ -15,9 +10,6 @@ int nop_compar(const struct dirent **d1, const struct dirent **d2) { int scandir(const char *dir, struct dirent ***namelist, int (*sel)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) { - if (!sel) - sel = nop_sel; - if (!compar) compar = nop_compar; @@ -28,8 +20,11 @@ int scandir(const char *dir, struct dirent ***namelist, struct dirent *e; int rc = 0; for (; (e = readdir(d));) { - if (!sel(e)) - continue; + if (sel) { + if (!sel(e)) { + continue; + } + } struct dirent *p = malloc(sizeof(struct dirent)); memcpy(p, e, sizeof(struct dirent)); list = realloc(list, (rc + 1) * sizeof(struct dirent *)); diff --git a/userland/libc/include/tb/sb.h b/userland/libc/include/tb/sb.h new file mode 100644 index 0000000..5675985 --- /dev/null +++ b/userland/libc/include/tb/sb.h @@ -0,0 +1,23 @@ +#ifndef SB_H +#define SB_H +#include "sv.h" +#include <stddef.h> + +struct sb { + char *string; + size_t length; + size_t capacity; +}; + +struct sv; + +void sb_init(struct sb *ctx); +void sb_free(struct sb *ctx); +void sb_reset(struct sb *ctx); +int sb_isempty(const struct sb *ctx); +void sb_append_char(struct sb *ctx, char c); +int sb_delete_right(struct sb *ctx, int n); +void sb_append(struct sb *ctx, const char *s); +void sb_append_sv(struct sb *ctx, struct sv sv); +void sb_prepend_sv(struct sb *ctx, struct sv sv); +#endif diff --git a/userland/libc/include/tb/sv.h b/userland/libc/include/tb/sv.h new file mode 100644 index 0000000..6e81b0b --- /dev/null +++ b/userland/libc/include/tb/sv.h @@ -0,0 +1,32 @@ +#ifndef SV_H +#define SV_H +#include "sb.h" +#include <stddef.h> + +#define SB_TO_SV(_sb) \ + (struct sv) { \ + .s = (_sb).string, .length = (_sb).length \ + } + +#define C_TO_SV(_c_string) \ + ((struct sv){.length = strlen(_c_string), .s = (_c_string)}) + +struct sv { + const char *s; + size_t length; +}; + +char *SV_TO_C(struct sv s); +struct sv sv_split_delim(const struct sv input, struct sv *rest, char delim); +struct sv sv_end_split_delim(const struct sv input, struct sv *rest, + char delim); +struct sv sv_split_space(const struct sv input, struct sv *rest); +int sv_isempty(struct sv s); +char sv_peek(struct sv s); +int sv_eq(struct sv a, struct sv b); +int sv_partial_eq(struct sv a, struct sv b); +struct sv sv_trim_left(struct sv s, size_t n); +struct sv sv_clone(struct sv s); +struct sv sv_clone_from_c(const char *s); +char *sv_copy_to_c(struct sv s, char *out, size_t buffer_length); +#endif diff --git a/userland/libc/malloc/malloc.c b/userland/libc/malloc/malloc.c index d1bc5ca..1c992ef 100644 --- a/userland/libc/malloc/malloc.c +++ b/userland/libc/malloc/malloc.c @@ -1,5 +1,6 @@ #include <assert.h> #include <math.h> +#include <stdarg.h> #include <stddef.h> #include <stdlib.h> #include <typedefs.h> @@ -23,6 +24,26 @@ MallocHeader *head = NULL; MallocHeader *final = NULL; u32 total_heap_size = 0; +// printf without using malloc() so that it can be used internally by +// malloc() such that it does not have a stack overflow. +int debug_vprintf(const char *fmt, va_list ap) { + const char buffer[4096]; + int rc = vsnprintf(buffer, 4096, fmt, ap); + if (0 > rc) { + return -1; + } + write(1, buffer, rc); + return rc; +} + +int debug_printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int rc = debug_vprintf(fmt, ap); + va_end(ap); + return rc; +} + int init_heap(void) { head = (MallocHeader *)sbrk(NEW_ALLOC_SIZE); total_heap_size += NEW_ALLOC_SIZE - sizeof(MallocHeader); @@ -63,8 +84,10 @@ MallocHeader *next_header(MallocHeader *a) { assert(a->magic == 0xdde51ab9410268b1); if (a->n) { if (a->n->magic != 0xdde51ab9410268b1) { - printf("Real magic value is: %x\n", a->n->magic); - printf("location: %x\n", &(a->n->magic)); + debug_printf("a->n: %x\n", a->n); + debug_printf("Real magic value is: %x\n", a->n->magic); + debug_printf("size: %x\n", a->n->size); + debug_printf("location: %x\n", &(a->n->magic)); assert(0); } return a->n; @@ -74,7 +97,7 @@ MallocHeader *next_header(MallocHeader *a) { MallocHeader *next_close_header(MallocHeader *a) { if (!a) { - printf("next close header fail\n"); + debug_printf("next close header fail\n"); for (;;) ; } @@ -122,13 +145,16 @@ void merge_headers(MallocHeader *b) { b->size += n->size; b->flags |= n->flags & IS_FINAL; b->n = n->n; + assert(b->magic == 0xdde51ab9410268b1); + if (b->n) { + assert(b->n->magic == 0xdde51ab9410268b1); + } if (n == final) { final = b; } } -void *malloc(size_t s) { - s += 0x1000; +void *int_malloc(size_t s, int recursion) { size_t n = s; MallocHeader *free_entry = find_free_entry(s); if (!free_entry) { @@ -136,7 +162,11 @@ void *malloc(size_t s) { assert(0); return NULL; } - return malloc(s); + if (recursion) { + debug_printf("RECURSION IN MALLOC :(\n"); + assert(0); + } + return int_malloc(s, 1); } void *rc = (void *)(free_entry + 1); @@ -158,12 +188,14 @@ void *malloc(size_t s) { free_entry->flags = 0; free_entry->n = new_entry; free_entry->magic = 0xdde51ab9410268b1; - for (int i = 0; i < s; i++) { - *(char *)rc = 'A'; - } + randomfill(rc, s); return rc; } +void *malloc(size_t s) { + return int_malloc(s, 0); +} + size_t get_mem_size(void *ptr) { if (!ptr) { return 0; @@ -216,13 +248,9 @@ void free(void *p) { if (!p) { return; } - // FIXME: This assumes that p is at the start of a allocated area. - // Could this be avoided in a simple way? MallocHeader *h = (MallocHeader *)((uintptr_t)p - sizeof(MallocHeader)); assert(h->magic == 0xdde51ab9410268b1); - if (h->flags & IS_FREE) { - return; - } + assert(!(h->flags & IS_FREE)); h->flags |= IS_FREE; merge_headers(h); diff --git a/userland/libc/stdio/vfprintf.c b/userland/libc/stdio/vfprintf.c index c3a8de7..65a2c27 100644 --- a/userland/libc/stdio/vfprintf.c +++ b/userland/libc/stdio/vfprintf.c @@ -93,9 +93,8 @@ int print_string(FILE *f, const char *s, int *rc, int prefix, int right_padding, break; bl--; } - int r; + int r = 0; FILE_WRITE(f, (const unsigned char *)s, 1, &r); - assert(r != 0); } if (right_padding) { assert(-1 == precision); // FIXME: Is this correct? diff --git a/userland/libc/stdlib/realpath.c b/userland/libc/stdlib/realpath.c index 5589032..d9e2387 100644 --- a/userland/libc/stdlib/realpath.c +++ b/userland/libc/stdlib/realpath.c @@ -1,62 +1,68 @@ #include <assert.h> +#include <errno.h> #include <stdlib.h> #include <string.h> +#include <tb/sb.h> +#include <tb/sv.h> #include <unistd.h> -// FIXME: This is nowhere near complete char *realpath(const char *filename, char *resolvedname) { - assert(resolvedname); - // FIXME: This really should have bounds checking + if (!filename) { + return -EINVAL; + } + char cwd[256]; getcwd(cwd, 256); - strcat(cwd, filename); - const char *path = cwd; - char *result = resolvedname; - // It has to be a absolute path - if ('/' != *path) - return 0; - const char *result_start = result; - int start_directory = 0; - int should_insert_slash = 0; - for (; *path; path++) { - if (start_directory) { - start_directory = 0; - if ('/' == *path) { - path++; - } else if (0 == memcmp(path, "./", 2) || 0 == memcmp(path, ".\0", 2)) { - path++; - } else if (0 == memcmp(path, "../", 3) || 0 == memcmp(path, "..\0", 3)) { - path += 2; - if (result_start + 2 > result) { - // The path is probably something like "/.." or - // "/../foo". A "/.." should become a "/" - // Therefore it skips going back to the parent - if (*path == '/') { - if (result_start == result) - return 0; - result--; - } - } else { - if ('/' != *path) { - should_insert_slash = 1; - } - result--; - result--; - for (; result_start <= result && '/' != *result; result--) - ; - } + strcat(cwd, filename); // FIXME: bounds check + + struct sb string; + sb_init(&string); + + struct sv path = C_TO_SV(cwd); + + int ignore = 0; + int last_was_dotdot = 0; + + int was_root = 0; + for (;;) { + ignore = 0; + was_root = 0; + struct sv dir = sv_end_split_delim(path, &path, '/'); + + if (sv_partial_eq(dir, C_TO_SV("/"))) { + was_root = 1; + } + + if (sv_eq(dir, C_TO_SV("/"))) { + ignore = 1; + } + + if (sv_eq(dir, C_TO_SV("/."))) { + ignore = 1; + } + + if (sv_eq(dir, C_TO_SV("/.."))) { + last_was_dotdot = 1; + ignore = 1; + } else { + if (last_was_dotdot) { + ignore = 1; } + last_was_dotdot = 0; + } + + if (!ignore && !last_was_dotdot) { + sb_prepend_sv(&string, dir); } - start_directory = ('/' == *path); - if ('\0' == *path) + + if (sv_isempty(path)) { + if (was_root && ignore && sb_isempty(&string)) { + sb_prepend_sv(&string, C_TO_SV("/")); + } break; - *result = *path; - result++; - } - if (should_insert_slash) { - *result = '/'; - result++; + } } - *result = '\0'; - return 1; + char *result = sv_copy_to_c(SB_TO_SV(string), resolvedname, 256); + sb_free(&string); + return result; } diff --git a/userland/libc/tb/sb.c b/userland/libc/tb/sb.c new file mode 100644 index 0000000..0d0ec52 --- /dev/null +++ b/userland/libc/tb/sb.c @@ -0,0 +1,69 @@ +#include <tb/sb.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +void sb_init(struct sb *ctx) { + ctx->string = malloc(512); + ctx->length = 0; + ctx->capacity = 512; +} + +void sb_free(struct sb *ctx) { + ctx->length = 0; + ctx->capacity = 0; + free(ctx->string); + ctx->string = NULL; +} + +void sb_reset(struct sb *ctx) { + ctx->length = 0; +} + +int sb_isempty(const struct sb *ctx) { + return (0 == ctx->length); +} + +void sb_append_char(struct sb *ctx, char c) { + if (1 > ctx->capacity - ctx->length) { + ctx->capacity += 32; + ctx->string = realloc(ctx->string, ctx->capacity); + } + memcpy(ctx->string + ctx->length, &c, 1); + ctx->length++; +} + +int sb_delete_right(struct sb *ctx, int n) { + n = min(n, ctx->length); + ctx->length -= n; + return n; +} + +void sb_append(struct sb *ctx, const char *s) { + size_t l = strlen(s); + if (l > ctx->capacity - ctx->length) { + ctx->capacity += l; + ctx->string = realloc(ctx->string, ctx->capacity); + } + memcpy(ctx->string + ctx->length, s, l); + ctx->length += l; +} + +void sb_prepend_sv(struct sb *ctx, struct sv sv) { + if (sv.length > ctx->capacity - ctx->length) { + ctx->capacity += sv.length; + ctx->string = realloc(ctx->string, ctx->capacity); + } + memmove(ctx->string + sv.length, ctx->string, ctx->length); + memcpy(ctx->string, sv.s, sv.length); + ctx->length += sv.length; +} + +void sb_append_sv(struct sb *ctx, struct sv sv) { + if (sv.length > ctx->capacity - ctx->length) { + ctx->capacity += sv.length; + ctx->string = realloc(ctx->string, ctx->capacity); + } + memcpy(ctx->string + ctx->length, sv.s, sv.length); + ctx->length += sv.length; +} diff --git a/userland/libc/tb/sv.c b/userland/libc/tb/sv.c new file mode 100644 index 0000000..9bffce3 --- /dev/null +++ b/userland/libc/tb/sv.c @@ -0,0 +1,147 @@ +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include <tb/sv.h> + +char *SV_TO_C(struct sv s) { + char *c_string = malloc(s.length + 1); + memcpy(c_string, s.s, s.length); + c_string[s.length] = '\0'; + return c_string; +} + +struct sv sv_split_space(const struct sv input, struct sv *rest) { + struct sv r = { + .s = input.s, + }; + for (size_t i = 0; i < input.length; i++) { + if (isspace(input.s[i])) { + r.length = i; + if (rest) { + rest->s += i + 1; + rest->length -= (i + 1); + } + return r; + } + } + + if (rest) { + rest->s = NULL; + rest->length = 0; + } + return input; +} + +struct sv sv_end_split_delim(const struct sv input, struct sv *rest, + char delim) { + for (size_t i = input.length - 1; i > 0; i--) { + if (delim == input.s[i]) { + struct sv r = { + .s = (input.s + i), + .length = input.length - i, + }; + if (rest) { + rest->s = input.s; + rest->length = i; + } + return r; + } + } + + if (rest) { + rest->s = NULL; + rest->length = 0; + } + return input; +} + +struct sv sv_split_delim(const struct sv input, struct sv *rest, char delim) { + struct sv r = { + .s = input.s, + }; + for (size_t i = 0; i < input.length; i++) { + if (delim == input.s[i]) { + r.length = i; + if (rest) { + rest->s += i + 1; + rest->length -= (i + 1); + } + return r; + } + } + + if (rest) { + rest->s = NULL; + rest->length = 0; + } + return input; +} + +int sv_isempty(struct sv s) { + return (0 == s.length); +} + +char sv_peek(struct sv s) { + if (0 == s.length) { + return '\0'; + } + return s.s[0]; +} + +int sv_partial_eq(struct sv a, struct sv b) { + if (a.length < b.length) { + return 0; + } + for (size_t i = 0; i < b.length; i++) { + if (a.s[i] != b.s[i]) { + return 0; + } + } + return 1; +} + +int sv_eq(struct sv a, struct sv b) { + if (a.length != b.length) { + return 0; + } + for (size_t i = 0; i < a.length; i++) { + if (a.s[i] != b.s[i]) { + return 0; + } + } + return 1; +} + +struct sv sv_trim_left(struct sv s, size_t n) { + if (s.length < n) { + s.s += s.length; + s.length = 0; + return s; + } + s.s += n; + s.length -= n; + return s; +} + +struct sv sv_clone(struct sv s) { + struct sv new_sv; + new_sv.length = s.length; + char *new_string = malloc(s.length); + memcpy(new_string, s.s, s.length); + new_sv.s = new_string; + return new_sv; +} + +char *sv_copy_to_c(struct sv s, char *out, size_t buffer_length) { + int copy_len = min(s.length + 1, buffer_length); + if (!out) { + out = malloc(copy_len); + } + memcpy(out, s.s, copy_len - 1); + out[copy_len] = '\0'; + return out; +} + +struct sv sv_clone_from_c(const char *s) { + return sv_clone(C_TO_SV(s)); +} diff --git a/userland/libgui/libgui.c b/userland/libgui/libgui.c index 2a8361d..f7a8079 100644 --- a/userland/libgui/libgui.c +++ b/userland/libgui/libgui.c @@ -256,8 +256,15 @@ void GUI_EventLoop(GUI_Window *w, void (*event_handler)(WS_EVENT ev)) { } } +// This should really not be a constant. It is merely here so that each +// window can be given a sufficently large buffer such that buffers +// don't have to be resized if the window is resized. +#define MAX_WINDOW_SIZE (1920 * 1080) void GUI_Resize(GUI_Window *w, uint32_t sx, uint32_t sy) { - ftruncate(w->bitmap_fd, sx * sy * sizeof(uint32_t)); + if (sx * sy > MAX_WINDOW_SIZE) { + return; + } + w->sx = sx; w->sy = sy; char buffer[sizeof(uint8_t) + sizeof(uint32_t) * 2]; @@ -298,8 +305,9 @@ GUI_Window *GUI_CreateWindow(uint32_t x, uint32_t y, uint32_t sx, uint32_t sy) { printf("bitmap_fd: %x\n", w->bitmap_fd); assert(0); } - ftruncate(w->bitmap_fd, sx * sy * sizeof(uint32_t)); - void *rc = mmap(NULL, sx * sy * sizeof(uint32_t), 0, 0, w->bitmap_fd, 0); + ftruncate(w->bitmap_fd, MAX_WINDOW_SIZE * sizeof(uint32_t)); + void *rc = + mmap(NULL, MAX_WINDOW_SIZE * sizeof(uint32_t), 0, 0, w->bitmap_fd, 0); if (!((int)rc >= 0)) { printf("rc: %x\n", rc); assert(0); diff --git a/userland/terminal/term.c b/userland/terminal/term.c index cd75a90..b0eabfd 100644 --- a/userland/terminal/term.c +++ b/userland/terminal/term.c @@ -14,6 +14,8 @@ #define TERM_BACKGROUND 0x000000 +char terminal_char_buffer[1920 / 8][1080 / 8] = {0}; + int cmdfd; GUI_Window *global_w; uint32_t screen_pos_x = 0; @@ -25,7 +27,7 @@ int shell_pid; int raw_mode = 0; void execsh(void) { - char *argv[] = {NULL}; + char *argv[] = {"/sh", NULL}; execv("/sh", argv); } @@ -45,6 +47,7 @@ void screen_update_cursor() { void screen_putchar(uint32_t c) { if (raw_mode) { GUI_DrawFont(global_w, screen_pos_x, screen_pos_y, c); + terminal_char_buffer[screen_pos_y / 8][screen_pos_x / 8] = c; screen_remove_old_cursor(); return; } @@ -70,6 +73,7 @@ void screen_putchar(uint32_t c) { screen_pos_y -= 8; } GUI_DrawFont(global_w, screen_pos_x, screen_pos_y, c); + terminal_char_buffer[screen_pos_y / 8][screen_pos_x / 8] = c; screen_pos_x += 8; if (screen_pos_x >= global_w->sx - 8) { screen_pos_x = 0; @@ -223,6 +227,15 @@ void handle_escape_codes_or_print(char *buffer, int len) { handle_escape_codes_or_print(buffer, len); } +void terminal_resize(uint32_t sx, uint32_t sy) { + GUI_Resize(global_w, sx, sy); + for (int y = 0; y < sy; y += 8) { + for (int x = 0; x < sx; x += 8) { + GUI_DrawFont(global_w, x, y, terminal_char_buffer[y / 8][x / 8]); + } + } +} + void run() { char buffer[4096]; struct pollfd fds[2]; @@ -253,10 +266,10 @@ void run() { exit(0); return; } - // if (WINDOWSERVER_EVENT_WINDOW_RESIZE == e.type) { - // GUI_Resize(global_w, e.vector[0], e.vector[1]); - // continue; - // } + if (WINDOWSERVER_EVENT_WINDOW_RESIZE == e.type) { + terminal_resize(e.vector[0], e.vector[1]); + continue; + } if (WINDOWSERVER_EVENT_KEYPRESS != e.type) { continue; } |