home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / vile-src.zip / vile-8.1 / djhandl.c < prev    next >
C/C++ Source or Header  |  1998-04-28  |  4KB  |  156 lines

  1. /*
  2.  *    control-c and critical error handlers for DJGPP environment
  3.  *
  4.  *    control-c code based exactly on the equivalent handler
  5.  *        for control-break in the go32 libraries
  6.  *    critical error handling from Bob Babcock.
  7.  *
  8.  * $Header: /usr/build/vile/vile/RCS/djhandl.c,v 1.6 1998/04/28 10:19:54 tom Exp $
  9.  *
  10.  *
  11.  */
  12.  
  13. #include <stdlib.h>
  14. #include <go32.h>
  15. #include <dpmi.h>
  16. #include <dos.h>
  17. #include <stdio.h>
  18.  
  19. #ifndef TRUE
  20. #define TRUE 1
  21. #define FALSE 0
  22. #endif
  23.  
  24. static _go32_dpmi_registers regs;
  25. static volatile unsigned long ctrl_c_count = 0;
  26. static int ctrl_c_hooked = 0;
  27. static _go32_dpmi_seginfo old_vector;
  28. static _go32_dpmi_seginfo new_vector;
  29.  
  30. unsigned long was_ctrl_c_hit();
  31. void   want_ctrl_c(int yes); /* auto-yes if call above function */
  32.  
  33. static void ctrl_c_isr(_go32_dpmi_registers *regs)
  34. {
  35.   ctrl_c_count ++;
  36. }
  37.  
  38. unsigned long was_ctrl_c_hit()
  39. {
  40.   unsigned long cnt;
  41.   want_ctrl_c(1);
  42.   cnt = ctrl_c_count;
  43.   ctrl_c_count = 0;
  44.   return cnt;
  45. }
  46.  
  47. void want_ctrl_c(int yes)
  48. {
  49.   if (yes)
  50.   {
  51.     if (ctrl_c_hooked)
  52.       return;
  53.     _go32_dpmi_get_real_mode_interrupt_vector(0x23, &old_vector);
  54.  
  55.     new_vector.pm_offset = (int)ctrl_c_isr;
  56.     _go32_dpmi_allocate_real_mode_callback_iret(&new_vector, ®s);
  57.     _go32_dpmi_set_real_mode_interrupt_vector(0x23, &new_vector);
  58.     ctrl_c_count = 0;
  59.     ctrl_c_hooked = 1;
  60.   }
  61.   else
  62.   {
  63.     if (!ctrl_c_hooked)
  64.       return;
  65.     _go32_dpmi_set_real_mode_interrupt_vector(0x23, &old_vector);
  66.     _go32_dpmi_free_real_mode_callback(&new_vector);
  67.     ctrl_c_count = 0;
  68.     ctrl_c_hooked = 0;
  69.   }
  70. }
  71.  
  72. /* hardgcc - critical error handler for gcc
  73.  */
  74.  
  75. int hard_error_occurred = FALSE;
  76.  
  77. static char handler[16] =
  78. {
  79.    0x81, 0xe7, 0x7f, 0,       /* and di,7f         */
  80.    0x47,                      /* inc di            */
  81.    0x2e, 0x89, 0x3e, 0xe, 0,  /* mov cs:[0eh],di   */
  82.    0xb8, 3, 0,                /* mov ax,3          */
  83.    0xcf,                      /* iret              */
  84.    0,0                        /* storage for error code */
  85. };
  86. static int handler_installed = FALSE;
  87. static _go32_dpmi_seginfo new_handler_info, old_handler_info;
  88.  
  89. /* clear_hard_error - clear any indication of a critical error
  90.  */
  91. void clear_hard_error(void)
  92. {
  93.    short zero = 0;
  94.  
  95.    if(handler_installed)
  96.       dosmemput(&zero, 2, new_handler_info.rm_segment * 16 + 14);
  97.    hard_error_occurred = 0;
  98.    return;
  99. }
  100.  
  101. /* install the real-mode critical error handler
  102.  */
  103. void hard_error_catch_setup(void)
  104. {
  105. /* On first call, allocate some DOS memory and copy the handler into it
  106.  */
  107.    if(!handler_installed) {
  108.       handler_installed = TRUE;
  109.       new_handler_info.size = old_handler_info.size = 1;
  110.       if (_go32_dpmi_allocate_dos_memory(&new_handler_info) != 0) {
  111.     fprintf(stderr,"Couldn't allocate handler memory\n");
  112.     exit(1);
  113.       }
  114.       dosmemput(handler, 16, new_handler_info.rm_segment * 16);
  115. #ifdef XDEBUG
  116.       sprintf(Tempbuf, "Handler at segment %x", new_handler_info.rm_segment);
  117.       error_msg(Tempbuf, 0);
  118. #endif
  119.     }
  120.     _go32_dpmi_get_real_mode_interrupt_vector(0x24, &old_handler_info);
  121.     _go32_dpmi_set_real_mode_interrupt_vector(0x24, &new_handler_info);
  122.     clear_hard_error();
  123.     return;
  124. }
  125.  
  126. /* switch back to old critical error handler
  127.  */
  128. void hard_error_teardown(void)
  129. {
  130.    if(handler_installed)
  131.       _go32_dpmi_set_real_mode_interrupt_vector(0x24, &old_handler_info);
  132.    return;
  133. }
  134.  
  135. /* test_hard_err - test whether a critical error has occurred and return
  136.    error code (0 if none or handler never installed).
  137.  */
  138. int did_hard_error_occur(void)
  139. {
  140.    short error_code;
  141.  
  142.    if(handler_installed)
  143.       {
  144.       dosmemget(new_handler_info.rm_segment * 16 + 14, 2, &error_code);
  145. #ifdef XDEBUG
  146.       if(error_code)
  147.          {
  148.          sprintf(Tempbuf,"Critical error code is %d", error_code);
  149.          error_msg(Tempbuf,0);
  150.          }
  151. #endif
  152.       return(error_code);
  153.       }
  154.    return(0);
  155. }
  156.