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
#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

View File

@ -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 )

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

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

View File

@ -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);

View File

@ -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

View File

@ -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