ref(libterm): now apple-styled too

This commit is contained in:
Karina
2026-01-31 22:47:42 +04:00
parent 2be7d3bd46
commit e21f5ef52f
37 changed files with 548 additions and 565 deletions
+11 -11
View File
@@ -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);
+7 -7
View File
@@ -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;
}
+2 -2
View File
@@ -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;
}
+7 -7
View File
@@ -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);
+2 -2
View File
@@ -4,5 +4,5 @@
#pragma once
#include <types.h>
UInt64 OSServiceWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length);
UInt64 OSServiceRead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count);
UInt64 OSServiceIOWrite(UInt64 fileDescriptor, UInt64 buffer, UInt64 length);
UInt64 OSServiceIORead(UInt64 fileDescriptor, UInt64 buffer, UInt64 count);
+1 -1
View File
@@ -4,4 +4,4 @@
#pragma once
#include <types.h>
UInt64 OSServiceMemoryGet(UInt64 size);
UInt64 OSServiceMemoryAllocate(UInt64 size);
+2 -2
View File
@@ -5,7 +5,7 @@
#include <IO/IOConsole.h>
#include <IO/IOKeyboard.h>
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++) {
+1 -1
View File
@@ -9,7 +9,7 @@
#include <VM/VMM.h>
#include <lib/String.h>
UInt64 OSServiceMemoryGet(UInt64 size) {
UInt64 OSServiceMemoryAllocate(UInt64 size) {
if (size == 0) return 0;
OSProcess* currentProcess = gOSSchedulerCurrentTask->process;
UInt64 addressToReturn = currentProcess->heapCurrentPointer;
+3 -3
View File
@@ -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);
+4 -6
View File
@@ -1,14 +1,12 @@
#include <stdio.h>
#include <process.h>
#include <types.h>
#include <termOS.h>
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);
}
}
}
+3 -4
View File
@@ -1,14 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <process.h>
#include <malloc.h>
#include <termOS.h>
// 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);
}
}
+9 -9
View File
@@ -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 $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>)
target_include_directories(term PUBLIC inc)
add_library(crt0_obj OBJECT src/crt0.asm)
target_compile_options(crt0_obj PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>)
add_library(RuntimeEntryObject OBJECT src/RuntimeEntry.asm)
target_compile_options(RuntimeEntryObject PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>)
function(add_termos_executable NAME SOURCES)
add_executable(${NAME} ${SOURCES})
target_sources(${NAME} PRIVATE $<TARGET_OBJECTS:crt0_obj>)
target_sources(${NAME} PRIVATE $<TARGET_OBJECTS:RuntimeEntryObject>)
target_compile_options(${NAME} PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>)
target_link_libraries(${NAME} PRIVATE term)
+15
View File
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <Types.h>
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);
+23
View File
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <Types.h>
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);
@@ -2,7 +2,7 @@
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
#include <Types.h>
Int32 spawn(const char* path);
Int32 wait(UInt64 pid);
Int32 ProcessSpawn(const char* path);
Int32 ProcessWait(UInt64 pid);
+16
View File
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <Types.h>
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);
-19
View File
@@ -1,19 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
#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);
-11
View File
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
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);
-16
View File
@@ -1,16 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#pragma once
#include <types.h>
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);
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <Console.h>
#include <Memory.h>
#include <Process.h>
#include <String.h>
#include <Varargs.h>
#include <Types.h>
+156
View File
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <Console.h>
#include <Varargs.h>
#include <String.h>
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;
}
+104
View File
@@ -0,0 +1,104 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
// brutally copypasting from kernel/mm/heap.c
#include <Memory.h>
#include <String.h>
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;
}
@@ -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
+15
View File
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <Process.h>
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);
}
@@ -6,9 +6,9 @@
section .text
global _start
extern main
extern sys_exit
extern OSServiceProcessExit
_start:
call main
mov rdi, rax
call sys_exit
call OSServiceProcessExit
+126
View File
@@ -0,0 +1,126 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <String.h>
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;
}
-103
View File
@@ -1,103 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
// brutally copypasting from kernel/mm/heap.c
#include <malloc.h>
#include <string.h>
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;
}
-15
View File
@@ -1,15 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <process.h>
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);
}
-185
View File
@@ -1,185 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <stdio.h>
#include <stdarg.h>
#include <types.h>
#include <string.h>
#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;
}
-126
View File
@@ -1,126 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <string.h>
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;
}
+2 -2
View File
@@ -1,5 +1,5 @@
#include <stdio.h>
#include <termOS.h>
void not_implemented_yet() {
printf("Not implemented yet!\n");
ConsolePrint("Not implemented yet!\n");
}
+6 -6
View File
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <process.h>
#include <stdio.h>
#include "handlers.h"
#include <termOS.h>
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);
}
}
+4 -6
View File
@@ -1,19 +1,17 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include "tokens.h"
#include <termOS.h>
#include "parser.h"
#include "handlers.h"
#include <stdio.h>
#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);
}
}
+4 -4
View File
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <string.h>
#include <termOS.h>
#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++;
}