Commit 63f1eab

kravantokh <kravantokh@noreply.codeberg.org>
2026-08-03 12:46:10
Move linux syscall error mapping to status into syscall wrappers. Fix missing memset.
1 parent 6933fcb
datatypes/error.h
@@ -67,7 +67,7 @@ enum _ErrorReasons {
 #define TRY(...) do {             \
 	Status _res = (__VA_ARGS__); \
 	if( S_NOK(_res) ) {          \
-		return _res;             \
+		return _res;            \
 	}                            \
 } while(0)
 
memory/memory.h
@@ -50,4 +50,16 @@ Status mem_relinquish( Page *start, u32 page_count ); /* Free virtual memory ran
 Status mem_occupy( Page *start, u32 page_count ); /* Set up physical backing */
 Status mem_vacate( Page *start, u32 page_count ); /* Allow removal of physical backing */
 
+#ifdef NOTLIBC_IMPLEMENT
+
+extern void *memset( void* ptr, int value, unsigned long count );
+
+void *memset( void* ptr, int value, unsigned long count ) {
+	mem_set( ptr, count, value );
+	return ptr;
+}
+
+#endif
+
+
 #endif
platform/linux/file.h
@@ -105,81 +105,20 @@ Status File_open( const String *name, usize flags, File *out ) {
 			break;
 	}
 
