From e21f5ef52fa9534fe81746083a2a7a8aeee8b8ff Mon Sep 17 00:00:00 2001 From: Karina Date: Sat, 31 Jan 2026 22:47:42 +0400 Subject: [PATCH] ref(libterm): now apple-styled too --- bootloader/src/uefi/stdio.c | 22 +-- bootloader/src/uefi/stdlib.c | 14 +- bootloader/src/uefi/string.c | 4 +- bootloader/src/uefi/uefi.h | 14 +- kernel/inc/OS/Services/OSServiceIO.h | 4 +- kernel/inc/OS/Services/OSServiceMemory.h | 2 +- kernel/src/OS/Services/OSServiceIO.c | 4 +- kernel/src/OS/Services/OSServiceMemory.c | 2 +- kernel/src/arch/x86_64/syscall.c | 6 +- userspace/debug/src/main.c | 10 +- userspace/init/src/main.c | 7 +- userspace/libterm/CMakeLists.txt | 18 +- userspace/libterm/inc/Console.h | 15 ++ userspace/libterm/inc/Memory.h | 23 +++ .../libterm/inc/{process.h => Process.h} | 6 +- userspace/libterm/inc/String.h | 16 ++ userspace/libterm/inc/{types.h => Types.h} | 0 userspace/libterm/inc/{stdarg.h => Varargs.h} | 0 userspace/libterm/inc/malloc.h | 19 -- userspace/libterm/inc/stdio.h | 11 -- userspace/libterm/inc/string.h | 16 -- userspace/libterm/inc/termOS.h | 8 + .../libterm/src/{ctype.c => Character.c} | 0 userspace/libterm/src/Console.c | 156 +++++++++++++++ userspace/libterm/src/Memory.c | 104 ++++++++++ .../src/{syscalls.asm => OSServices.asm} | 24 +-- userspace/libterm/src/Process.c | 15 ++ .../src/{crt0.asm => RuntimeEntry.asm} | 4 +- userspace/libterm/src/String.c | 126 ++++++++++++ userspace/libterm/src/malloc.c | 103 ---------- userspace/libterm/src/process.c | 15 -- userspace/libterm/src/stdio.c | 185 ------------------ userspace/libterm/src/string.c | 126 ------------ userspace/termosh/src/handlers/misc.c | 4 +- userspace/termosh/src/handlers/spawn.c | 12 +- userspace/termosh/src/main.c | 10 +- userspace/termosh/src/modules/parser.c | 8 +- 37 files changed, 548 insertions(+), 565 deletions(-) create mode 100644 userspace/libterm/inc/Console.h create mode 100644 userspace/libterm/inc/Memory.h rename userspace/libterm/inc/{process.h => Process.h} (51%) create mode 100644 userspace/libterm/inc/String.h rename userspace/libterm/inc/{types.h => Types.h} (100%) rename userspace/libterm/inc/{stdarg.h => Varargs.h} (100%) delete mode 100644 userspace/libterm/inc/malloc.h delete mode 100644 userspace/libterm/inc/stdio.h delete mode 100644 userspace/libterm/inc/string.h create mode 100644 userspace/libterm/inc/termOS.h rename userspace/libterm/src/{ctype.c => Character.c} (100%) create mode 100644 userspace/libterm/src/Console.c create mode 100644 userspace/libterm/src/Memory.c rename userspace/libterm/src/{syscalls.asm => OSServices.asm} (52%) create mode 100644 userspace/libterm/src/Process.c rename userspace/libterm/src/{crt0.asm => RuntimeEntry.asm} (74%) create mode 100644 userspace/libterm/src/String.c delete mode 100644 userspace/libterm/src/malloc.c delete mode 100644 userspace/libterm/src/process.c delete mode 100644 userspace/libterm/src/stdio.c delete mode 100644 userspace/libterm/src/string.c diff --git a/bootloader/src/uefi/stdio.c b/bootloader/src/uefi/stdio.c index cd0e45a..c49a4f7 100644 --- a/bootloader/src/uefi/stdio.c +++ b/bootloader/src/uefi/stdio.c @@ -46,7 +46,7 @@ void __stdio_cleanup(void) BS->FreePool(__argvutf8); #endif if(__blk_devs) { - free(__blk_devs); + MemoryFree(__blk_devs); __blk_devs = NULL; __blk_ndevs = 0; } @@ -127,7 +127,7 @@ int fclose (FILE *__stream) if(__stream == (FILE*)__blk_devs[i].bio) return 1; status = __stream->Close(__stream); - free(__stream); + MemoryFree(__stream); return !EFI_ERROR(status); } @@ -188,7 +188,7 @@ err: __stdio_seterrno(status); return -1; } /* no need for fclose(f); */ - free(f); + MemoryFree(f); return 0; } @@ -250,7 +250,7 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) /* workaround a bug in TianoCore, it reports zero size even though the data is in the buffer */ if(handle_size < 1) handle_size = (uintn_t)sizeof(handles) / sizeof(efi_handle_t); - __blk_devs = (block_file_t*)malloc(handle_size * sizeof(block_file_t)); + __blk_devs = (block_file_t*)MemoryAllocate(handle_size * sizeof(block_file_t)); if(__blk_devs) { memset(__blk_devs, 0, handle_size * sizeof(block_file_t)); for(i = __blk_ndevs = 0; i < handle_size; i++) @@ -276,7 +276,7 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) errno = ENODEV; return NULL; } - ret = (FILE*)malloc(sizeof(FILE)); + ret = (FILE*)MemoryAllocate(sizeof(FILE)); if(!ret) return NULL; /* normally write means read,write,create. But for remove (internal '*' mode), we need read,write without create * also mode 'w' in POSIX means write-only (without read), but that's not working on certain firmware, we must @@ -292,16 +292,16 @@ FILE *fopen (const char_t *__filename, const char_t *__modes) __modes[1] == CL('d') ? EFI_FILE_DIRECTORY : 0); if(EFI_ERROR(status)) { err: __stdio_seterrno(status); - free(ret); return NULL; + MemoryFree(ret); return NULL; } if(__modes[0] == CL('*')) return ret; status = ret->GetInfo(ret, &infGuid, &fsiz, &info); if(EFI_ERROR(status)) goto err; if(__modes[1] == CL('d') && !(info.Attribute & EFI_FILE_DIRECTORY)) { - ret->Close(ret); free(ret); errno = ENOTDIR; return NULL; + ret->Close(ret); MemoryFree(ret); errno = ENOTDIR; return NULL; } if(__modes[1] != CL('d') && (info.Attribute & EFI_FILE_DIRECTORY)) { - ret->Close(ret); free(ret); errno = EISDIR; return NULL; + ret->Close(ret); MemoryFree(ret); errno = EISDIR; return NULL; } if(__modes[0] == CL('a')) fseek(ret, 0, SEEK_END); if(__modes[0] == CL('w')) { @@ -713,7 +713,7 @@ int sprintf(char_t *dst, const char_t* fmt, ...) return ret; } -int snprintf(char_t *dst, size_t maxlen, const char_t* fmt, ...) +int StringFormat(char_t *dst, size_t maxlen, const char_t* fmt, ...) { int ret; __builtin_va_list args; @@ -738,7 +738,7 @@ int vprintf(const char_t* fmt, __builtin_va_list args) return ret; } -int printf(const char_t* fmt, ...) +int ConsolePrint(const char_t* fmt, ...) { int ret; __builtin_va_list args; @@ -800,7 +800,7 @@ int getchar_ifany (void) return EFI_ERROR(status) ? 0 : key.UnicodeChar; } -int getchar (void) +int ConsoleGetCharacter (void) { uintn_t idx; BS->WaitForEvent(1, &ST->ConIn->WaitForKey, &idx); diff --git a/bootloader/src/uefi/stdlib.c b/bootloader/src/uefi/stdlib.c index ae10bf6..ca8abaa 100644 --- a/bootloader/src/uefi/stdlib.c +++ b/bootloader/src/uefi/stdlib.c @@ -77,7 +77,7 @@ int64_t strtol (const char_t *s, char_t **__endptr, int __base) return v * sign; } -void *malloc (size_t __size) +void *MemoryAllocate (size_t __size) { void *ret = NULL; efi_status_t status; @@ -106,20 +106,20 @@ void *malloc (size_t __size) void *calloc (size_t __nmemb, size_t __size) { - void *ret = malloc(__nmemb * __size); + void *ret = MemoryAllocate(__nmemb * __size); if(ret) memset(ret, 0, __nmemb * __size); return ret; } -void *realloc (void *__ptr, size_t __size) +void *MemoryReallocate (void *__ptr, size_t __size) { void *ret = NULL; efi_status_t status; #ifndef UEFI_NO_TRACK_ALLOC uintn_t i; #endif - if(!__ptr) return malloc(__size); - if(!__size) { free(__ptr); return NULL; } + if(!__ptr) return MemoryAllocate(__size); + if(!__size) { MemoryFree(__ptr); return NULL; } #ifndef UEFI_NO_TRACK_ALLOC /* get the slot which stores the old size for this buffer */ for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != (uintptr_t)__ptr; i += 2); @@ -145,7 +145,7 @@ void *realloc (void *__ptr, size_t __size) return ret; } -void free (void *__ptr) +void MemoryFree (void *__ptr) { efi_status_t status; #ifndef UEFI_NO_TRACK_ALLOC @@ -341,7 +341,7 @@ uint8_t *getenv(char_t *name, uintn_t *len) #else status = RT->GetVariable(name, &globGuid, &attr, len, &tmp); #endif - if(EFI_ERROR(status) || *len < 1 || !(ret = malloc((*len) + 1))) { + if(EFI_ERROR(status) || *len < 1 || !(ret = MemoryAllocate((*len) + 1))) { *len = 0; return NULL; } diff --git a/bootloader/src/uefi/string.c b/bootloader/src/uefi/string.c index eb7be41..1233ff0 100644 --- a/bootloader/src/uefi/string.c +++ b/bootloader/src/uefi/string.c @@ -116,7 +116,7 @@ void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl) return NULL; } -char_t *strcpy(char_t *dst, const char_t *src) +char_t *StringCopy(char_t *dst, const char_t *src) { char_t *s = dst; if(src && dst && src != dst) { @@ -178,7 +178,7 @@ int strncmp(const char_t *s1, const char_t *s2, size_t n) char_t *strdup(const char_t *s) { size_t i = (strlen(s)+1) * sizeof(char_t); - char_t *s2 = (char_t *)malloc(i); + char_t *s2 = (char_t *)MemoryAllocate(i); if(s2 != NULL) memcpy(s2, (const void*)s, i); return s2; } diff --git a/bootloader/src/uefi/uefi.h b/bootloader/src/uefi/uefi.h index d46ed95..9d07f5b 100644 --- a/bootloader/src/uefi/uefi.h +++ b/bootloader/src/uefi/uefi.h @@ -1314,10 +1314,10 @@ typedef int (*__compar_fn_t) (const void *, const void *); extern int atoi (const char_t *__nptr); extern int64_t atol (const char_t *__nptr); extern int64_t strtol (const char_t *__nptr, char_t **__endptr, int __base); -extern void *malloc (size_t __size); +extern void *MemoryAllocate (size_t __size); extern void *calloc (size_t __nmemb, size_t __size); -extern void *realloc (void *__ptr, size_t __size); -extern void free (void *__ptr); +extern void *MemoryReallocate (void *__ptr, size_t __size); +extern void MemoryFree (void *__ptr); extern void abort (void); extern void exit (int __status); /* exit Boot Services function. Returns 0 on success. */ @@ -1355,14 +1355,14 @@ extern int fseek (FILE *__stream, long int __off, int __whence); extern long int ftell (FILE *__stream); extern int feof (FILE *__stream); extern int fprintf (FILE *__stream, const char_t *__format, ...); -extern int printf (const char_t *__format, ...); +extern int ConsolePrint (const char_t *__format, ...); extern int sprintf (char_t *__s, const char_t *__format, ...); extern int vfprintf (FILE *__s, const char_t *__format, __builtin_va_list __arg); extern int vprintf (const char_t *__format, __builtin_va_list __arg); extern int vsprintf (char_t *__s, const char_t *__format, __builtin_va_list __arg); -extern int snprintf (char_t *__s, size_t __maxlen, const char_t *__format, ...); +extern int StringFormat (char_t *__s, size_t __maxlen, const char_t *__format, ...); extern int vsnprintf (char_t *__s, size_t __maxlen, const char_t *__format, __builtin_va_list __arg); -extern int getchar (void); +extern int ConsoleGetCharacter (void); /* non-blocking, only returns UNICODE if there's any key pressed, 0 otherwise */ extern int getchar_ifany (void); extern int putchar (int __c); @@ -1376,7 +1376,7 @@ extern void *memchr(const void *__s, int __c, size_t __n); extern void *memrchr(const void *__s, int __c, size_t __n); void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl); void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl); -extern char_t *strcpy (char_t *__dest, const char_t *__src); +extern char_t *StringCopy (char_t *__dest, const char_t *__src); extern char_t *strncpy (char_t *__dest, const char_t *__src, size_t __n); extern char_t *strcat (char_t *__dest, const char_t *__src); extern char_t *strncat (char_t *__dest, const char_t *__src, size_t __n); diff --git a/kernel/inc/OS/Services/OSServiceIO.h b/kernel/inc/OS/Services/OSServiceIO.h index 98f96bf..03b79bb 100644 --- a/kernel/inc/OS/Services/OSServiceIO.h +++ b/kernel/inc/OS/Services/OSServiceIO.h @@ -4,5 +4,5 @@ #pragma once #include -UInt64 OSServiceWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length); -UInt64 OSServiceRead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count); \ No newline at end of file +UInt64 OSServiceIOWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length); +UInt64 OSServiceIORead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count); \ No newline at end of file diff --git a/kernel/inc/OS/Services/OSServiceMemory.h b/kernel/inc/OS/Services/OSServiceMemory.h index c1d71d6..69aa687 100644 --- a/kernel/inc/OS/Services/OSServiceMemory.h +++ b/kernel/inc/OS/Services/OSServiceMemory.h @@ -4,4 +4,4 @@ #pragma once #include -UInt64 OSServiceMemoryGet(UInt64 size); \ No newline at end of file +UInt64 OSServiceMemoryAllocate(UInt64 size); \ No newline at end of file diff --git a/kernel/src/OS/Services/OSServiceIO.c b/kernel/src/OS/Services/OSServiceIO.c index e3b60fc..481f436 100644 --- a/kernel/src/OS/Services/OSServiceIO.c +++ b/kernel/src/OS/Services/OSServiceIO.c @@ -5,7 +5,7 @@ #include #include -UInt64 OSServiceWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length) { +UInt64 OSServiceIOWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length) { if (fileDescriptor == 1 || fileDescriptor == 2) { char* string = (char*)buffer; for (UInt64 i = 0; i < length; i++) { @@ -16,7 +16,7 @@ UInt64 OSServiceWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length) { return 0; } -UInt64 OSServiceRead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count) { +UInt64 OSServiceIORead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count) { char* readBuffer = (char*)buffer; if (fileDescriptor == 0) { for (UInt64 i = 0; i < count; i++) { diff --git a/kernel/src/OS/Services/OSServiceMemory.c b/kernel/src/OS/Services/OSServiceMemory.c index 5fae4ca..1faec03 100644 --- a/kernel/src/OS/Services/OSServiceMemory.c +++ b/kernel/src/OS/Services/OSServiceMemory.c @@ -9,7 +9,7 @@ #include #include -UInt64 OSServiceMemoryGet(UInt64 size) { +UInt64 OSServiceMemoryAllocate(UInt64 size) { if (size == 0) return 0; OSProcess* currentProcess = gOSSchedulerCurrentTask->process; UInt64 addressToReturn = currentProcess->heapCurrentPointer; diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c index f842d43..2445c85 100644 --- a/kernel/src/arch/x86_64/syscall.c +++ b/kernel/src/arch/x86_64/syscall.c @@ -55,9 +55,9 @@ UInt64 syscall_dispatch(UInt64 id, UInt64 arg1, UInt64 arg2, UInt64 arg3, UInt64 switch (id) { case SYS_EXIT: return OSServiceProcessExit(arg1); case SYS_SPAWN: return OSServiceProcessSpawn((const char*)arg1); - case SYS_MEM: return OSServiceMemoryGet(arg1); - case SYS_WRITE: return OSServiceWrite(arg1, arg2, arg3); - case SYS_READ: return OSServiceRead(arg1, arg2, arg3); + case SYS_MEM: return OSServiceMemoryAllocate(arg1); + case SYS_WRITE: return OSServiceIOWrite(arg1, arg2, arg3); + case SYS_READ: return OSServiceIORead(arg1, arg2, arg3); case SYS_WAIT: return OSServiceProcessWait(arg1); default: IOConsoleLog("[Dewar] Unknown syscall %d\n", id); diff --git a/userspace/debug/src/main.c b/userspace/debug/src/main.c index a679cd6..0f51246 100644 --- a/userspace/debug/src/main.c +++ b/userspace/debug/src/main.c @@ -1,14 +1,12 @@ -#include -#include -#include +#include int main() { for (int i = 0; i < 100; i++) { - UInt64 pid = spawn("/System/CoreServices/debug"); + UInt64 pid = ProcessSpawn("/System/CoreServices/debug"); if (pid < 0) { - printf("[PIDSPAMMER] Error %d\n", pid); + ConsolePrint("[PIDSPAMMER] Error %d\n", pid); } else { - printf("[PIDSPAMMER] %d spawned\n", pid); + ConsolePrint("[PIDSPAMMER] %d spawned\n", pid); } } } \ No newline at end of file diff --git a/userspace/init/src/main.c b/userspace/init/src/main.c index 2879ffe..8f29761 100644 --- a/userspace/init/src/main.c +++ b/userspace/init/src/main.c @@ -1,14 +1,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2026 0xKarinyash -#include -#include +#include // TODO: read .cfg and spawn what stated there int main() { while (1) { - Int32 pid = spawn("/System/CoreServices/termosh"); + Int32 pid = ProcessSpawn("/System/CoreServices/termosh"); if (pid < 0) return pid; - wait(pid); + ProcessWait(pid); } } \ No newline at end of file diff --git a/userspace/libterm/CMakeLists.txt b/userspace/libterm/CMakeLists.txt index d0ba758..50cd6f0 100644 --- a/userspace/libterm/CMakeLists.txt +++ b/userspace/libterm/CMakeLists.txt @@ -22,12 +22,12 @@ set(USER_C_FLAGS set(CMAKE_ASM_NASM_FLAGS "-f elf64") set(LIBTERM_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/src/syscalls.asm - ${CMAKE_CURRENT_SOURCE_DIR}/src/stdio.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/malloc.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/string.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/ctype.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/process.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/OSServices.asm + ${CMAKE_CURRENT_SOURCE_DIR}/src/Console.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/Memory.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/String.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/Character.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/Process.c ) add_library(term STATIC ${LIBTERM_SOURCES}) @@ -36,13 +36,13 @@ target_compile_options(term PRIVATE $<$:${USER_C_FLAGS}>) target_include_directories(term PUBLIC inc) -add_library(crt0_obj OBJECT src/crt0.asm) -target_compile_options(crt0_obj PRIVATE $<$:${USER_C_FLAGS}>) +add_library(RuntimeEntryObject OBJECT src/RuntimeEntry.asm) +target_compile_options(RuntimeEntryObject PRIVATE $<$:${USER_C_FLAGS}>) function(add_termos_executable NAME SOURCES) add_executable(${NAME} ${SOURCES}) - target_sources(${NAME} PRIVATE $) + target_sources(${NAME} PRIVATE $) target_compile_options(${NAME} PRIVATE $<$:${USER_C_FLAGS}>) target_link_libraries(${NAME} PRIVATE term) diff --git a/userspace/libterm/inc/Console.h b/userspace/libterm/inc/Console.h new file mode 100644 index 0000000..e104735 --- /dev/null +++ b/userspace/libterm/inc/Console.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#pragma once +#include + +enum { + kConsoleEOF = -1, + kConsoleDefaultBufferSize = 1024 +}; + +Int32 ConsolePrint(const char* format, ...); +Int32 StringFormat(char* destination, UInt64 size, const char* format, ...); +Int32 ConsoleGetCharacter(); +char* ConsoleReadLine(char* string, UInt64 size); \ No newline at end of file diff --git a/userspace/libterm/inc/Memory.h b/userspace/libterm/inc/Memory.h new file mode 100644 index 0000000..1f9a173 --- /dev/null +++ b/userspace/libterm/inc/Memory.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#pragma once +#include + +enum { + kMemoryBlockMagic = 0x1CE1CE, + kMemoryAlignment = 16, + kMemoryPageSize = 4096 +}; + +typedef struct MemoryBlockHeader { + UInt64 magic; + struct MemoryBlockHeader* next; + struct MemoryBlockHeader* previous; + UInt64 size; + bool isFree; +} MemoryBlockHeader; + +void* MemoryAllocate(UInt64 size); +void MemoryFree(void* pointer); +void* MemoryReallocate(void* pointer, UInt64 newSize); \ No newline at end of file diff --git a/userspace/libterm/inc/process.h b/userspace/libterm/inc/Process.h similarity index 51% rename from userspace/libterm/inc/process.h rename to userspace/libterm/inc/Process.h index f66c7ed..fb43073 100644 --- a/userspace/libterm/inc/process.h +++ b/userspace/libterm/inc/Process.h @@ -2,7 +2,7 @@ // Copyright (c) 2026 0xKarinyash #pragma once -#include +#include -Int32 spawn(const char* path); -Int32 wait(UInt64 pid); \ No newline at end of file +Int32 ProcessSpawn(const char* path); +Int32 ProcessWait(UInt64 pid); \ No newline at end of file diff --git a/userspace/libterm/inc/String.h b/userspace/libterm/inc/String.h new file mode 100644 index 0000000..ea4156a --- /dev/null +++ b/userspace/libterm/inc/String.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#pragma once +#include + +void* MemorySet(void* destination, UInt8 value, UInt64 count); +void* MemoryCopy(void* destination, const void* source, UInt64 count); +Int32 StringCompare(const char* firstString, const char* secondString); +Int32 StringCompareWithLimit(const char* firstString, const char* secondString, UInt64 limit); +char* StringCopy(char* destination, const char* source); +char* StringCopyWithLimit(char* destination, const char* source, UInt64 limit); +UInt64 StringGetLength(const char* string); +UInt64 StringGetInitialSpan(const char* string, const char* characterSet); +char* StringFindFirstCharacterFromSet(const char* string, const char* accept); +char* StringTokenize(char *s, const char* delim); \ No newline at end of file diff --git a/userspace/libterm/inc/types.h b/userspace/libterm/inc/Types.h similarity index 100% rename from userspace/libterm/inc/types.h rename to userspace/libterm/inc/Types.h diff --git a/userspace/libterm/inc/stdarg.h b/userspace/libterm/inc/Varargs.h similarity index 100% rename from userspace/libterm/inc/stdarg.h rename to userspace/libterm/inc/Varargs.h diff --git a/userspace/libterm/inc/malloc.h b/userspace/libterm/inc/malloc.h deleted file mode 100644 index 6e1556c..0000000 --- a/userspace/libterm/inc/malloc.h +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#pragma once -#include - -#define HEADER_MAGIC 0x1CE1CE - -typedef struct block_header { - UInt64 magic; - struct block_header* next; - struct block_header* prev; - UInt64 size; - bool is_free; -} block_header; - -void* malloc(UInt64 size); -void free(void* ptr); -void* realloc(void* ptr, UInt64 new_size); \ No newline at end of file diff --git a/userspace/libterm/inc/stdio.h b/userspace/libterm/inc/stdio.h deleted file mode 100644 index 9de61bc..0000000 --- a/userspace/libterm/inc/stdio.h +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#pragma once -#include - -int printf(const char *fmt, ...); -int snprintf(char* str, UInt64 size, const char* fmt, ...); -int getchar(); -char* gets(char* str); -char* gets_s(char* str, UInt64 size); \ No newline at end of file diff --git a/userspace/libterm/inc/string.h b/userspace/libterm/inc/string.h deleted file mode 100644 index 57094f0..0000000 --- a/userspace/libterm/inc/string.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#pragma once -#include - -void *memset(void *ptr, int value, usize num); -void* memcpy(void* dest, const void* src, UInt64 n); -Int32 strcmp(const char *s1, const char *s2); -Int32 strncmp(const char* s1, const char* s2, UInt64 n); -char* strcpy(char* dest, const char* src); -char* strncpy(char* dest, const char* src, UInt64 n); -UInt64 strlen(const char* str); -UInt64 strspn(const char* s, const char* accept); -char* strpbrk(const char* s, const char* accept); -char* strtok(char *s, const char* delim); \ No newline at end of file diff --git a/userspace/libterm/inc/termOS.h b/userspace/libterm/inc/termOS.h new file mode 100644 index 0000000..f02426c --- /dev/null +++ b/userspace/libterm/inc/termOS.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/userspace/libterm/src/ctype.c b/userspace/libterm/src/Character.c similarity index 100% rename from userspace/libterm/src/ctype.c rename to userspace/libterm/src/Character.c diff --git a/userspace/libterm/src/Console.c b/userspace/libterm/src/Console.c new file mode 100644 index 0000000..a7054e4 --- /dev/null +++ b/userspace/libterm/src/Console.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include +#include +#include + +extern UInt64 OSServiceIORead(UInt64 fileDescriptor, void* buffer, UInt64 length); +extern UInt64 OSServiceIOWrite(UInt64 fileDescriptor, const void* buffer, UInt64 length); + +static void sConsoleWriteCharacter(char character) { + OSServiceIOWrite(1, &character, 1); +} + +static inline void sConsoleBufferAdd(char* string, UInt64 size, UInt64* written, char character) { + if (*written < size - 1 && size > 0) { + string[*written] = character; + } + (*written)++; +} + +static Int32 sStringFormatVariadic(char* string, UInt64 size, const char* format, va_list args) { + UInt64 written = 0; + for (UInt32 i = 0; format[i] != '\0'; i++) { + if (format[i] == '%') { + i++; + if (format[i] == '\0') break; + switch (format[i]) { + case 's': { + const char* vaArgString = va_arg(args, const char*); + if (!vaArgString) vaArgString = "(null)"; + while (*vaArgString) sConsoleBufferAdd(string, size, &written, *vaArgString++); + break; + } + case 'c': { + char character = (char)va_arg(args, int); + sConsoleBufferAdd(string, size, &written, character); + break; + } + case 'd': { + Int64 number = va_arg(args, int); + if (number < 0) { + sConsoleBufferAdd(string, size, &written, '-'); + number = -number; + } + UInt64 unsignedNumber = (UInt64)number; + char tempBuffer[32]; + Int32 position = 0; + if (unsignedNumber == 0) tempBuffer[position++] = '0'; + while (unsignedNumber > 0) { + tempBuffer[position++] = (unsignedNumber % 10) + '0'; + unsignedNumber /= 10; + } + + while (position > 0) sConsoleBufferAdd(string, size, &written, tempBuffer[--position]); + break; + } + case 'x': + case 'X': { + UInt64 unsignedNumber = va_arg(args, unsigned long long); + UInt8 padding = (format[i] == 'X') ? 16 : 0; + + char tempBuffer[32]; + int position = 0; + const char* hex = "0123456789ABCDEF"; + + if (unsignedNumber == 0 && padding == 0) tempBuffer[position++] = '0'; + while (unsignedNumber > 0) { + tempBuffer[position++] = hex[unsignedNumber % 16]; + unsignedNumber /= 16; + } + + while (position < padding) tempBuffer[position++] = '0'; + while (position > 0) sConsoleBufferAdd(string, size, &written, tempBuffer[--position]); + break; + } + case '%': { + sConsoleBufferAdd(string, size, &written, '%'); + break; + } + default: { + sConsoleBufferAdd(string, size, &written, '%'); + sConsoleBufferAdd(string, size, &written, format[i]); + break; + } + } + } else { + sConsoleBufferAdd(string, size, &written, format[i]); + } + } + + if (size > 0) { + if (written < size) string[written] = '\0'; + else string[size - 1] = '\0'; + } + + return (int)written; +} + +Int32 StringFormat(char* destination, usize size, const char* format, ...) { + va_list args; + va_start(args, format); + int returnValue = sStringFormatVariadic(destination, size, format, args); + va_end(args); + return returnValue; +} + +Int32 ConsolePrint(const char *format, ...) { + char buffer[kConsoleDefaultBufferSize]; + va_list args; + va_start(args, format); + + int length = sStringFormatVariadic(buffer, sizeof(buffer), format, args); + va_end(args); + + UInt64 writeLength = ((UInt64)length < sizeof(buffer)) ? length : (sizeof(buffer) - 1); + OSServiceIOWrite(1, buffer, writeLength); + + return (int)writeLength; +} + +Int32 ConsoleGetCharacter() { + char character; + UInt64 serviceCallResult = OSServiceIORead(0, &character, 1); + if (serviceCallResult <= 0) return kConsoleEOF; + return (int)(unsigned char)character; +} + +char* ConsoleReadLine(char* string, UInt64 size) { + if (size == 0) return string; + + UInt64 i = 0; + int character; + + while (i < size - 1) { + character = ConsoleGetCharacter(); + if (character == kConsoleEOF || character == '\n' || character == '\r') break; + if (character == '\b') { + if (i > 0) { + i--; + ConsolePrint("\b \b"); + } + + continue; + } + + string[i++] = (char)character; + + sConsoleWriteCharacter(character); + } + + string[i] = '\0'; + sConsoleWriteCharacter('\n'); + + return string; +} \ No newline at end of file diff --git a/userspace/libterm/src/Memory.c b/userspace/libterm/src/Memory.c new file mode 100644 index 0000000..a114c72 --- /dev/null +++ b/userspace/libterm/src/Memory.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash +// brutally copypasting from kernel/mm/heap.c + +#include +#include + +static MemoryBlockHeader* sMemoryHeapListHead = nullptr; +extern UInt64 OSServiceMemoryAllocate(UInt64 size); + +static void sMemoryCombineForward(MemoryBlockHeader* current) { + if (!current->next || !current->next->isFree) return; + current->size += sizeof(MemoryBlockHeader) + current->next->size; + current->next = current->next->next; + if (current->next) current->next->previous = current; +} + +void* MemoryAllocate(UInt64 size) { + if (size == 0) return nullptr; + UInt64 alignedSize = (size + (kMemoryAlignment-1)) & ~(kMemoryAlignment - 1); + + MemoryBlockHeader* current = sMemoryHeapListHead; + MemoryBlockHeader* lastBlock = nullptr; + + while (current) { + if (current->isFree && current->size >= alignedSize) { + if (current->size > alignedSize + sizeof(MemoryBlockHeader) + kMemoryAlignment) { + MemoryBlockHeader* newBlock = (MemoryBlockHeader*)((UInt64)current + sizeof(MemoryBlockHeader) + alignedSize); + newBlock->size = current->size - alignedSize - sizeof(MemoryBlockHeader); + newBlock->isFree = true; + newBlock->next = current->next; + newBlock->previous = current; + newBlock->magic = kMemoryBlockMagic; + + if (current->next) current->next->previous = newBlock; + current->next = newBlock; + current->size = alignedSize; + } + current->isFree = false; + return (void*)((UInt64)current + sizeof(MemoryBlockHeader)); + } + lastBlock = current; + current = current->next; + } + + UInt64 sizeNeededToAllocate = alignedSize + sizeof(MemoryBlockHeader); + + UInt64 pageAlignedSize = (sizeNeededToAllocate + (kMemoryPageSize-1)) & ~(kMemoryPageSize-1); + + UInt64 newMemoryAddress = OSServiceMemoryAllocate(pageAlignedSize); + if (newMemoryAddress == 0) return nullptr; + + MemoryBlockHeader* newBlock = (MemoryBlockHeader*)newMemoryAddress; + newBlock->size = pageAlignedSize - sizeof(MemoryBlockHeader); + newBlock->isFree = true; + newBlock->magic = kMemoryBlockMagic; + newBlock->next = nullptr; + newBlock->previous = lastBlock; + + if (lastBlock) { + lastBlock->next = newBlock; + } else { + sMemoryHeapListHead = newBlock; + } + + return MemoryAllocate(size); +} + +void MemoryFree(void* pointer) { + if (!pointer) return; + + MemoryBlockHeader* current = (MemoryBlockHeader*)((UInt64)pointer - sizeof(MemoryBlockHeader)); + if (current->magic != kMemoryBlockMagic) return; + + current->isFree = true; + if (current->next && current->next->isFree) sMemoryCombineForward(current); + if (current->previous && current->previous->isFree) sMemoryCombineForward(current->previous); +} + +void* MemoryReallocate(void* pointer, UInt64 newSize) { + if (!pointer) return MemoryAllocate(newSize); + if (newSize == 0) { + MemoryFree(pointer); + return nullptr; + } + + MemoryBlockHeader* current = (MemoryBlockHeader*)((UInt64)pointer - sizeof(MemoryBlockHeader)); + if (current->size >= newSize) return pointer; + + if (current->next && + current->next->isFree && + (current->size + sizeof(MemoryBlockHeader) + current->next->size) >= newSize) { + sMemoryCombineForward(current); + return pointer; + } + + void* newPointer = MemoryAllocate(newSize); + if (!newPointer) return nullptr; + + MemoryCopy(newPointer, pointer, current->size); + MemoryFree(pointer); + + return newPointer; +} \ No newline at end of file diff --git a/userspace/libterm/src/syscalls.asm b/userspace/libterm/src/OSServices.asm similarity index 52% rename from userspace/libterm/src/syscalls.asm rename to userspace/libterm/src/OSServices.asm index 8890f09..71c4d74 100644 --- a/userspace/libterm/src/syscalls.asm +++ b/userspace/libterm/src/OSServices.asm @@ -5,39 +5,39 @@ bits 64 section .text -global sys_exit -global sys_spawn -global sys_mem -global sys_write -global sys_read -global sys_wait +global OSServiceProcessExit +global OSServiceProcessSpawn +global OSServiceMemoryAllocate +global OSServiceIOWrite +global OSServiceIORead +global OSServiceProcessWait -sys_exit: +OSServiceProcessExit: mov rax, 0 syscall ret -sys_spawn: +OSServiceProcessSpawn: mov rax, 1 syscall ret -sys_mem: +OSServiceMemoryAllocate: mov rax, 2 syscall ret -sys_write: +OSServiceIOWrite: mov rax, 3 syscall ret -sys_read: +OSServiceIORead: mov rax, 4 syscall ret -sys_wait: +OSServiceProcessWait: mov rax, 5 syscall ret \ No newline at end of file diff --git a/userspace/libterm/src/Process.c b/userspace/libterm/src/Process.c new file mode 100644 index 0000000..f2ba9b5 --- /dev/null +++ b/userspace/libterm/src/Process.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include + +extern Int32 OSServiceProcessSpawn(const char* path); +extern Int32 OSServiceProcessWait(UInt64 pid); + +Int32 ProcessSpawn(const char* path) { + return OSServiceProcessSpawn(path); +} + +Int32 ProcessWait(UInt64 pid) { + return OSServiceProcessWait(pid); +} \ No newline at end of file diff --git a/userspace/libterm/src/crt0.asm b/userspace/libterm/src/RuntimeEntry.asm similarity index 74% rename from userspace/libterm/src/crt0.asm rename to userspace/libterm/src/RuntimeEntry.asm index bed6c26..9ab1035 100644 --- a/userspace/libterm/src/crt0.asm +++ b/userspace/libterm/src/RuntimeEntry.asm @@ -6,9 +6,9 @@ section .text global _start extern main -extern sys_exit +extern OSServiceProcessExit _start: call main mov rdi, rax - call sys_exit \ No newline at end of file + call OSServiceProcessExit \ No newline at end of file diff --git a/userspace/libterm/src/String.c b/userspace/libterm/src/String.c new file mode 100644 index 0000000..d2cedfa --- /dev/null +++ b/userspace/libterm/src/String.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include + +static char* olds; + +void* MemorySet(void* destination, UInt8 value, usize count) { + UInt8* bytePointer = (UInt8*) destination; + while (count--) { + *bytePointer++ = (UInt8)value; + } + return destination; +} + +void* MemoryCopy(void* destination, const void* source, UInt64 count) { + UInt8* destinationBuffer = (UInt8*)destination; + const UInt8* sourceBuffer = (const UInt8*)source; + + while (count >= 8) { + *(UInt64*)destinationBuffer = *(const UInt64*)sourceBuffer; + destinationBuffer += 8; + sourceBuffer += 8; + count -= 8; + } + + while (count > 0) { + *destinationBuffer++ = *sourceBuffer++; + count--; + } + + return destination; +} + +Int32 StringCompare(const char* firstString, const char* secondString) { + while (*firstString && (*firstString == *secondString)) { + firstString++; + secondString++; + } + return *(const unsigned char*)firstString - *(const unsigned char*)secondString; +} + +Int32 StringCompareWithLimit(const char* firstString, const char* secondString, UInt64 limit) { + while (limit > 0) { + if (*firstString != *secondString) return *(unsigned char*)firstString - *(unsigned char*)secondString; + if (*firstString == '\0') return 0; + firstString++; + secondString++; + limit--; + } + + return 0; +} + +char* StringCopy(char* destination, const char* source) { + char* saved = destination; + while (*source) *destination++ = *source++; + *destination = 0; + return saved; +} + +char* StringCopyWithLimit(char* destination, const char* source, UInt64 limit) { + char* saved = destination; + while (*source && limit > 0) { + *destination++ = *source++; + limit--; + } + while (limit > 0) { + *destination++ = 0; + limit--; + } + return saved; +} + +UInt64 StringGetLength(const char* string) { + UInt64 result = 0; + for (result = 0; string[result]; result++); + return result; +} + +static inline int sStringIsInSet(char character, const char* set) { + while (*set) { + if (*set == character) return 1; + set++; + } + return 0; +} + +UInt64 StringGetInitialSpan(const char* string, const char* characterSet) { + UInt64 count = 0; + while (*string && sStringIsInSet(*string, characterSet)) { + count++; + string++; + } + return count; +} + +char* StringFindFirstCharacterFromSet(const char* string, const char* set) { + while (*string) { + if (sStringIsInSet(*string, set)) { + return (char*)string; + } + string++; + } + return nullptr; +} +// took from https://github.com/walac/glibc/blob/master/string/strtok.c +char* StringTokenize(char* string, const char* delimiters) { + char* token; + if (string == nullptr) string = olds; + string += StringGetInitialSpan(string, delimiters); + if (*string == '\0') { + olds = string; + return nullptr; + } + + token = string; + string = StringFindFirstCharacterFromSet(token, delimiters); + if (string == nullptr) olds = token + StringGetLength(token); + else { + *string = '\0'; + olds = string + 1; + } + + return token; +} \ No newline at end of file diff --git a/userspace/libterm/src/malloc.c b/userspace/libterm/src/malloc.c deleted file mode 100644 index c7b6ca4..0000000 --- a/userspace/libterm/src/malloc.c +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash -// brutally copypasting from kernel/mm/heap.c - -#include -#include - -static block_header* heap_list_head = nullptr; -extern UInt64 sys_mem(UInt64 size); - -void combine_forward(block_header* curr) { - if (!curr->next || !curr->next->is_free) return; - curr->size += sizeof(block_header) + curr->next->size; - curr->next = curr->next->next; - if (curr->next) curr->next->prev = curr; // what the fuck -} - -void* malloc(UInt64 size) { - if (size == 0) return nullptr; - UInt64 aligned_size = (size + 15) & ~15; - - block_header* curr = heap_list_head; - block_header* last = nullptr; - while (curr) { - if (curr->is_free && curr->size >= aligned_size) { - if (curr->size > aligned_size + sizeof(block_header) + 16) { - block_header* new_block = (block_header*)((UInt64)curr + sizeof(block_header) + aligned_size); - new_block->size = curr->size - aligned_size - sizeof(block_header); - new_block->is_free = true; - new_block->next = curr->next; - new_block->prev = curr; - new_block->magic = HEADER_MAGIC; - - if (curr->next) curr->next->prev = new_block; - curr->next = new_block; - curr->size = aligned_size; - } - curr->is_free = false; - return (void*)((UInt64)curr + sizeof(block_header)); - } - last = curr; - curr = curr->next; - } - - UInt64 need_to_alloc = aligned_size + sizeof(block_header); - - UInt64 page_aligned_size = (need_to_alloc + 4095) & ~4095; - - UInt64 new_mem_addr = sys_mem(page_aligned_size); - if (new_mem_addr == 0) return nullptr; - - block_header* new_block = (block_header*)new_mem_addr; - new_block->size = page_aligned_size - sizeof(block_header); - new_block->is_free = true; - new_block->magic = HEADER_MAGIC; - new_block->next = nullptr; - new_block->prev = last; - - if (last) { - last->next = new_block; - } else { - heap_list_head = new_block; - } - - return malloc(size); -} - -void free(void* ptr) { - if (!ptr) return; - - block_header* curr = (block_header*)((UInt64)ptr - sizeof(block_header)); - if (curr->magic != HEADER_MAGIC) return; - - curr->is_free = true; - if (curr->next && curr->next->is_free) combine_forward(curr); - if (curr->prev && curr->prev->is_free) combine_forward(curr->prev); -} - -void* realloc(void* ptr, UInt64 new_size) { - if (!ptr) return malloc(new_size); - if (new_size == 0) { - free(ptr); - return nullptr; - } - - block_header* curr = (block_header*)((UInt64)ptr - sizeof(block_header)); - if (curr->size >= new_size) return ptr; - - if (curr->next && - curr->next->is_free && - (curr->size + sizeof(block_header) + curr->next->size) >= new_size) { // why ts so fucking unreadable - combine_forward(curr); - return ptr; - } - - void* new_ptr = malloc(new_size); - if (!new_ptr) return nullptr; - - memcpy(new_ptr, ptr, curr->size); - free(ptr); - - return new_ptr; -} \ No newline at end of file diff --git a/userspace/libterm/src/process.c b/userspace/libterm/src/process.c deleted file mode 100644 index e44b58d..0000000 --- a/userspace/libterm/src/process.c +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include - -extern Int32 sys_spawn(const char* path); -extern Int32 sys_wait(UInt64 pid); - -Int32 spawn(const char* path) { - return sys_spawn(path); -} - -Int32 wait(UInt64 pid) { - return sys_wait(pid); -} \ No newline at end of file diff --git a/userspace/libterm/src/stdio.c b/userspace/libterm/src/stdio.c deleted file mode 100644 index 12715e5..0000000 --- a/userspace/libterm/src/stdio.c +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include -#include -#include -#include - -#define EOF (-1) -#define PRINTF_BUFFER_SIZE 1024 - -extern UInt64 sys_read(UInt64 fd, void* buf, UInt64 len); -extern UInt64 sys_write(UInt64 fd, const void* buf, UInt64 len); - -static void putchar(char c) { - sys_write(1, &c, 1); -} - -static inline void buf_add(char* str, UInt64 size, UInt64* written, char c) { - if (*written < size - 1 && size > 0) { - str[*written] = c; - } - (*written)++; -} - -int vsnprintf(char* str, UInt64 size, const char* fmt, va_list args) { - UInt64 written = 0; - for (UInt32 i = 0; fmt[i] != '\0'; i++) { - if (fmt[i] == '%') { - i++; - if (fmt[i] == '\0') break; - switch (fmt[i]) { - case 's': { - const char* s = va_arg(args, const char*); - if (!s) s = "(null)"; - while (*s) buf_add(str, size, &written, *s++); - break; - } - case 'c': { - char c = (char)va_arg(args, int); - buf_add(str, size, &written, c); - break; - } - case 'd': { - Int64 n = va_arg(args, int); - if (n < 0) { - buf_add(str, size, &written, '-'); - n = -n; - } - UInt64 u = (UInt64)n; - char tmp[32]; - Int32 pos = 0; - if (u == 0) tmp[pos++] = '0'; - while (u > 0) { - tmp[pos++] = (u % 10) + '0'; - u /= 10; - } - - while (pos > 0) buf_add(str, size, &written, tmp[--pos]); - break; - } - case 'x': - case 'X': { - UInt64 u = va_arg(args, unsigned long long); - UInt8 padding = (fmt[i] == 'X') ? 16 : 0; - - char tmp[32]; - int pos = 0; - const char* hex = "0123456789ABCDEF"; - - if (u == 0 && padding == 0) tmp[pos++] = '0'; - while (u > 0) { - tmp[pos++] = hex[u % 16]; - u /= 16; - } - - while (pos < padding) tmp[pos++] = '0'; - while (pos > 0) buf_add(str, size, &written, tmp[--pos]); - break; - } - case '%': { - buf_add(str, size, &written, '%'); - break; - } - default: { - buf_add(str, size, &written, '%'); - buf_add(str, size, &written, fmt[i]); - break; - } - } - } else { - buf_add(str, size, &written, fmt[i]); - } - } - - if (size > 0) { - if (written < size) str[written] = '\0'; - else str[size - 1] = '\0'; - } - - return (int)written; -} - -int snprintf(char* str, usize size, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - int ret = vsnprintf(str, size, fmt, args); - va_end(args); - return ret; -} - -int printf(const char *fmt, ...) { - char buf[PRINTF_BUFFER_SIZE]; - va_list args; - va_start(args, fmt); - - int len = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - - UInt64 write_len = ((UInt64)len < sizeof(buf)) ? len : (sizeof(buf) - 1); - sys_write(1, buf, write_len); - - return (int)write_len; -} - -int getchar() { - char c; - unsigned long long res = sys_read(0, &c, 1); - if (res <= 0) return EOF; - return (int)(unsigned char)c; -} - -char* gets(char* str) { - int i = 0; - int c; - - while (1) { - c = getchar(); - - if (c == EOF || c == '\n' || c == '\r') { - break; - } - - str[i++] = (char)c; - - char ch = (char)c; - sys_write(1, &ch, 1); - } - - str[i] = '\0'; - - char nl = '\n'; - sys_write(1, &nl, 1); - - return str; -} - -char* gets_s(char* str, UInt64 size) { - if (size == 0) return str; - - UInt64 i = 0; - int c; - - while (i < size - 1) { - c = getchar(); - if (c == EOF || c == '\n' || c == '\r') break; - if (c == '\b') { - if (i > 0) { - i--; - printf("\b \b"); - } - - continue; - } - - str[i++] = (char)c; - - putchar(c); - } - - str[i] = '\0'; - putchar('\n'); - - return str; -} \ No newline at end of file diff --git a/userspace/libterm/src/string.c b/userspace/libterm/src/string.c deleted file mode 100644 index 0865f67..0000000 --- a/userspace/libterm/src/string.c +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - -#include - -static char* olds; - -void *memset(void *ptr, int value, usize num) { - UInt8 *p = (UInt8 *)ptr; - while (num--) { - *p++ = (UInt8)value; - } - return ptr; -} - -void* memcpy(void* dest, const void* src, UInt64 n) { - UInt8* d = (UInt8*)dest; - const UInt8* s = (const UInt8*)src; - - while (n >= 8) { - *(UInt64*)d = *(const UInt64*)s; - d += 8; - s += 8; - n -= 8; - } - - while (n > 0) { - *d++ = *s++; - n--; - } - - return dest; -} - -Int32 strcmp(const char *s1, const char *s2) { - while (*s1 && (*s1 == *s2)) { - s1++; - s2++; - } - return *(const unsigned char*)s1 - *(const unsigned char*)s2; -} - -Int32 strncmp(const char* s1, const char* s2, UInt64 n) { - while (n > 0) { - if (*s1 != *s2) return *(unsigned char*)s1 - *(unsigned char*)s2; - if (*s1 == '\0') return 0; - s1++; - s2++; - n--; - } - - return 0; -} - -char* strcpy(char* dest, const char* src) { - char* saved = dest; - while (*src) *dest++ = *src++; - *dest = 0; - return saved; -} - -char* strncpy(char* dest, const char* src, UInt64 n) { - char* saved = dest; - while (*src && n > 0) { - *dest++ = *src++; - n--; - } - while (n > 0) { - *dest++ = 0; - n--; - } - return saved; -} - -UInt64 strlen(const char* str) { - UInt64 res = 0; - for (res = 0; str[res]; res++); - return res; -} - -static inline int is_in_set(char c, const char* set) { - while (*set) { - if (*set == c) return 1; - set++; - } - return 0; -} - -UInt64 strspn(const char* s, const char* accept) { - UInt64 count = 0; - while (*s && is_in_set(*s, accept)) { - count++; - s++; - } - return count; -} - -char* strpbrk(const char* s, const char* accept) { - while (*s) { - if (is_in_set(*s, accept)) { - return (char*)s; - } - s++; - } - return nullptr; -} -// took from https://github.com/walac/glibc/blob/master/string/strtok.c -char* strtok(char *s, const char* delim) { - char* token; - if (s == nullptr) s = olds; - s += strspn(s, delim); - if (*s == '\0') { - olds = s; - return nullptr; - } - - token = s; - s = strpbrk(token, delim); - if (s == nullptr) olds = token + strlen(token); - else { - *s = '\0'; - olds = s + 1; - } - - return token; -} \ No newline at end of file diff --git a/userspace/termosh/src/handlers/misc.c b/userspace/termosh/src/handlers/misc.c index 833c1e9..2f01abd 100644 --- a/userspace/termosh/src/handlers/misc.c +++ b/userspace/termosh/src/handlers/misc.c @@ -1,5 +1,5 @@ -#include +#include void not_implemented_yet() { - printf("Not implemented yet!\n"); + ConsolePrint("Not implemented yet!\n"); } \ No newline at end of file diff --git a/userspace/termosh/src/handlers/spawn.c b/userspace/termosh/src/handlers/spawn.c index beaf302..c66dfc1 100644 --- a/userspace/termosh/src/handlers/spawn.c +++ b/userspace/termosh/src/handlers/spawn.c @@ -1,16 +1,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2026 0xKarinyash -#include -#include +#include "handlers.h" +#include void cmd_spawn(const char* path) { - Int32 pid = spawn(path); + Int32 pid = ProcessSpawn(path); if (pid < 0) { switch (pid) { - case -1: printf("\"%s\" not found.\n", path); break; - default: printf("failed to spawn (%d)\n", pid); break; + case -1: ConsolePrint("\"%s\" not found.\n", path); break; + default: ConsolePrint("failed to spawn (%d)\n", pid); break; } } else { - wait(pid); + ProcessWait(pid); } } \ No newline at end of file diff --git a/userspace/termosh/src/main.c b/userspace/termosh/src/main.c index 3399702..20e6b1f 100644 --- a/userspace/termosh/src/main.c +++ b/userspace/termosh/src/main.c @@ -1,19 +1,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2026 0xKarinyash -#include "tokens.h" +#include #include "parser.h" #include "handlers.h" -#include - #define BUFFER_SIZE 512 int main() { while (true) { - printf("termosh_> "); + ConsolePrint("termosh_> "); char cmdbuff[BUFFER_SIZE]; - gets_s(cmdbuff, BUFFER_SIZE); + ConsoleReadLine(cmdbuff, BUFFER_SIZE); char* tokens[BUFFER_SIZE]; int tokens_count = tokenize(cmdbuff, tokens, BUFFER_SIZE); if (tokens_count < 1) continue; @@ -25,7 +23,7 @@ int main() { case TOKEN_SPAWN: if (tokens_count >= 2) cmd_spawn(tokens[1]); break; default: { char buff[256]; - snprintf(buff, sizeof(buff), "/System/CoreServices/%s", tokens[0]); + StringFormat(buff, sizeof(buff), "/System/CoreServices/%s", tokens[0]); cmd_spawn(buff); } } diff --git a/userspace/termosh/src/modules/parser.c b/userspace/termosh/src/modules/parser.c index a859393..5c4986f 100644 --- a/userspace/termosh/src/modules/parser.c +++ b/userspace/termosh/src/modules/parser.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2026 0xKarinyash -#include +#include #include "parser.h" #include "tokens.h" @@ -27,7 +27,7 @@ static const termosh_token_map token_map[] = { termosh_token char2token(char* token) { for (int i = 0; token_map[i].str != nullptr; i++) { - if (strcmp(token, token_map[i].str) == 0) { + if (StringCompare(token, token_map[i].str) == 0) { return token_map[i].token; } } @@ -36,12 +36,12 @@ termosh_token char2token(char* token) { } int tokenize(char* buffer, char* tokens[], int max_tokens) { - char* token = strtok(buffer, delim); + char* token = StringTokenize(buffer, delim); int i = 0; while (token != nullptr && i < max_tokens) { tokens[i] = token; - token = strtok(nullptr, delim); + token = StringTokenize(nullptr, delim); i++; }