/* * I haven't tested the signals in UNIX, yet..., Frank. * * Instead of the Abort, Retry, Ignore thing, let's try to handle critical * errors within tde. Give the user some indication of the critical error * and then find out what the user wants to do. * * If we are in a unix environment, lets map signals to our DOS critical * error handler. * * IMPORTANT: This is a replacement for the standard DOS critical error * handler. Since DOS is not re-entrant, do not call any functions that, * directly or indirectly, call DOS functions. We are in some DOS function * when a critical error occurs. Using BIOS and direct hardware I/O * functions, however, is allowed. * * The prototype for the critical error handler is * * int FAR crit_err_handler( void ) * * The handler is explicitly declared as "FAR", because the assembly * routine is hard coded for a "FAR" function. See the bottom of * int24.asm for more info. * * See (incidentally, these are the current references for MSDOS 6.0): * * Microsoft Knowledge Base, "Action Taken on Abort, Retry, Ignore, Fail", * Microsoft Corporation, Redmond, Wash., 1992, Document Number: Q67586, * Publication Date: March 24, 1993. * * Microsoft Knowledge Base, "Extended Error Code Information", * Microsoft Corporation, Redmond, Wash., 1992, Document Number: Q74463, * Publication Date: March 24, 1993. * * Programmer's Reference Manual, Microsoft Corporation, Redmond, * Washington, 1986, Document No. 410630014-320-003-1285, pp. 1-20 thru * 1-21, pp. 1-34 thru 1-38, p 1-99, pp. 1-121 thru 1-124, pp. 1-216 thru * 1-218, pp. 2-1 thru 2-30. * * Ray Duncan, _Advanced MS-DOS_, Microsoft Press, Redmond, Washington, * 1986, ISBN 0-914845-77-2, pp 89-97, pp 130-133. * * * New editor name: TDE, the Thomson-Davis Editor. * Author: Frank Davis * Date: June 5, 1991, version 1.0 * Date: July 29, 1991, version 1.1 * Date: October 5, 1991, version 1.2 * Date: January 20, 1992, version 1.3 * Date: February 17, 1992, version 1.4 * Date: April 1, 1992, version 1.5 * Date: June 5, 1992, version 2.0 * Date: October 31, 1992, version 2.1 * Date: April 1, 1993, version 2.2 * Date: June 5, 1993, version 3.0 * Date: August 29, 1993, version 3.1 * Date: November 13, 1993, version 3.2 * Date: June 5, 1994, version 4.0 * * This code is released into the public domain, Frank Davis. * You may distribute it freely. */ #include "tdestr.h" #include "common.h" #include "tdefunc.h" #include "criterr.h" #if defined( __UNIX__ ) #include #endif /* * Save the area of the screen that will display the Critical * Error info. CEH_WIDTH and CEH_HEIGHT are the dimensions of critical * error screen in criterr.h. CEH_OFFSET is the offset into the screen * refresh buffer. Let the compiler calculate the offset, 'cause the offset * don't change anyway. */ #define CEH_ROW 5 #define CEH_COL 6 #define CEH_WIDTH 69 #define CEH_HEIGHT 15 #define CEH_OFFSET ((CEH_ROW * 160) + (CEH_COL * 2)) #define NEXT_LINE 160 #if defined( __UNIX__ ) /* ********************************************************************** ****************************** PART 1 ****************************** ********************************************************************** * * Let's try to make unix have the look and feel of a PC. */ /* * buffer for ceh info screen. make this a chtype array */ chtype ceh_buffer[CEH_HEIGHT][CEH_WIDTH]; /* chtype is defined in curses.h */ /* * Name: crit_err_handler * Purpose: Show user something is wrong and get a response * Date: November 13, 1993 * Notes: I noticed that some signals in Linux */ void crit_err_handler( int sig ) { int attr; int rc; int c; int action; attr = g_display.help_color; save_area( (chtype *)ceh_buffer ); show_error_screen( CEH_ROW, CEH_COL ); switch (sig) { case SIGABRT : s_output( sigabrt_1, 8, 23, attr ); s_output( sigabrt_2, 9, 23, attr ); s_output( sigabrt_3, 10, 23, attr ); break; case SIGALRM : s_output( sigalrm_1, 8, 23, attr ); s_output( sigalrm_2, 9, 23, attr ); break; case SIGCHLD : s_output( sigchld_1, 8, 23, attr ); s_output( sigchld_2, 9, 23, attr ); s_output( sigchld_3, 10, 23, attr ); s_output( sigchld_4, 11, 23, attr ); break; case SIGCONT : s_output( sigcont_1, 8, 23, attr ); s_output( sigcont_2, 9, 23, attr ); s_output( sigcont_3, 10, 23, attr ); s_output( sigcont_4, 11, 23, attr ); break; case SIGFPE : s_output( sigfpe_1, 8, 23, attr ); s_output( sigfpe_2, 9, 23, attr ); s_output( sigfpe_3, 10, 23, attr ); break; case SIGHUP : s_output( sighup_1, 8, 23, attr ); s_output( sighup_2, 9, 23, attr ); s_output( sighup_3, 10, 23, attr ); break; case SIGILL : s_output( sigill_1, 8, 23, attr ); s_output( sigill_2, 9, 23, attr ); s_output( sigill_3, 10, 23, attr ); break; case SIGINT : s_output( sigint_1, 8, 23, attr ); s_output( sigint_2, 9, 23, attr ); s_output( sigint_3, 10, 23, attr ); break; case SIGIO : s_output( sigio_1, 8, 23, attr ); s_output( sigio_2, 9, 23, attr ); s_output( sigio_3, 10, 23, attr ); break; /* * SIGIOT and SIGABRT share same signal in linux????, Frank * case SIGIOT : s_output( sigiot_1, 8, 23, attr ); s_output( sigiot_2, 9, 23, attr ); s_output( sigiot_3, 10, 23, attr ); break; */ case SIGKILL : s_output( sigkill_1, 8, 23, attr ); s_output( sigkill_2, 9, 23, attr ); s_output( sigkill_3, 10, 23, attr ); break; case SIGPIPE : s_output( sigpipe_1, 8, 23, attr ); s_output( sigpipe_2, 9, 23, attr ); s_output( sigpipe_3, 10, 23, attr ); break; /* * SIGPOLL, SIGIO, and SIGURG share the same signal in linux???, Frank * case SIGPOLL : s_output( sigpoll_1, 8, 23, attr ); s_output( sigpoll_2, 9, 23, attr ); break; */ /* * is TDE supposed to catch profiler signals? case SIGPROF : break; */ case SIGPWR : s_output( sigpwr_1, 8, 23, attr ); s_output( sigpwr_2, 9, 23, attr ); s_output( sigpwr_3, 10, 23, attr ); break; case SIGQUIT : s_output( sigquit_1, 8, 23, attr ); s_output( sigquit_2, 9, 23, attr ); s_output( sigquit_3, 10, 23, attr ); break; case SIGSEGV : s_output( sigsegv_1, 8, 23, attr ); s_output( sigsegv_2, 9, 23, attr ); s_output( sigsegv_3, 10, 23, attr ); break; case SIGSTOP : s_output( sigstop_1, 8, 23, attr ); s_output( sigstop_2, 9, 23, attr ); s_output( sigstop_3, 10, 23, attr ); break; case SIGTERM : s_output( sigterm_1, 8, 23, attr ); s_output( sigterm_2, 9, 23, attr ); s_output( sigterm_3, 10, 23, attr ); break; case SIGTRAP : s_output( sigtrap_1, 8, 23, attr ); s_output( sigtrap_2, 9, 23, attr ); s_output( sigtrap_3, 10, 23, attr ); break; case SIGTSTP : s_output( sigtstp_1, 8, 23, attr ); s_output( sigtstp_2, 9, 23, attr ); s_output( sigtstp_3, 10, 23, attr ); break; case SIGTTIN : s_output( sigttin_1, 8, 23, attr ); s_output( sigttin_2, 9, 23, attr ); s_output( sigttin_3, 10, 23, attr ); break; case SIGTTOU : s_output( sigttou_1, 8, 23, attr ); s_output( sigttou_2, 9, 23, attr ); s_output( sigttou_3, 10, 23, attr ); break; /* * SIGPOLL, SIGIO, and SIGURG share the same signal in linux???, Frank * case SIGURG : s_output( sigurg_1, 8, 23, attr ); s_output( sigurg_2, 9, 23, attr ); s_output( sigurg_3, 10, 23, attr ); break; */ case SIGUSR1 : s_output( sigusr1_1, 8, 23, attr ); s_output( sigusr1_2, 9, 23, attr ); s_output( sigusr1_3, 10, 23, attr ); break; case SIGUSR2 : s_output( sigusr2_1, 8, 23, attr ); s_output( sigusr2_2, 9, 23, attr ); s_output( sigusr2_3, 10, 23, attr ); break; case SIGVTALRM : s_output( sigvtalrm_1, 8, 23, attr ); s_output( sigvtalrm_2, 9, 23, attr ); break; case SIGWINCH : s_output( sigwinch_1, 8, 23, attr ); s_output( sigwinch_2, 9, 23, attr ); s_output( sigwinch_3, 10, 23, attr ); break; case SIGXCPU : s_output( sigxcpu_1, 8, 23, attr ); s_output( sigxcpu_2, 9, 23, attr ); s_output( sigxcpu_3, 10, 23, attr ); break; case SIGXFSZ : s_output( sigxfsz_1, 8, 23, attr ); s_output( sigxfsz_2, 9, 23, attr ); s_output( sigxfsz_3, 10, 23, attr ); break; default : break; } xygoto( 60, 17 ); do c = getanswerkey( ); while (c != L_FAIL && c != L_RETRY && c != L_ABORT); switch ( c ) { case L_ABORT : rc = ABORT; break; case L_FAIL : rc = FAIL; break; case L_RETRY : default : rc = RETRY; break; } restore_area( (chtype *)ceh_buffer ); } /* * Name: show_error_screen * Purpose: Display error screen in window * Date: November 13, 1993 * Passed: row: line to display ceh screen * col: column to begin display ceh screen */ void show_error_screen( int row, int col ) { char **p; for (p=criterr_screen; *p != NULL; p++, row++) s_output( *p, row, col, g_display.help_color ); } /* * Name: save_area * Purpose: save a region of the screen * Date: November 13, 1993 * Passed: dest: pointer to buffer for contents of screen under ceh * Notes: the source is the screen and the destination is the buffer. */ void save_area( chtype *dest ) { int hgt; int wid; int i; i = 0; for (hgt=CEH_HEIGHT; hgt; hgt--) for (wid=CEH_WIDTH; wid; wid--) dest[i++] = mvinch( hgt + CEH_ROW, wid + CEH_COL ); } /* * Name: restore_area * Purpose: restore a region of the screen * Date: November 13, 1993 * Passed: source: pointer to buffer for contents of screen under ceh * Notes: the source is the buffer and the destination is the screen. */ void restore_area( chtype *source ) { int hgt; int wid; register int i; i = 0; for (hgt=CEH_HEIGHT; hgt; hgt--) for (wid=CEH_WIDTH; wid; wid--) mvaddch( hgt + CEH_ROW, wid + CEH_COL, source[i++] ); } #else /* ********************************************************************** ****************************** PART 2 ****************************** ********************************************************************** * * DOS critical error handler. */ /* * buffer for ceh info screen. make this an int array because we * need to save character and attribute. */ int ceh_buffer[CEH_HEIGHT][CEH_WIDTH]; /* * Name: crit_err_handler * Purpose: Show user something is wrong and get a response * Date: April 1, 1992 */ int FAR crit_err_handler( void ) { int rc; int c; save_area( (char FAR *)ceh_buffer ); show_error_screen( CEH_ROW, CEH_COL ); xygoto( 60, 17 ); do c = getanswerkey( ); while (c != L_FAIL && c != L_RETRY && c != L_ABORT); switch ( c ) { case L_ABORT : rc = ABORT; break; case L_FAIL : rc = FAIL; break; case L_RETRY : default : rc = RETRY; break; } restore_area( (char FAR *)ceh_buffer ); return( rc ); } /* * Name: show_error_screen * Purpose: Display error screen in window * Date: April 1, 1992 * Passed: row: line to display ceh screen * col: column to begin display ceh screen */ void show_error_screen( int row, int col ) { char **p; for (p=criterr_screen; *p != NULL; p++, row++) s_output( *p, row, col, g_display.help_color ); s_output( error_code[ceh.code], 8, 23, g_display.help_color ); s_output( operation[ceh.rw], 9, 23, g_display.help_color ); if (ceh.dattr == 0) c_output( ceh.drive + 'a', 23, 10, g_display.help_color ); else s_output( critt1, 10, 23, g_display.help_color ); s_output( ext_err[ceh.extended], 11, 23, g_display.help_color ); s_output( error_class[ceh.class], 12, 23, g_display.help_color ); s_output( locus[ceh.locus], 13, 23, g_display.help_color ); s_output( device_type[ceh.dattr], 14, 23, g_display.help_color ); s_output( ceh.dattr == 0 ? critt1 : ceh.dname, 15, 23, g_display.help_color ); } /* * Name: save_area * Purpose: save a region of the screen * Date: April 1, 1992 * Passed: dest: pointer to buffer for contents of screen under ceh * Notes: this function does not check for snow. the source is the screen * and the destination is the buffer. */ void save_area( char FAR *dest ) { char FAR *source; register int hgt; source = (char FAR *)g_display.display_address + CEH_OFFSET; for (hgt=CEH_HEIGHT; hgt; hgt--) { _fmemcpy( dest, source, CEH_WIDTH*2 ); source += NEXT_LINE; dest += (CEH_WIDTH*2); } } /* * Name: restore_area * Purpose: restore a region of the screen * Date: April 1, 1992 * Passed: source: pointer to buffer for contents of screen under ceh * Notes: this function does not check for snow. the source is the buffer * and the destination is the screen. */ void restore_area( char FAR *source ) { char FAR *dest; register int hgt; dest = (char FAR *)g_display.display_address + CEH_OFFSET; for (hgt=CEH_HEIGHT; hgt; hgt--) { _fmemcpy( dest, source, CEH_WIDTH*2 ); dest += NEXT_LINE; source += (CEH_WIDTH*2); } } #endif