home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
LIBSRC.ZOO
/
libsrc
/
local
/
except.c
< prev
next >
Wrap
Text File
|
1992-04-04
|
16KB
|
500 lines
#define INCL_DOSSIGNALS
#define INCL_DOSMISC
#include <os2.h>
#include <signal.h>
#include <stdio.h>
#define XSIGNAL(x) (XCPT_FATAL_EXCEPTION | XCPT_CUSTOMER_CODE | (x))
/* Signal mask for this process... initially none blocked */
int __signal_mask = 0;
/* List of actions. One for each signal */
void *__signal_proc[32] = {SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL};
/* List of masks to be used when handler is running. One for each signal */
/* zero means block the signal being delivered and leave the rest of the mask as is */
int __handler_mask[32] = {0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
static int user_handler (int);
static void GenReturnCode (int);
ULONG Dos32CreateThread() asm ("Dos32CreateThread");
ULONG Dos32WaitThread() asm ("Dos32WaitThread");
ULONG Dos32Exit() asm ("Dos32Exit");
ULONG Dos32Error() asm ("Dos32Error");
__SignalHandler(EXCEPTIONREPORTRECORD *parg)
{
switch (parg -> ExceptionNum)
{
/* SIGHUP */
case XSIGNAL(SIGHUP):
if (user_handler (SIGHUP) || __signal_proc[SIGHUP] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGHUP,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGINT */
case XSIGNAL(SIGINT):
case XCPT_SIGNAL: /* Also SIGTERM */
if (user_handler (SIGINT) || __signal_proc[SIGINT] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGINT,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
if (parg -> ExceptionNum == XSIGNAL(SIGINT))
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGQUIT */
case XSIGNAL(SIGQUIT):
if (user_handler (SIGQUIT) || __signal_proc[SIGQUIT] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGQUIT,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGILL */
case XSIGNAL(SIGILL):
case XCPT_ILLEGAL_INSTRUCTION:
if (user_handler (SIGILL) || __signal_proc[SIGILL] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGILL,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
if (parg -> ExceptionNum == XSIGNAL(SIGILL))
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGTRAP */
case XSIGNAL(SIGTRAP):
case XCPT_BREAKPOINT:
case XCPT_SINGLE_STEP:
if (user_handler (SIGTRAP) || __signal_proc[SIGTRAP] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGTRAP,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
if (parg -> ExceptionNum == XSIGNAL(SIGTRAP))
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGABRT */
case XSIGNAL(SIGABRT):
if (user_handler (SIGABRT) || __signal_proc[SIGABRT] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
fprintf (stderr, "\nabnormal program termination\n");
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGABRT,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGEMT */
case XSIGNAL(SIGEMT):
if (user_handler (SIGEMT) || __signal_proc[SIGEMT] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGEMT,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGFPE */
case XSIGNAL(SIGFPE):
case XCPT_FLOAT_DIVIDE_BY_ZERO:
case XCPT_FLOAT_INVALID_OPERATION:
case XCPT_FLOAT_OVERFLOW:
case XCPT_FLOAT_UNDERFLOW:
case XCPT_FLOAT_DENORMAL_OPERAND:
case XCPT_FLOAT_INEXACT_RESULT:
case XCPT_FLOAT_STACK_CHECK:
case XCPT_INTEGER_DIVIDE_BY_ZERO:
if (user_handler (SIGFPE) || __signal_proc[SIGFPE] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGFPE,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
if (parg -> ExceptionNum == XSIGNAL(SIGFPE))
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGKILL */
case XSIGNAL(SIGKILL):
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
/* SIGBUS */
case XSIGNAL(SIGBUS):
if (user_handler (SIGBUS) || __signal_proc[SIGBUS] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGBUS,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGSEGV */
case XSIGNAL(SIGSEGV):
case XCPT_ACCESS_VIOLATION:
if (user_handler (SIGSEGV) || __signal_proc[SIGSEGV] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGSEGV,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
if (parg -> ExceptionNum == XSIGNAL(SIGSEGV))
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGSYS */
case XSIGNAL(SIGSYS):
case XCPT_BAD_STACK:
case XCPT_INVALID_UNWIND_TARGET:
if (user_handler (SIGSYS) || __signal_proc[SIGSYS] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGSYS,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
if (parg -> ExceptionNum == XSIGNAL(SIGSYS))
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGPIPE */
case XSIGNAL(SIGPIPE):
if (user_handler (SIGPIPE) || __signal_proc[SIGPIPE] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGPIPE,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGALRM */
case XSIGNAL(SIGALRM):
if (user_handler (SIGALRM) || __signal_proc[SIGALRM] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGALRM,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGTERM */
case XSIGNAL(SIGTERM):
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
/* SIGURG */
case XSIGNAL(SIGURG):
user_handler (SIGURG);
return (XCPT_CONTINUE_EXECUTION);
/* SIGSTOP */
case XSIGNAL(SIGSTOP):
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
/* SIGTSTP */
case XSIGNAL(SIGTSTP):
if (user_handler (SIGTSTP) || __signal_proc[SIGTSTP] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGTSTP,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGCONT */
case XSIGNAL(SIGCONT):
user_handler (SIGCONT);
return (XCPT_CONTINUE_EXECUTION);
/* SIGCHLD */
case XSIGNAL(SIGCHLD):
user_handler (SIGCHLD);
return (XCPT_CONTINUE_EXECUTION);
/* SIGTTIN */
case XSIGNAL(SIGTTIN):
if (user_handler (SIGTTIN) || __signal_proc[SIGTTIN] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGTTIN,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGTTOU */
case XSIGNAL(SIGTTOU):
if (user_handler (SIGTTOU) || __signal_proc[SIGTTOU] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGTTOU,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGIO */
case XSIGNAL(SIGIO):
user_handler (SIGIO);
return (XCPT_CONTINUE_EXECUTION);
/* SIGXCPU */
case XSIGNAL(SIGXCPU):
if (user_handler (SIGXCPU) || __signal_proc[SIGXCPU] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGXCPU,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGXFSZ */
case XSIGNAL(SIGXFSZ):
if (user_handler (SIGXFSZ) || __signal_proc[SIGXFSZ] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGXFSZ,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGVTALRM */
case XSIGNAL(SIGVTALRM):
if (user_handler (SIGVTALRM) || __signal_proc[SIGVTALRM] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGVTALRM,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGPROF */
case XSIGNAL(SIGPROF):
if (user_handler (SIGPROF) || __signal_proc[SIGPROF] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGPROF,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGWINCH */
case XSIGNAL(SIGWINCH):
user_handler (SIGWINCH);
return (XCPT_CONTINUE_EXECUTION);
/* SIGINFO */
case XSIGNAL(SIGINFO):
user_handler (SIGINFO);
return (XCPT_CONTINUE_EXECUTION);
/* SIGUSR1 */
case XSIGNAL(SIGUSR1):
if (user_handler (SIGUSR1) || __signal_proc[SIGUSR1] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGUSR1,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
/* SIGUSR2 */
case XSIGNAL(SIGUSR2):
if (user_handler (SIGUSR2) || __signal_proc[SIGUSR2] == SIG_IGN)
return (XCPT_CONTINUE_EXECUTION);
else {
TID ThreadID;
Dos32CreateThread (&ThreadID,
GenReturnCode,
SIGUSR2,
0,
4096);
Dos32WaitThread (&ThreadID, 0);
Dos32Error (FERR_DISABLEEXCEPTION);
return (XCPT_CONTINUE_SEARCH);
}
case XCPT_GUARD_PAGE_VIOLATION:
case XCPT_UNABLE_TO_GROW_STACK:
case XCPT_PRIVILEGED_INSTRUCTION:
case XCPT_INTEGER_OVERFLOW:
case XCPT_DATATYPE_MISALIGNMENT:
case XCPT_IN_PAGE_ERROR:
case XCPT_NONCONTINUABLE_EXCEPTION:
case XCPT_INVALID_DISPOSITION:
case XCPT_INVALID_LOCK_SEQUENCE:
case XCPT_PROCESS_TERMINATE:
case XCPT_ASYNC_PROCESS_TERMINATE:
case XCPT_ARRAY_BOUNDS_EXCEEDED:
case XCPT_UNWIND:
default:
return (XCPT_CONTINUE_SEARCH);
}
}
static int user_handler(int sig)
{
void (*proc)(int);
if (__signal_proc[sig] == SIG_DFL || __signal_proc[sig] == SIG_IGN)
return (0);
proc = __signal_proc[sig];
proc(sig);
return (1);
}
static void GenReturnCode (int code)
{
Dos32Exit (0, code);
}