This is djhandl.c in view mode; [Download] [Up]
/* * control-c and critical error handlers for DJGPP environment * * control-c code based exactly on the equivalent handler * for control-break in the go32 libraries * critical error handling from Bob Babcock. * * $Header: /usr2/foxharp/src/pgf/vile/RCS/djhandl.c,v 1.5 1995/12/31 16:25:32 pgf Exp $ * * */ #include <stdlib.h> #include <go32.h> #include <dpmi.h> #include <dos.h> #include <stdio.h> #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif static _go32_dpmi_registers regs; static volatile unsigned long ctrl_c_count = 0; static int ctrl_c_hooked = 0; static _go32_dpmi_seginfo old_vector; static _go32_dpmi_seginfo new_vector; unsigned long was_ctrl_c_hit(); void want_ctrl_c(int yes); /* auto-yes if call above function */ static void ctrl_c_isr(_go32_dpmi_registers *regs) { ctrl_c_count ++; } unsigned long was_ctrl_c_hit() { unsigned long cnt; want_ctrl_c(1); cnt = ctrl_c_count; ctrl_c_count = 0; return cnt; } void want_ctrl_c(int yes) { if (yes) { if (ctrl_c_hooked) return; _go32_dpmi_get_real_mode_interrupt_vector(0x23, &old_vector); new_vector.pm_offset = (int)ctrl_c_isr; _go32_dpmi_allocate_real_mode_callback_iret(&new_vector, ®s); _go32_dpmi_set_real_mode_interrupt_vector(0x23, &new_vector); ctrl_c_count = 0; ctrl_c_hooked = 1; } else { if (!ctrl_c_hooked) return; _go32_dpmi_set_real_mode_interrupt_vector(0x23, &old_vector); _go32_dpmi_free_real_mode_callback(&new_vector); ctrl_c_count = 0; ctrl_c_hooked = 0; } } /* hardgcc - critical error handler for gcc */ int hard_error_occurred = FALSE; static char handler[16] = { 0x81, 0xe7, 0x7f, 0, /* and di,7f */ 0x47, /* inc di */ 0x2e, 0x89, 0x3e, 0xe, 0, /* mov cs:[0eh],di */ 0xb8, 3, 0, /* mov ax,3 */ 0xcf, /* iret */ 0,0 /* storage for error code */ }; static int handler_installed = FALSE; static _go32_dpmi_seginfo new_handler_info, old_handler_info; /* clear_hard_error - clear any indication of a critical error */ void clear_hard_error(void) { short zero = 0; if(handler_installed) dosmemput(&zero, 2, new_handler_info.rm_segment * 16 + 14); hard_error_occurred = 0; return; } /* install the real-mode critical error handler */ void hard_error_catch_setup(void) { /* On first call, allocate some DOS memory and copy the handler into it */ if(!handler_installed) { handler_installed = TRUE; new_handler_info.size = old_handler_info.size = 1; if (_go32_dpmi_allocate_dos_memory(&new_handler_info) != 0) { fprintf(stderr,"Couldn't allocate handler memory\n"); exit(1); } dosmemput(handler, 16, new_handler_info.rm_segment * 16); #ifdef XDEBUG sprintf(Tempbuf, "Handler at segment %x", new_handler_info.rm_segment); error_msg(Tempbuf, 0); #endif } _go32_dpmi_get_real_mode_interrupt_vector(0x24, &old_handler_info); _go32_dpmi_set_real_mode_interrupt_vector(0x24, &new_handler_info); clear_hard_error(); return; } /* switch back to old critical error handler */ void hard_error_teardown(void) { if(handler_installed) _go32_dpmi_set_real_mode_interrupt_vector(0x24, &old_handler_info); return; } /* test_hard_err - test whether a critical error has occurred and return error code (0 if none or handler never installed). */ int did_hard_error_occur(void) { short error_code; if(handler_installed) { dosmemget(new_handler_info.rm_segment * 16 + 14, 2, &error_code); #ifdef XDEBUG if(error_code) { sprintf(Tempbuf,"Critical error code is %d", error_code); error_msg(Tempbuf,0); } #endif return(error_code); } return(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.