688 lines
16 KiB
C
688 lines
16 KiB
C
#define SUPPRESS_COMPILER_INLINES
|
|
#include "std.h"
|
|
#include "file_incl.h"
|
|
#include "lpc_incl.h"
|
|
#include "backend.h"
|
|
#include "simul_efun.h"
|
|
#include "main.h"
|
|
#include "otable.h"
|
|
#include "comm.h"
|
|
#include "compiler.h"
|
|
#include "port.h"
|
|
#include "md.h"
|
|
#include "main.h"
|
|
#include "socket_efuns.h"
|
|
#include "master.h"
|
|
#include "eval.h"
|
|
|
|
port_def_t external_port[5];
|
|
|
|
static int e_flag = 0; /* Load empty, without preloads. */
|
|
int t_flag = 0; /* Disable heart beat and reset */
|
|
int comp_flag = 0; /* Trace compilations */
|
|
int max_cost;
|
|
int time_to_clean_up;
|
|
const char *default_fail_message;
|
|
time_t boot_time;
|
|
int max_array_size;
|
|
int max_buffer_size;
|
|
int max_string_length;
|
|
static int reserved_size;
|
|
char *reserved_area; /* reserved for MALLOC() */
|
|
static char *mud_lib;
|
|
|
|
double consts[NUM_CONSTS];
|
|
|
|
#ifndef NO_IP_DEMON
|
|
int no_ip_demon = 0;
|
|
void init_addr_server();
|
|
#endif /* NO_IP_DEMON */
|
|
|
|
#ifdef SIGNAL_FUNC_TAKES_INT
|
|
#define SIGPROT (int)
|
|
#define PSIG(z) z (int sig)
|
|
#else
|
|
#define SIGPROT (void)
|
|
#define PSIG(z) z()
|
|
#endif
|
|
|
|
static void CDECL sig_fpe SIGPROT;
|
|
static void CDECL sig_cld SIGPROT;
|
|
|
|
#ifdef HAS_CONSOLE
|
|
static void CDECL sig_ttin SIGPROT;
|
|
#endif
|
|
|
|
#ifdef TRAP_CRASHES
|
|
static void CDECL sig_usr1 SIGPROT;
|
|
static void CDECL sig_usr2 SIGPROT;
|
|
static void CDECL sig_term SIGPROT;
|
|
static void CDECL sig_int SIGPROT;
|
|
|
|
#ifndef DEBUG
|
|
static void CDECL sig_hup SIGPROT,
|
|
CDECL sig_abrt SIGPROT,
|
|
CDECL sig_segv SIGPROT,
|
|
CDECL sig_ill SIGPROT,
|
|
CDECL sig_bus SIGPROT,
|
|
CDECL sig_iot SIGPROT;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef DEBUG_MACRO
|
|
/* used by debug.h: please leave this in here -- Tru (you can change its
|
|
value if you like).
|
|
*/
|
|
int debug_level = 0;
|
|
#endif
|
|
|
|
int main (int argc, char ** argv)
|
|
{
|
|
time_t tm;
|
|
int i, new_mudlib = 0, got_defaults = 0;
|
|
char *p;
|
|
char version_buf[80];
|
|
#if 0
|
|
int dtablesize;
|
|
#endif
|
|
error_context_t econ;
|
|
|
|
#ifdef PROTO_TZSET
|
|
void tzset();
|
|
#endif
|
|
|
|
#ifdef INCL_LOCALE_H
|
|
setlocale(LC_ALL, "C");
|
|
#endif
|
|
|
|
#if !defined(__SASC) && (defined(AMITCP) || defined(AS225))
|
|
amiga_sockinit();
|
|
atexit(amiga_sockexit);
|
|
#endif
|
|
#ifdef WRAPPEDMALLOC
|
|
wrappedmalloc_init();
|
|
#endif /* WRAPPEDMALLOC */
|
|
#ifdef DEBUGMALLOC
|
|
MDinit();
|
|
#endif
|
|
|
|
#if (defined(PROFILING) && !defined(PROFILE_ON) && defined(HAS_MONCONTROL))
|
|
moncontrol(0);
|
|
#endif
|
|
#ifdef USE_TZSET
|
|
tzset();
|
|
#endif
|
|
boot_time = get_current_time();
|
|
|
|
const0.type = T_NUMBER;
|
|
const0.u.number = 0;
|
|
const1.type = T_NUMBER;
|
|
const1.u.number = 1;
|
|
|
|
/* const0u used by undefinedp() */
|
|
const0u.type = T_NUMBER;
|
|
const0u.subtype = T_UNDEFINED;
|
|
const0u.u.number = 0;
|
|
|
|
//fake_prog.program_size = 0; //0 anyway
|
|
|
|
/*
|
|
* Check that the definition of EXTRACT_UCHAR() is correct.
|
|
*/
|
|
p = (char *) &i;
|
|
*p = -10;
|
|
if (EXTRACT_UCHAR(p) != 0x100 - 10) {
|
|
fprintf(stderr, "Bad definition of EXTRACT_UCHAR() in interpret.h.\n");
|
|
exit(-1);
|
|
}
|
|
|
|
/*
|
|
* An added test: can we do EXTRACT_UCHAR(x++)?
|
|
* (read_number, etc uses it)
|
|
*/
|
|
p = (char *) &i;
|
|
(void) EXTRACT_UCHAR(p++);
|
|
if ((p - (char *) &i) != 1) {
|
|
fprintf(stderr, "EXTRACT_UCHAR() in interpret.h evaluates its argument more than once.\n");
|
|
exit(-1);
|
|
}
|
|
|
|
/*
|
|
* Check the living hash table size
|
|
*/
|
|
if (CFG_LIVING_HASH_SIZE != 4 && CFG_LIVING_HASH_SIZE != 16 &&
|
|
CFG_LIVING_HASH_SIZE != 64 && CFG_LIVING_HASH_SIZE != 256 &&
|
|
CFG_LIVING_HASH_SIZE != 1024 && CFG_LIVING_HASH_SIZE != 4096) {
|
|
fprintf(stderr, "CFG_LIVING_HASH_SIZE in options.h must be one of 4, 16, 64, 256, 1024, 4096, ...\n");
|
|
exit(-1);
|
|
}
|
|
|
|
#ifdef RAND
|
|
srand(get_current_time());
|
|
#else
|
|
# ifdef DRAND48
|
|
srand48(get_current_time());
|
|
# else
|
|
# ifdef RANDOM
|
|
srandom(get_current_time());
|
|
# else
|
|
fprintf(stderr, "Warning: no random number generator specified!\n");
|
|
# endif
|
|
# endif
|
|
#endif
|
|
current_time = get_current_time();
|
|
/*
|
|
* Initialize the microsecond clock.
|
|
*/
|
|
init_usec_clock();
|
|
|
|
/* read in the configuration file */
|
|
|
|
got_defaults = 0;
|
|
for (i = 1; (i < argc) && !got_defaults; i++) {
|
|
if (argv[i][0] != '-') {
|
|
set_defaults(argv[i]);
|
|
got_defaults = 1;
|
|
}
|
|
}
|
|
get_version(version_buf);
|
|
if (!got_defaults) {
|
|
fprintf(stderr, "%s for %s.\n", version_buf, ARCH);
|
|
fprintf(stderr, "You must specify the configuration filename as an argument.\n");
|
|
exit(-1);
|
|
}
|
|
|
|
printf("Initializing internal tables....\n");
|
|
init_strings(); /* in stralloc.c */
|
|
init_otable(); /* in otable.c */
|
|
init_identifiers(); /* in lex.c */
|
|
init_locals(); /* in compiler.c */
|
|
|
|
/*
|
|
* If our estimate is larger than FD_SETSIZE, then we need more file
|
|
* descriptors than the operating system can handle. This is a problem
|
|
* that can be resolved by decreasing MAX_USERS, MAX_EFUN_SOCKS, or both.
|
|
*
|
|
* Unfortunately, since neither MAX_USERS or MAX_EFUN_SOCKS exist any more,
|
|
* we have no clue how many we will need. This code really should be
|
|
* moved to places where ENFILE/EMFILE is returned.
|
|
*/
|
|
#if 0
|
|
if (dtablesize > FD_SETSIZE) {
|
|
fprintf(stderr, "Warning: File descriptor requirements exceed system capacity!\n");
|
|
fprintf(stderr, " Configuration exceeds system capacity by %d descriptor(s).\n",
|
|
dtablesize - FD_SETSIZE);
|
|
}
|
|
#ifdef HAS_SETDTABLESIZE
|
|
/*
|
|
* If the operating system supports setdtablesize() then we can request
|
|
* the number of file descriptors we really need. First check to see if
|
|
* wee already have enough. If so dont bother the OS. If not, attempt to
|
|
* allocate the number we estimated above. There are system imposed
|
|
* limits on file descriptors, so we may not get as many as we asked for.
|
|
* Check to make sure we get enough.
|
|
*/
|
|
if (getdtablesize() < dtablesize)
|
|
if (setdtablesize(dtablesize) < dtablesize) {
|
|
fprintf(stderr, "Warning: Could not allocate enough file descriptors!\n");
|
|
fprintf(stderr, " setdtablesize() could not allocate %d descriptor(s).\n",
|
|
getdtablesize() - dtablesize);
|
|
}
|
|
/*
|
|
* Just be polite and tell the administrator how many he has.
|
|
*/
|
|
fprintf(stderr, "%d file descriptors were allocated, (%d were requested).\n",
|
|
getdtablesize(), dtablesize);
|
|
#endif
|
|
#endif
|
|
time_to_clean_up = TIME_TO_CLEAN_UP;
|
|
max_cost = MAX_COST;
|
|
reserved_size = RESERVED_SIZE;
|
|
max_array_size = MAX_ARRAY_SIZE;
|
|
if(max_array_size > 2147483647){
|
|
fprintf(stderr, "Maximum array size can not exceed 65535");
|
|
max_array_size = 2147483647;
|
|
}
|
|
max_buffer_size = MAX_BUFFER_SIZE;
|
|
max_string_length = MAX_STRING_LENGTH;
|
|
mud_lib = (char *) MUD_LIB;
|
|
set_inc_list(INCLUDE_DIRS);
|
|
if (reserved_size > 0)
|
|
reserved_area = (char *) DMALLOC(reserved_size, TAG_RESERVED, "main.c: reserved_area");
|
|
for (i = 0; i < sizeof consts / sizeof consts[0]; i++)
|
|
consts[i] = exp(-i / 900.0);
|
|
reset_machine(1);
|
|
/*
|
|
* The flags are parsed twice ! The first time, we only search for the -m
|
|
* flag, which specifies another mudlib, and the D-flags, so that they
|
|
* will be available when compiling master.c.
|
|
*/
|
|
for (i = 1; i < argc; i++) {
|
|
if (argv[i][0] != '-')
|
|
continue;
|
|
switch (argv[i][1]) {
|
|
case 'D':
|
|
if (argv[i][2]) {
|
|
lpc_predef_t *tmp = ALLOCATE(lpc_predef_t, TAG_PREDEFINES,
|
|
"predef");
|
|
tmp->flag = argv[i] + 2;
|
|
tmp->next = lpc_predefs;
|
|
lpc_predefs = tmp;
|
|
continue;
|
|
}
|
|
fprintf(stderr, "Illegal flag syntax: %s\n", argv[i]);
|
|
exit(-1);
|
|
case 'N':
|
|
no_ip_demon++;
|
|
continue;
|
|
#ifdef HAS_CONSOLE
|
|
case 'C':
|
|
has_console = 1;
|
|
continue;
|
|
#endif
|
|
#ifdef YYDEBUG
|
|
case 'y':
|
|
yydebug = 1;
|
|
continue;
|
|
#endif /* YYDEBUG */
|
|
case 'm':
|
|
mud_lib = alloc_cstring(argv[i] + 2, "mudlib dir");
|
|
if (chdir(mud_lib) == -1) {
|
|
fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib);
|
|
exit(-1);
|
|
}
|
|
new_mudlib = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!new_mudlib && chdir(mud_lib) == -1) {
|
|
fprintf(stderr, "Bad mudlib directory: %s\n", mud_lib);
|
|
exit(-1);
|
|
}
|
|
time(&tm);
|
|
debug_message("----------------------------------------------------------------------------\n%s (%s) starting up on %s - %s\n\n", MUD_NAME, version_buf, ARCH, ctime(&tm));
|
|
|
|
add_predefines();
|
|
#ifdef WIN32
|
|
_tzset();
|
|
#endif
|
|
|
|
#ifndef NO_IP_DEMON
|
|
if (!no_ip_demon && ADDR_SERVER_IP)
|
|
init_addr_server(ADDR_SERVER_IP, ADDR_SERVER_PORT);
|
|
#endif /* NO_IP_DEMON */
|
|
|
|
save_context(&econ);
|
|
if (SETJMP(econ.context)) {
|
|
debug_message("The simul_efun (%s) and master (%s) objects must be loadable.\n",
|
|
SIMUL_EFUN, MASTER_FILE);
|
|
exit(-1);
|
|
} else {
|
|
init_simul_efun(SIMUL_EFUN);
|
|
init_master();
|
|
}
|
|
set_eval(max_cost);
|
|
pop_context(&econ);
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
if (argv[i][0] != '-') {
|
|
continue;
|
|
} else {
|
|
/*
|
|
* Look at flags. -m and -o has already been tested.
|
|
*/
|
|
switch (argv[i][1]) {
|
|
case 'D':
|
|
case 'N':
|
|
case 'm':
|
|
case 'y':
|
|
case 'C':
|
|
continue;
|
|
case 'f':
|
|
save_context(&econ);
|
|
if (SETJMP(econ.context)) {
|
|
debug_message("Error while calling master::flag(\"%s\"), aborting ...\n", argv[i] + 2);
|
|
exit(-1);
|
|
}
|
|
push_constant_string(argv[i] + 2);
|
|
apply_master_ob(APPLY_FLAG, 1);
|
|
if (MudOS_is_being_shut_down) {
|
|
debug_message("Shutdown by master object.\n");
|
|
exit(0);
|
|
}
|
|
pop_context(&econ);
|
|
continue;
|
|
case 'e':
|
|
e_flag++;
|
|
continue;
|
|
case 'p':
|
|
external_port[0].port = atoi(argv[i] + 2);
|
|
continue;
|
|
case 'd':
|
|
#ifdef DEBUG_MACRO
|
|
if (argv[i][2])
|
|
debug_level_set(&argv[i][2]);
|
|
else
|
|
debug_level |= DBG_d_flag;
|
|
#else
|
|
debug_message("Driver must be compiled with DEBUG_MACRO on to use -d.\n");
|
|
#endif
|
|
break;
|
|
case 'c':
|
|
comp_flag++;
|
|
continue;
|
|
case 't':
|
|
t_flag++;
|
|
continue;
|
|
default:
|
|
debug_message("Unknown flag: %s\n", argv[i]);
|
|
exit(-1);
|
|
}
|
|
}
|
|
}
|
|
if (MudOS_is_being_shut_down)
|
|
exit(1);
|
|
if (*(DEFAULT_FAIL_MESSAGE)) {
|
|
char buf[8192];
|
|
|
|
strcpy(buf, DEFAULT_FAIL_MESSAGE);
|
|
strcat(buf, "\n");
|
|
default_fail_message = make_shared_string(buf);
|
|
} else
|
|
default_fail_message = "What?\n";
|
|
#ifdef PACKAGE_MUDLIB_STATS
|
|
restore_stat_files();
|
|
#endif
|
|
preload_objects(e_flag);
|
|
#ifdef SIGFPE
|
|
signal(SIGFPE, sig_fpe);
|
|
#endif
|
|
#ifdef TRAP_CRASHES
|
|
#ifdef SIGUSR1
|
|
signal(SIGUSR1, sig_usr1);
|
|
#endif
|
|
#ifdef SIGUSR2
|
|
signal(SIGUSR2, sig_usr2);
|
|
#endif
|
|
signal(SIGTERM, sig_term);
|
|
signal(SIGINT, sig_int);
|
|
#ifndef DEBUG
|
|
#if defined(SIGABRT)
|
|
signal(SIGABRT, sig_abrt);
|
|
#endif
|
|
#ifdef SIGIOT
|
|
signal(SIGIOT, sig_iot);
|
|
#endif
|
|
#ifdef SIGHUP
|
|
signal(SIGHUP, sig_hup);
|
|
#endif
|
|
#ifdef SIGBUS
|
|
signal(SIGBUS, sig_bus);
|
|
#endif
|
|
signal(SIGSEGV, sig_segv);
|
|
signal(SIGILL, sig_ill);
|
|
#endif /* DEBUG */
|
|
#endif
|
|
#ifndef WIN32
|
|
#ifdef USE_BSD_SIGNALS
|
|
signal(SIGCHLD, sig_cld);
|
|
#else
|
|
signal(SIGCLD, sig_cld);
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef HAS_CONSOLE
|
|
if(has_console >= 0)
|
|
signal(SIGTTIN, sig_ttin);
|
|
signal(SIGTTOU, SIG_IGN);
|
|
#endif
|
|
|
|
backend();
|
|
return 0;
|
|
}
|
|
|
|
#ifdef DEBUGMALLOC
|
|
char *int_string_copy (const char * const str, char * desc)
|
|
#else
|
|
char *int_string_copy (const char * const str)
|
|
#endif
|
|
{
|
|
char *p;
|
|
int len;
|
|
|
|
DEBUG_CHECK(!str, "Null string passed to string_copy.\n");
|
|
len = strlen(str);
|
|
if (len > max_string_length) {
|
|
len = max_string_length;
|
|
p = new_string(len, desc);
|
|
(void) strncpy(p, str, len);
|
|
p[len] = '\0';
|
|
} else {
|
|
p = new_string(len, desc);
|
|
(void) strncpy(p, str, len + 1);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
#ifdef DEBUGMALLOC
|
|
char *int_string_unlink (const char * str, char * desc)
|
|
#else
|
|
char *int_string_unlink (const char * str)
|
|
#endif
|
|
{
|
|
malloc_block_t *mbt, *newmbt;
|
|
|
|
mbt = ((malloc_block_t *)str) - 1;
|
|
mbt->ref--;
|
|
|
|
if (mbt->size == USHRT_MAX) {
|
|
int l = strlen(str + USHRT_MAX) + USHRT_MAX; /* ouch */
|
|
|
|
newmbt = (malloc_block_t *)DXALLOC(l + sizeof(malloc_block_t) + 1, TAG_MALLOC_STRING, desc);
|
|
memcpy((char *)(newmbt + 1), (char *)(mbt + 1), l+1);
|
|
newmbt->size = USHRT_MAX;
|
|
ADD_NEW_STRING(USHRT_MAX, sizeof(malloc_block_t));
|
|
} else {
|
|
newmbt = (malloc_block_t *)DXALLOC(mbt->size + sizeof(malloc_block_t) + 1, TAG_MALLOC_STRING, desc);
|
|
memcpy((char *)(newmbt + 1), (char *)(mbt + 1), mbt->size+1);
|
|
newmbt->size = mbt->size;
|
|
ADD_NEW_STRING(mbt->size, sizeof(malloc_block_t));
|
|
}
|
|
newmbt->ref = 1;
|
|
CHECK_STRING_STATS;
|
|
|
|
return (char *)(newmbt + 1);
|
|
}
|
|
|
|
static FILE *debug_message_fp = 0;
|
|
|
|
void debug_message (const char *fmt, ...)
|
|
{
|
|
static char deb_buf[1024];
|
|
static char *deb = deb_buf;
|
|
va_list args;
|
|
|
|
if (!debug_message_fp) {
|
|
/*
|
|
* check whether config file specified this option
|
|
*/
|
|
if (strlen(DEBUG_LOG_FILE))
|
|
snprintf(deb, 1023, "%s/%s", LOG_DIR, DEBUG_LOG_FILE);
|
|
else
|
|
snprintf(deb, 1023, "%s/debug.log", LOG_DIR);
|
|
deb[1023] = 0;
|
|
while (*deb == '/')
|
|
deb++;
|
|
debug_message_fp = fopen(deb, "w");
|
|
if (!debug_message_fp) {
|
|
/* darn. We're in trouble */
|
|
perror(deb);
|
|
abort();
|
|
}
|
|
}
|
|
|
|
V_START(args, fmt);
|
|
V_VAR(char *, fmt, args);
|
|
vfprintf(debug_message_fp, fmt, args);
|
|
fflush(debug_message_fp);
|
|
va_end(args);
|
|
V_START(args, fmt);
|
|
V_VAR(char *, fmt, args);
|
|
vfprintf(stderr, fmt, args);
|
|
fflush(stderr);
|
|
va_end(args);
|
|
}
|
|
|
|
int slow_shut_down_to_do = 0;
|
|
|
|
char *xalloc (int size)
|
|
{
|
|
char *p;
|
|
const char *t;
|
|
static int going_to_exit;
|
|
|
|
if (going_to_exit)
|
|
exit(3);
|
|
#ifdef DEBUG
|
|
if (size == 0)
|
|
fatal("Tried to allocate 0 bytes.\n");
|
|
#endif
|
|
p = (char *) DMALLOC(size, TAG_MISC, "main.c: xalloc");
|
|
if (p == 0) {
|
|
if (reserved_area) {
|
|
FREE(reserved_area);
|
|
t = "Temporarily out of MEMORY. Freeing reserve.\n";
|
|
write(1, t, strlen(t));
|
|
reserved_area = 0;
|
|
slow_shut_down_to_do = 6;
|
|
return xalloc(size);/* Try again */
|
|
}
|
|
going_to_exit = 1;
|
|
fatal("Totally out of MEMORY.\n");
|
|
}
|
|
return p;
|
|
}
|
|
|
|
static void CDECL PSIG(sig_cld)
|
|
{
|
|
#ifndef WIN32
|
|
int status;
|
|
#ifdef USE_BSD_SIGNALS
|
|
while (wait3(&status, WNOHANG, NULL) > 0)
|
|
;
|
|
#else
|
|
wait(&status);
|
|
signal(SIGCLD, sig_cld);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
static void CDECL PSIG(sig_fpe)
|
|
{
|
|
signal(SIGFPE, sig_fpe);
|
|
}
|
|
|
|
#ifdef HAS_CONSOLE
|
|
void restore_sigttin(void) {
|
|
if(has_console >= 0)
|
|
signal(SIGTTIN, sig_ttin);
|
|
}
|
|
|
|
/* The console goes to sleep when backgrounded and can
|
|
* be woken back up with kill -SIGTTIN <pid>
|
|
*/
|
|
static void CDECL PSIG(sig_ttin)
|
|
{ char junk[1024];
|
|
int fl;
|
|
|
|
has_console = !has_console;
|
|
|
|
signal(SIGTTIN, SIG_IGN);
|
|
|
|
if(has_console) {
|
|
/* now eat all the gibberish they typed in the console when it was dead */
|
|
fl = fcntl(STDIN_FILENO, F_GETFL);
|
|
fcntl(STDIN_FILENO, F_SETFL, fl | O_NONBLOCK);
|
|
|
|
while(read(STDIN_FILENO, junk, 1023) > 0); /* ; */
|
|
|
|
/* leaving the output nonblocking is a bad idea. large outputs tend
|
|
to get truncated.
|
|
*/
|
|
fcntl(STDIN_FILENO, F_SETFL, fl);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef TRAP_CRASHES
|
|
|
|
/* send this signal when the machine is about to reboot. The script
|
|
which restarts the MUD should take an exit code of 1 to mean don't
|
|
restart
|
|
*/
|
|
|
|
static void CDECL PSIG(sig_usr1)
|
|
{
|
|
push_constant_string("Host machine shutting down");
|
|
push_undefined();
|
|
push_undefined();
|
|
apply_master_ob(APPLY_CRASH, 3);
|
|
debug_message("Received SIGUSR1, calling exit(-1)\n");
|
|
exit(-1);
|
|
}
|
|
|
|
/* Abort evaluation */
|
|
static void CDECL PSIG(sig_usr2)
|
|
{
|
|
outoftime = 1;
|
|
}
|
|
|
|
/*
|
|
* Actually, doing all this stuff from a signal is probably illegal
|
|
* -Beek
|
|
*/
|
|
static void CDECL PSIG(sig_term)
|
|
{
|
|
fatal("Process terminated");
|
|
}
|
|
|
|
static void CDECL PSIG(sig_int)
|
|
{
|
|
fatal("Process interrupted");
|
|
}
|
|
|
|
#ifndef DEBUG
|
|
static void CDECL PSIG(sig_segv)
|
|
{
|
|
fatal("Segmentation fault");
|
|
}
|
|
|
|
static void CDECL PSIG(sig_bus)
|
|
{
|
|
fatal("Bus error");
|
|
}
|
|
|
|
static void CDECL PSIG(sig_ill)
|
|
{
|
|
fatal("Illegal instruction");
|
|
}
|
|
|
|
static void CDECL PSIG(sig_hup)
|
|
{
|
|
fatal("Hangup!");
|
|
}
|
|
|
|
static void CDECL PSIG(sig_abrt)
|
|
{
|
|
fatal("Aborted");
|
|
}
|
|
|
|
static void CDECL PSIG(sig_iot)
|
|
{
|
|
fatal("Aborted(IOT)");
|
|
}
|
|
#endif /* !DEBUG */
|
|
|
|
#endif /* TRAP_CRASHES */
|