-	out->fd = linux_open( &name->data[0], syscall_flags, 0666 );
-
-	if( !LINUX_SYSCALL_ERROR( out->fd ) ) {
-		return S_SUCCESS;
-	} else {
-		switch( out->fd ) {
-			case -EACCES:
-			case -EPERM:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_PERMISSION_DENIED;
-			case -EEXIST:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_ALREADY_EXISTS;
-			case -EINVAL:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_INVALID_ARGUMENT;
-			case -ENOENT:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_DOESNT_EXIST;
-			case -ENAMETOOLONG:
-				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
-			case -ENOSPC:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_NO_DISK_SPACE;
-			default:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
-		}
-	}
+	return linux_open( &name->data[0], syscall_flags, 0666, &out->fd );
 }
 
 Status File_close( File *f ) {
-	usize res = linux_close( f->fd );
-
-	if( !LINUX_SYSCALL_ERROR( res ) ) {
-		f->fd = -1;
-		return S_SUCCESS;
-	} else {
-		switch( res ) {
-			case -EBADF:
-				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
-			default:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
-		}
-	}
+	return linux_close( &f->fd );
 }
 
 
 Status File_read( const File *f, usize max_amount, usize *out_amount, u8 *out ) {
-	usize res = linux_read( f->fd, out, max_amount ); 
-	if( !LINUX_SYSCALL_ERROR(res) ) {
-		*out_amount = res;
-		return S_SUCCESS;
-	} else {
-		switch(res) {
-			case -EBADF:
-				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
-			case -EFAULT:
-				return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
-			default:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
-		}
-	}
+	return linux_read( f->fd, max_amount, out_amount, out);
 }
 
 Status File_write( const File *f, usize amount, usize *out_amount, const u8 *buf ) {
-	usize res = linux_write( f->fd, buf, amount ); 
-
-	if( !LINUX_SYSCALL_ERROR(res) ) {
-		*out_amount = res;
-		return S_SUCCESS;
-	} else {
-		switch(res) {
-			case -EBADF:
-				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
-			case -EFAULT:
-				return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
-			default:
-				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
-		}
-	}
+	return linux_write( f->fd, amount, out_amount, buf ); 
 }
 
 Status File_delete( const String *name ) {
@@ -203,20 +142,7 @@ Status File_delete( const String *name ) {
 }
 
 Status File_seek( const File *f, usize position ) {
-	usize res = linux_lseek( f->fd, position, SEEK_SET );
-
-	if( !LINUX_SYSCALL_ERROR(res) ) {
-		return S_SUCCESS;
-	} else {
-		switch( res ) {
-			case -EBADF:
-				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
-			case -EOVERFLOW:
-				return S_FAILURE | ERR_OVERFLOW;
-			default:
-				return S_FAILURE | ERR_GENERIC;
-		}
-	}
+	return linux_lseek( f->fd, position, SEEK_SET );
 }
 
 Status FileView_from_file( File *file, usize claim_amount, usize flags, FileView *out ) {
@@ -231,22 +157,24 @@ Status FileView_from_file( File *file, usize claim_amount, usize flags, FileView
 
 	/* Get filesize */
 	struct stat s = {0};
-	isize res = linux_fstat( file->fd, &s );
-
-	if( LINUX_SYSCALL_ERROR(res) ) {
-		DEBUG(breakpoint());
-		return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
-	}
+	TRY( linux_fstat( file->fd, &s ) );
 
 	out->filesize = s.st_size;
 
-	if( out->filesize != 0 ) { /* Nothing to map in an empty file */
-		res = linux_mmap( (usize)out->start, out->filesize, LINUX_PROT_READ | LINUX_PROT_WRITE, MMAP_MAP_FIXED | MMAP_MAP_SHARED, file->fd, 0 );
-		if( LINUX_SYSCALL_ERROR(res) ) {
-			DEBUG(breakpoint());
-			return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
-		}
+	void *discard;
+
+	if( out->filesize > 0 ) { /* Nothing to map in an empty file */
+		TRY( linux_mmap(
+			(usize)out->start,
+			out->filesize,
+			LINUX_PROT_READ | LINUX_PROT_WRITE,
+			MMAP_MAP_FIXED | MMAP_MAP_SHARED,
+			file->fd,
+			0,
+			&discard
+		));
 	}
+
 	/* Finalize output */
 	out->file = *file;
 	out->flags = flags;
@@ -281,26 +209,21 @@ Status FileView_extend_file( FileView *fv, usize amount ) {
 
 	usize map_start_addr = (u64)((u8*)fv->start + map_start_offset);
 
+	TRY( linux_fallocate( fv->file.fd, 0, fv->filesize, amount ) );
 
-	usize res = linux_fallocate( fv->file.fd, 0, fv->filesize, amount );
-	if( LINUX_SYSCALL_ERROR(res) ) {
-		return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
-	}
 	fv->filesize += amount;
 
-	res = linux_mmap(
+	void *discard;
+
+	TRY( linux_mmap(
 		map_start_addr,
 		fv->filesize - map_start_offset + amount,
 		LINUX_PROT_READ | LINUX_PROT_WRITE,
 		MMAP_MAP_FIXED | MMAP_MAP_SHARED,
 		fv->file.fd,
-		map_start_offset
-	);
-
-
-	if( LINUX_SYSCALL_ERROR(res) ) {
-		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_MAP_FAILURE;
-	}
+		map_start_offset,
+		&discard
+	));
 
 	return S_SUCCESS;
 }
@@ -311,10 +234,7 @@ Status FileView_destroy( FileView *fv ) {
 		fv->file.fd = -1;
 	}
 
-	usize res = linux_munmap( (usize)fv->start, fv->claimed );
-	if( LINUX_SYSCALL_ERROR(res) ) {
-		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_UNMAP_FAILURE;
-	}
+	TRY( linux_munmap( (usize)fv->start, fv->claimed ) );
 
 	fv->flags = 0;
 	fv->filesize = 0;
platform/linux/memory.h
@@ -6,12 +6,16 @@
 #include "./syscalls.h"
 
 Status mem_claim( u32 page_count, Page **ptr_out) {
-	void* res = (void*)linux_mmap( 0, page_count*sizeof(Page), LINUX_PROT_NONE, MMAP_MAP_PRIVATE | MMAP_MAP_ANONYMOUS, -1, 0 );
+	TRY( linux_mmap(
+		0,
+		page_count*sizeof(Page),
+		LINUX_PROT_NONE,
+		MMAP_MAP_PRIVATE | MMAP_MAP_ANONYMOUS,
+		-1,
+		0,
+		(void**)ptr_out
+	));
 
-	if( LINUX_SYSCALL_ERROR(res) )
-		return S_FAILURE | ERR_MEM_MAP_FAILURE;
-
-	*ptr_out = res;
 	return S_SUCCESS;
 }
 
@@ -26,29 +30,19 @@ Status mem_relinquish( Page *start, u32 page_count ) {
 }
 
 Status mem_occupy( Page *start, u32 page_count ) {
-	usize res = linux_mprotect( (usize)start, page_count*sizeof(Page), LINUX_PROT_READ | LINUX_PROT_WRITE );
-
-	if( LINUX_SYSCALL_ERROR(res) ) {
-		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETPERM_FAILURE;
-	}
+	return linux_mprotect(
+		(usize)start,
+		page_count*sizeof(Page),
+		LINUX_PROT_READ | LINUX_PROT_WRITE
+	);
 
-	return S_SUCCESS;
 }
 
 Status mem_vacate( Page *start, u32 page_count ) {
 	usize amount = page_count*sizeof(Page);
 
-	usize res = linux_mprotect( (usize)start, amount, LINUX_PROT_NONE );
-
-	if( LINUX_SYSCALL_ERROR(res) ) {
-		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETPERM_FAILURE;
-	}
-
-	res = linux_madvise( (usize)start, amount, MADV_DONTNEED);
-
-	if( LINUX_SYSCALL_ERROR(res) ) {
-		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETHINT_FAILURE;
-	}
+	TRY( linux_mprotect( (usize)start, amount, LINUX_PROT_NONE ) );
+	TRY( linux_madvise( (usize)start, amount, MADV_DONTNEED) );
 
 	return S_SUCCESS;
 }
platform/linux/syscalls.h
@@ -1,7 +1,9 @@
 #ifndef HEADER_PLATFORM_LINUX_SYSCALLS_INCLUDED
 #define HEADER_PLATFORM_LINUX_SYSCALLS_INCLUDED
 
+#include "datatypes/error.h"
 #include "platform/common/types.h"
+#include "platform/info/build.h"
 
 static inline isize linux_syscall1(usize num, usize arg1);
 static inline isize linux_syscall2(usize num, usize arg1, usize arg2);
@@ -155,13 +157,39 @@ static inline isize linux_syscall6(usize num, usize arg1, usize arg2, usize arg3
 #define ERFKILL         132 /* Operation not possible due to RF-kill */
 #define EHWPOISON       133 /* Memory page has hardware error */
 
-
-static inline isize linux_read( u32 fd, u8* buf, usize count ) {
-	return linux_syscall3( 0, fd, (usize)buf, count );
+static inline Status linux_read( u32 fd, usize max_amount, usize *out_amount, u8 *out  ) {
+	usize res = linux_syscall3( 0, fd, (usize)out, max_amount );
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		*out_amount = res;
+		return S_SUCCESS;
+	} else {
+		switch(res) {
+			case -EBADF:
+				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+			case -EFAULT:
+				return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
+			default:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+		}
+	}
 }
 
-static inline isize linux_write( u32 fd, const u8* buf, usize count ) {
-	return linux_syscall3( 1, fd, (usize)buf, count );
+static inline Status linux_write( u32 fd, usize amount, usize *out_amount, const u8 *buf ) {
+	usize res = linux_syscall3( 1, fd, (usize)buf, amount );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		*out_amount = res;
+		return S_SUCCESS;
+	} else {
+		switch(res) {
+			case -EBADF:
+				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+			case -EFAULT:
+				return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
+			default:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+		}
+	}
 }
 
 /* Copied from some header included by linux/fcntl */
@@ -190,20 +218,69 @@ static inline isize linux_write( u32 fd, const u8* buf, usize count ) {
 #define O_TMPFILE    (__O_TMPFILE | O_DIRECTORY)
 
 
-static inline isize linux_open( const u8* path, s32 flags, s32 mode ) {
-	return linux_syscall3( 2, (usize)path, (usize)flags, (usize)mode);
+static inline Status linux_open( const u8* path, s32 flags, s32 mode, s32 *out_fd ) {
+	isize res = linux_syscall3( 2, (usize)path, (usize)flags, (usize)mode);
+
+	if( !LINUX_SYSCALL_ERROR( res ) ) {
+		*out_fd = res;
+		return S_SUCCESS;
+	} else {
+		switch( res ) {
+			case -EACCES:
+			case -EPERM:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_PERMISSION_DENIED;
+			case -EEXIST:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_ALREADY_EXISTS;
+			case -EINVAL:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_INVALID_ARGUMENT;
+			case -ENOENT:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_DOESNT_EXIST;
+			case -ENAMETOOLONG:
+				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+			case -ENOSPC:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_NO_DISK_SPACE;
+			default:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+		}
+	}
 }
 
-static inline isize linux_close( u32 fd ) {
-	return linux_syscall1( 3, fd );
+static inline Status linux_close( s32 *fd ) {
+	usize res = linux_syscall1( 3, *fd );
+
+	if( !LINUX_SYSCALL_ERROR( res ) ) {
+		*fd = -1;
+		return S_SUCCESS;
+	} else {
+		switch( res ) {
+			case -EBADF:
+				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+			default:
+				return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+		}
+	}
 }
 
 #define SEEK_SET 0
 #define SEEK_CUR 1
 #define SEEK_END 2
 
-static inline isize linux_lseek( u32 fd, usize offset, usize whence ) {
-	return linux_syscall3( 8, fd, offset, whence );
+static inline Status linux_lseek( u32 fd, usize offset, usize whence ) {
+
+	usize res = linux_syscall3( 8, fd, offset, whence );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		switch( res ) {
+			case -EBADF:
+				return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+			case -EOVERFLOW:
+				return S_FAILURE | ERR_OVERFLOW;
+			default:
+				return S_FAILURE | ERR_GENERIC;
+		}
+	}
 }
 
 #if ARCH == ARCH_X86_64
@@ -242,8 +319,14 @@ static inline isize linux_stat( const char* path, struct stat *statbuf ) {
 	return linux_syscall2( 4, (usize)path, (usize)statbuf );
 }
 
-static inline isize linux_fstat( s32 fd, struct stat *statbuf ) {
-	return linux_syscall2( 5, (usize)fd, (usize)statbuf );
+static inline Status linux_fstat( s32 fd, struct stat *statbuf ) {
+	isize res = linux_syscall2( 5, (usize)fd, (usize)statbuf );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+	}
 }
 
 static inline void linux_exit( s32 exitcode ) {
@@ -265,18 +348,36 @@ static inline void linux_exit( s32 exitcode ) {
 
 #define MMAP_MAP_FAILED ((void *)-1)
 
-static inline isize linux_mmap( usize addr, usize len, usize prot, usize flags, usize fd, usize offset ) {
-	return linux_syscall6( 9, addr, len, prot, flags, fd, offset );
-}
+static inline Status linux_mmap( usize addr, usize len, usize prot, usize flags, usize fd, usize offset, void **out ) {
+	isize res = linux_syscall6( 9, addr, len, prot, flags, fd, offset );
 
-static inline isize linux_munmap( usize start, usize len ) {
-	return linux_syscall2( 11, start, len );
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		*out = (void*)res;
+		return S_SUCCESS;
+	} else {
+		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_MAP_FAILURE;
+	}
 }
 
-static inline isize linux_mprotect( usize start, usize len, usize prot ) {
-	return linux_syscall3( 10, start, len, prot );
+static inline Status linux_munmap( usize start, usize len ) {
+	isize res = linux_syscall2( 11, start, len );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_UNMAP_FAILURE;
+	}
 }
 
+static inline Status linux_mprotect( usize start, usize len, usize prot ) {
+	isize res = linux_syscall3( 10, start, len, prot );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETPERM_FAILURE;
+	}
+}
 
 #define MADV_NORMAL 0
 #define MADV_RANDOM 1
@@ -305,8 +406,14 @@ static inline isize linux_mprotect( usize start, usize len, usize prot ) {
 #define MADV_GUARD_INSTALL 102
 #define MADV_GUARD_REMOVE 103
 
-static inline isize linux_madvise( usize start, usize len, s32 behaviour ) {
-	return linux_syscall3( 11, start, len, (usize)(u32)behaviour );
+static inline Status linux_madvise( usize start, usize len, s32 behaviour ) {
+	isize res = linux_syscall3( 11, start, len, (usize)(u32)behaviour );
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETHINT_FAILURE;
+	}
 }
 
 
@@ -314,8 +421,14 @@ static inline isize linux_unlink( const u8 *path ) {
 	return linux_syscall1( 87, (usize)path );
 }
 
-static inline isize linux_fallocate( s32 fd, s32 mode, usize offset, usize len ) {
-	return linux_syscall4(285, fd, mode, offset, len);
+static inline Status linux_fallocate( s32 fd, s32 mode, usize offset, usize len ) {
+	isize res = linux_syscall4(285, fd, mode, offset, len);
+
+	if( !LINUX_SYSCALL_ERROR(res) ) {
+		return S_SUCCESS;
+	} else {
+		return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+	}
 }
 
 #endif
platform/platform.h
@@ -24,4 +24,6 @@
 	}
 #endif
 
+
+
 #endif
testing/tests/000_entry_exit.c
@@ -1,4 +1,4 @@
-#include "platform/platform.h"
+#include "notlibc/core.h"
 
 void entry(void) {
 	terminate(0);
testing/tests/001_safemath.c
@@ -1,5 +1,4 @@
-#include "platform/platform.h"
-#include "util/mathops.h"
+#include "notlibc/core.h"
 
 #define N 12
 
testing/tests/002_round.c
@@ -1,5 +1,4 @@
-#include "platform/platform.h"
-#include "util/mathops.h"
+#include "notlibc/core.h"
 
 #define N 13
 
testing/test.sh
@@ -20,7 +20,7 @@ echo
 echo Compiling tests.
 echo
 
-CFLAGS="-nostdlib -I. -DNOTLIBC_IMPLEMENT -DNOTLIBC_SILENCE -fno-builtin -g"
+CFLAGS="-nostdlib -ffreestanding -I. -DNOTLIBC_IMPLEMENT -DNOTLIBC_SILENCE -fno-builtin -g -Wall -Wextra -Wpedantic -Werror"
 
 for SRC in ./testing/tests/*.c; do