Programmers can now redirect what the errno macro refers to.

This commit is contained in:
Jonas 'Sortie' Termansen 2012-03-26 22:22:59 +02:00
parent e7baf6a4b0
commit ec5fa92761
8 changed files with 41 additions and 12 deletions

View File

@ -1,7 +1,14 @@
#ifndef _ERRNO_DECL #ifndef _ERRNO_DECL
#define _ERRNO_DECL #define _ERRNO_DECL
extern volatile int errno; /* Returns the address of the errno variable for this thread. */
#define errno errno 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 #endif

View File

@ -33,18 +33,30 @@
namespace Maxsi { namespace Maxsi {
namespace Error { 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 #ifndef SORTIX_KERNEL
DEFN_SYSCALL1(int, SysRegisterErrno, SYSCALL_REGISTER_ERRNO, int*); DEFN_SYSCALL1(int, SysRegisterErrno, SYSCALL_REGISTER_ERRNO, int*);
extern "C" void init_error_functions() extern "C" void init_error_functions()
{ {
errno = 0; global_errno = 0;
SysRegisterErrno(&errno); SysRegisterErrno(&global_errno);
} }
#endif #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) extern "C" const char* sortix_strerror(int errnum)
{ {
switch ( errnum ) switch ( errnum )

View File

@ -37,6 +37,16 @@ namespace Maxsi
{ {
inline int Last() { return errno; } inline int Last() { return errno; }
inline void Set(int error) { errno = error; } 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);
}
} }
} }

View File

@ -204,7 +204,7 @@ namespace Sortix
// Copy variables. // Copy variables.
clone->mmapfrom = mmapfrom; clone->mmapfrom = mmapfrom;
clone->errno = errno; clone->errnop = errnop;
if ( workingdir ) { clone->workingdir = String::Clone(workingdir); } if ( workingdir ) { clone->workingdir = String::Clone(workingdir); }
else { clone->workingdir = NULL; } else { clone->workingdir = NULL; }
@ -783,7 +783,7 @@ namespace Sortix
int SysRegisterErrno(int* errnop) int SysRegisterErrno(int* errnop)
{ {
CurrentProcess()->errno = errnop; CurrentProcess()->errnop = errnop;
return 0; return 0;
} }

View File

@ -76,7 +76,7 @@ namespace Sortix
int exitstatus; int exitstatus;
char* workingdir; char* workingdir;
pid_t pid; pid_t pid;
int* errno; int* errnop;
public: public:
Process* parent; Process* parent;

View File

@ -104,9 +104,9 @@ namespace Sortix
int error = Error::Last(); int error = Error::Last();
if ( !error ) { return; } if ( !error ) { return; }
Process* process = CurrentProcess(); Process* process = CurrentProcess();
if ( !process->errno ) { return; } if ( !process->errnop ) { return; }
// TODO: Validate that process->errno is in userspace memory! // 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); extern "C" size_t resume_syscall(void* scfunc, size_t scsize, size_t* scstate);

View File

@ -73,7 +73,7 @@ syscall_handler:
movl $0, system_was_incomplete movl $0, system_was_incomplete
# Reset the kernel errno. # Reset the kernel errno.
movl $0, errno movl $0, global_errno
# Make sure the requested system call is valid. # Make sure the requested system call is valid.
cmp SYSCALL_MAX, %rax cmp SYSCALL_MAX, %rax

View File

@ -59,7 +59,7 @@ syscall_handler:
movl $0, system_was_incomplete movl $0, system_was_incomplete
# Reset the kernel errno. # Reset the kernel errno.
movl $0, errno movl $0, global_errno
# Make sure the requested system call is valid. # Make sure the requested system call is valid.
cmp SYSCALL_MAX, %eax cmp SYSCALL_MAX, %eax