From ec5fa92761dd605ac9d695894782afea59b4664e Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Mon, 26 Mar 2012 22:22:59 +0200 Subject: [PATCH] Programmers can now redirect what the errno macro refers to. --- libmaxsi/decl/errno_decl.h | 11 +++++++++-- libmaxsi/error.cpp | 18 +++++++++++++++--- libmaxsi/include/libmaxsi/error.h | 10 ++++++++++ sortix/process.cpp | 4 ++-- sortix/process.h | 2 +- sortix/syscall.cpp | 4 ++-- sortix/x64/syscall.s | 2 +- sortix/x86/syscall.s | 2 +- 8 files changed, 41 insertions(+), 12 deletions(-) diff --git a/libmaxsi/decl/errno_decl.h b/libmaxsi/decl/errno_decl.h index 777a00a0..11a603cc 100644 --- a/libmaxsi/decl/errno_decl.h +++ b/libmaxsi/decl/errno_decl.h @@ -1,7 +1,14 @@ #ifndef _ERRNO_DECL #define _ERRNO_DECL -extern volatile int errno; -#define errno errno +/* Returns the address of the errno variable for this thread. */ +extern int* get_errno_location(void); + +/* get_errno_location will forward the request to a user-specified function if + specified, or if NULL, will return the global thread-shared errno value. */ +typedef int* (*errno_location_func_t)(void); +extern void set_errno_location_func(errno_location_func_t func); + +#define errno (*get_errno_location()) #endif diff --git a/libmaxsi/error.cpp b/libmaxsi/error.cpp index 188e4860..39e8dd31 100644 --- a/libmaxsi/error.cpp +++ b/libmaxsi/error.cpp @@ -33,18 +33,30 @@ namespace Maxsi { namespace Error { -extern "C" { int errno = 0; } +extern "C" { int global_errno = 0; } +extern "C" { errno_location_func_t errno_location_func = NULL; } #ifndef SORTIX_KERNEL DEFN_SYSCALL1(int, SysRegisterErrno, SYSCALL_REGISTER_ERRNO, int*); extern "C" void init_error_functions() { - errno = 0; - SysRegisterErrno(&errno); + global_errno = 0; + SysRegisterErrno(&global_errno); } #endif +extern "C" int* get_errno_location(void) +{ + if ( errno_location_func ) { return errno_location_func(); } + return &global_errno; +} + +extern "C" void set_errno_location_func(errno_location_func_t func) +{ + errno_location_func = func; +} + extern "C" const char* sortix_strerror(int errnum) { switch ( errnum ) diff --git a/libmaxsi/include/libmaxsi/error.h b/libmaxsi/include/libmaxsi/error.h index f2f9dbe8..5e0c3363 100644 --- a/libmaxsi/include/libmaxsi/error.h +++ b/libmaxsi/include/libmaxsi/error.h @@ -37,6 +37,16 @@ namespace Maxsi { inline int Last() { return errno; } inline void Set(int error) { errno = error; } + + inline int* GetErrnoLocation() + { + return get_errno_location(); + } + + inline void SetErrnoLocationFunc(errno_location_func_t func) + { + set_errno_location_func(func); + } } } diff --git a/sortix/process.cpp b/sortix/process.cpp index 280ac0dc..cc285e33 100644 --- a/sortix/process.cpp +++ b/sortix/process.cpp @@ -204,7 +204,7 @@ namespace Sortix // Copy variables. clone->mmapfrom = mmapfrom; - clone->errno = errno; + clone->errnop = errnop; if ( workingdir ) { clone->workingdir = String::Clone(workingdir); } else { clone->workingdir = NULL; } @@ -783,7 +783,7 @@ namespace Sortix int SysRegisterErrno(int* errnop) { - CurrentProcess()->errno = errnop; + CurrentProcess()->errnop = errnop; return 0; } diff --git a/sortix/process.h b/sortix/process.h index 1aab20e0..f5518706 100644 --- a/sortix/process.h +++ b/sortix/process.h @@ -76,7 +76,7 @@ namespace Sortix int exitstatus; char* workingdir; pid_t pid; - int* errno; + int* errnop; public: Process* parent; diff --git a/sortix/syscall.cpp b/sortix/syscall.cpp index a47b04ea..a98f6564 100644 --- a/sortix/syscall.cpp +++ b/sortix/syscall.cpp @@ -104,9 +104,9 @@ namespace Sortix int error = Error::Last(); if ( !error ) { return; } Process* process = CurrentProcess(); - if ( !process->errno ) { return; } + if ( !process->errnop ) { return; } // TODO: Validate that process->errno is in userspace memory! - *process->errno = error; + *process->errnop = error; } extern "C" size_t resume_syscall(void* scfunc, size_t scsize, size_t* scstate); diff --git a/sortix/x64/syscall.s b/sortix/x64/syscall.s index e97a9730..2fe79704 100644 --- a/sortix/x64/syscall.s +++ b/sortix/x64/syscall.s @@ -73,7 +73,7 @@ syscall_handler: movl $0, system_was_incomplete # Reset the kernel errno. - movl $0, errno + movl $0, global_errno # Make sure the requested system call is valid. cmp SYSCALL_MAX, %rax diff --git a/sortix/x86/syscall.s b/sortix/x86/syscall.s index f482a84a..439ffe9e 100644 --- a/sortix/x86/syscall.s +++ b/sortix/x86/syscall.s @@ -59,7 +59,7 @@ syscall_handler: movl $0, system_was_incomplete # Reset the kernel errno. - movl $0, errno + movl $0, global_errno # Make sure the requested system call is valid. cmp SYSCALL_MAX, %eax