Browse Source
This version of signal (which does not rely on a notion of userland processes and is thus excluded from Vhex) follows C99 semantics but does not generate any signals by default. Basically, the signal function sets up function pointers and the signal function calls them. Termination signals call exit() while other signals call _Exit(), which is a quicker program termination similar to abort(). C99 allows programs to long jump out of signal handlers (!) which is unbelievably scary because it would bypass stack switching code in Vhex as well as normal interrupt handler termination in gint.pull/2/head
10 changed files with 127 additions and 20 deletions
@ -0,0 +1,20 @@
|
||||
#ifndef __BITS_SIGNUM_H__ |
||||
# define __BITS_SIGNUM_H__ |
||||
|
||||
// Define the number of signals
|
||||
#define _NSIG 16 |
||||
|
||||
/* Fake signal functions. */ |
||||
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ |
||||
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ |
||||
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ |
||||
|
||||
/* ISO C99 signals. */ |
||||
#define SIGINT 2 /* Interactive attention signal. */ |
||||
#define SIGILL 4 /* Illegal instruction. */ |
||||
#define SIGABRT 6 /* Abnormal termination. */ |
||||
#define SIGFPE 8 /* Erroneous arithmetic operation. */ |
||||
#define SIGSEGV 11 /* Invalid access to storage. */ |
||||
#define SIGTERM 15 /* Termination request. */ |
||||
|
||||
#endif /*__BITS_SIGNUM_H__*/ |
@ -0,0 +1,35 @@
|
||||
#include <signal.h> |
||||
#include <bits/signum.h> |
||||
#include <stdlib.h> |
||||
#include "signal_p.h" |
||||
|
||||
#ifndef __SUPPORT_VHEX_KERNEL |
||||
|
||||
int raise(int sig) |
||||
{ |
||||
if(sig < 0 || sig >= _NSIG) |
||||
return 1; |
||||
|
||||
/* TODO: libc/signal: support signal masks? */ |
||||
__sighandler_t handler = signal(sig, SIG_DFL); |
||||
|
||||
if(handler == SIG_DFL) { |
||||
/* Signals that terminate */ |
||||
if(sig == SIGINT || sig == SIGTERM) { |
||||
exit(128 + sig); |
||||
} |
||||
/* Signals that abort */ |
||||
if(sig == SIGILL || sig == SIGABRT || sig == SIGFPE || |
||||
sig == SIGSEGV) { |
||||
_Exit(128 + sig); |
||||
} |
||||
} |
||||
else if(handler != SIG_IGN) { |
||||
(*handler)(sig); |
||||
} |
||||
|
||||
signal(sig, handler); |
||||
return 0; |
||||
} |
||||
|
||||
#endif /*! __SUPPORT_VHEX_KERNEL*/ |
@ -0,0 +1,19 @@
|
||||
#include <signal.h> |
||||
#include <bits/signum.h> |
||||
#include "signal_p.h" |
||||
|
||||
#ifndef __SUPPORT_VHEX_KERNEL |
||||
|
||||
__sighandler_t __signal_handlers[_NSIG] = { 0 }; |
||||
|
||||
__sighandler_t signal(int signum, __sighandler_t handler) |
||||
{ |
||||
if(signum < 0 || signum >= _NSIG) |
||||
return SIG_ERR; |
||||
|
||||
__sighandler_t prev = __signal_handlers[signum]; |
||||
__signal_handlers[signum] = handler; |
||||
return prev; |
||||
} |
||||
|
||||
#endif /*! __SUPPORT_VHEX_KERNEL*/ |
@ -0,0 +1,13 @@
|
||||
#ifndef __SIGNAL_P_H__ |
||||
# define __SIGNAL_P_H__ |
||||
|
||||
#ifdef __SUPPORT_VHEX_KERNEL |
||||
|
||||
#include <bits/signum.h> |
||||
|
||||
/* Handlers for all signals. */ |
||||
extern __sighandler_t __signal_handlers[_NSIG]; |
||||
|
||||
#endif /*! __SUPPORT_VHEX_KERNEL*/ |
||||
|
||||
#endif /*__SIGNAL_P_H__*/ |
@ -1,10 +1,11 @@
|
||||
#include <stdlib.h> |
||||
#include <bits/stdlib.h> |
||||
#include <signal.h> |
||||
|
||||
void abort(int rc) |
||||
void abort(void) |
||||
{ |
||||
/* TODO: Close BFile handles (essential) */ |
||||
|
||||
raise(SIGABRT); |
||||
/* If the signal handler ever returns, leave on our own */ |
||||
_Exit(EXIT_FAILURE); |
||||
} |
||||
|
Loading…
Reference in new issue