signal.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* $Id$ */
  2. #include <signal.h>
  3. typedef void (*callvec)() ;
  4. static callvec vector[16] = {
  5. SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  6. SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL
  7. } ;
  8. static char mapvec[] = {
  9. 0, /* EARRAY */
  10. 0, /* ERANGE */
  11. 0, /* ESET */
  12. 0, /* EIOVFL */
  13. SIGFPE, /* EFOVFL */
  14. SIGFPE, /* EFUNDFL */
  15. 0, /* EIDIVZ */
  16. SIGFPE, /* EFDIVZ */
  17. 0, /* EIUND, already ignored */
  18. SIGFPE, /* EFUND */
  19. 0, /* ECONV */
  20. 0, /* 11 */
  21. 0, /* 12 */
  22. 0, /* 13 */
  23. 0, /* 14 */
  24. 0, /* 15 */
  25. SIGSEGV, /* ESTACK */
  26. SIGSEGV, /* EHEAP */
  27. 0, /* EILLINS */
  28. 0, /* EODDZ */
  29. 0, /* ECASE */
  30. SIGSEGV, /* EBADMEM */
  31. SIGBUS, /* EBADPTR */
  32. 0, /* EBADPC */
  33. 0, /* EBADLAE */
  34. SIGSYS, /* EBADMON */
  35. 0, /* EBADLIN */
  36. 0, /* EBADGTO */
  37. } ;
  38. #define VECBASE 128
  39. static firsttime = 1 ;
  40. static int catchtrp() ;
  41. static int procesig() ;
  42. callvec signal(sig,func) int sig ; callvec func ; {
  43. register index, i ;
  44. callvec prev ;
  45. index= sig-1 ;
  46. if ( index<0 || index>=(sizeof vector/sizeof vector[0]) ) {
  47. return (callvec) -1 ;
  48. }
  49. if ( firsttime ) {
  50. firsttime= 0 ;
  51. _setsig(catchtrp) ;
  52. }
  53. prev= vector[index] ;
  54. if ( prev!=func ) {
  55. register int mapval ;
  56. vector[index]= func ;
  57. if ( func==SIG_IGN ) {
  58. mapval= -3;
  59. } else if ( func==SIG_DFL ) {
  60. mapval= -2;
  61. } else {
  62. mapval=VECBASE+sig;
  63. }
  64. if ( sigtrp(mapval,sig)== -1 ) return (callvec) -1;
  65. }
  66. return prev ;
  67. }
  68. static int catchtrp(trapno) int trapno ; {
  69. if ( trapno>VECBASE &&
  70. trapno<=VECBASE + (sizeof vector/sizeof vector[0]) ) {
  71. return procesig(trapno-VECBASE) ;
  72. }
  73. if ( trapno>=0 && trapno< (sizeof mapvec/sizeof mapvec[0]) &&
  74. mapvec[trapno] ) {
  75. return procesig(mapvec[trapno]) ;
  76. }
  77. return 0 ; /* Failed to handle the trap */
  78. }
  79. static int procesig(sig) int sig ; {
  80. register index ;
  81. callvec trf ;
  82. index= sig-1 ;
  83. trf= vector[index] ;
  84. if ( trf==SIG_IGN ) return 1 ;
  85. if ( sig!=SIGILL && sig!=SIGTRAP ) vector[index]= SIG_IGN ;
  86. if ( trf==SIG_DFL ) return 0 ;
  87. (*trf)(sig) ;
  88. return 1 ;
  89. }