home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 10
/
AU_CD10.iso
/
Updates
/
DigitalCD
/
!DigitalCD
/
Copy
/
PowerBars
/
c
/
Exception
< prev
next >
Wrap
Text File
|
1999-01-02
|
2KB
|
107 lines
/*** exception.c ***/
/* C exception handling system
* (c) Paul Field
*/
#include "exception.h"
#include <assert.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "kernel.h"
static exception current;
_exception_block *_exception_list = NULL;
void throw(void)
{
_exception_block* first_block;
first_block = _exception_list;
if (first_block == NULL)
{
exit(EXIT_FAILURE);
}
else
{
_exception_list = first_block->previous;
longjmp(first_block->jmpbuf, 1);
}
}
void __throw_user(unsigned id, char* file , int line)
{
current.type = exception_user;
current.error.user_id = id;
current.file = file;
current.line = line;
throw();
}
void __throw_os(const _kernel_oserror* err, char* file , int line)
{
if (err == NULL) return;
current.type = exception_os;
current.error.os = err;
current.file = file;
current.line = line;
throw();
}
void __throw_last_os_error(char* file , int line)
{
current.file = file;
current.line = line;
throw_os(_kernel_last_oserror());
}
void __throw_string(char* file , int line, const char* pformat, ...)
{
va_list arg;
static _kernel_oserror err;
va_start(arg, pformat);
vsprintf(err.errmess, pformat, arg);
va_end(arg);
err.errnum = 1;
__throw_os(&err, file, line);
}
const exception* exception_current(void)
{
return ¤t;
}
static void throw_signal(int sig)
{
current.type = exception_signal;
current.error.signal_id = sig;
signal(sig, throw_signal); /* reinstate signal handler */
throw();
}
static void throw_last_os(int sig)
{
sig=sig;
signal(SIGOSERROR, throw_last_os); /* reinstate signal handler */
throw_os(_kernel_last_oserror());
}
void exception_initialise(void)
{
signal(SIGABRT, throw_signal);
signal(SIGFPE, throw_signal);
signal(SIGILL, throw_signal);
signal(SIGINT, throw_signal);
signal(SIGSEGV, throw_signal);
signal(SIGTERM, throw_signal);
/*signal(SIGSTAK, throw_signal);*/
signal(SIGOSERROR, throw_last_os);
}