m_sigtrp.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. Dedicated treatment of the sigtrp system call, MON 48.
  3. */
  4. /* $Id$ */
  5. #include <signal.h>
  6. #include "global.h"
  7. #include "log.h"
  8. #include "warn.h"
  9. #include "trap.h"
  10. /*************************** SIGTRP *************************************
  11. * The monitor call "sigtrp()" is handled by "do_sigtrp()". The first *
  12. * argument is a EM-trap number (0<=tn<=252), the second a UNIX signal *
  13. * number. The user wants trap "tn" to be generated, in case signal *
  14. * "sn" occurs. The report about this interpreter has a section, *
  15. * giving all details about signal handling. Do_sigtrp() returns the *
  16. * previous trap-number "sn" was mapped onto. A return value of -1 *
  17. * indicates an error. *
  18. ************************************************************************/
  19. #define UNIX_trap(sn) (SIGILL <= sn && sn <= SIGSYS)
  20. #ifndef NSIG
  21. #define NSIG _NSIG
  22. #endif
  23. PRIVATE int sig_map[NSIG+1]; /* maps signals onto trap numbers */
  24. PRIVATE void HndlIntSig(); /* handle signal to interpreter */
  25. PRIVATE void HndlEmSig(); /* handle signal to user program */
  26. init_signals() {
  27. int sn;
  28. for (sn = 0; sn < NSIG+1; sn++) {
  29. sig_map[sn] = -2; /* Default EM trap number */
  30. }
  31. for (sn = 0; sn < NSIG+1; sn++) {
  32. /* for all signals that would cause termination */
  33. if (!UNIX_trap(sn)) {
  34. #ifdef SIGCHLD
  35. if (sn == SIGCHLD) continue;
  36. #endif
  37. #ifdef SIGIO
  38. if (sn == SIGIO) continue;
  39. #endif
  40. #ifdef SIGWINCH
  41. if (sn == SIGWINCH) continue;
  42. #endif
  43. if (signal(sn, SIG_IGN) != SIG_IGN) {
  44. /* we take our fate in our own hand */
  45. signal(sn, HndlIntSig);
  46. }
  47. }
  48. }
  49. }
  50. int do_sigtrp(tn, sn)
  51. int tn; /* EM trap number */
  52. int sn; /* UNIX signal number */
  53. {
  54. register int old_tn;
  55. if (sn <= 0 || sn > NSIG) {
  56. einval(WILLSN);
  57. return (-1);
  58. }
  59. if (UNIX_trap(sn)) {
  60. einval(WUNIXTR);
  61. return (-1);
  62. }
  63. old_tn = sig_map[sn];
  64. sig_map[sn] = tn;
  65. if (tn == -2) { /* reset default for signal sn */
  66. signal(sn, SIG_DFL);
  67. }
  68. else if (tn == -3) { /* ignore signal sn */
  69. signal(sn, SIG_IGN);
  70. }
  71. else if (tn >= 0 && tn <= 252) {/* legal tn */
  72. if ((int)signal(sn, HndlEmSig) == -1) {
  73. sig_map[sn] = old_tn;
  74. return (-1);
  75. }
  76. }
  77. else {
  78. /* illegal trap number */
  79. einval(WILLTN);
  80. sig_map[sn] = old_tn; /* restore sig_map */
  81. return (-1);
  82. }
  83. return (old_tn);
  84. }
  85. trap_signal()
  86. {
  87. /* execute the trap belonging to the signal that came in during
  88. the last instruction
  89. */
  90. register int old_sig = signalled;
  91. signalled = 0;
  92. trap(sig_map[old_sig]);
  93. }
  94. /* The handling functions for the UNIX signals */
  95. PRIVATE void HndlIntSig(sn)
  96. int sn;
  97. {
  98. /* The interpreter got the signal */
  99. signal(sn, SIG_IGN); /* peace and quiet for close_down() */
  100. LOG(("@t1 signal %d caught by interpreter", sn));
  101. message("interpreter received signal %d, which was not caught by the interpreted program",
  102. sn);
  103. close_down(1);
  104. }
  105. PRIVATE void HndlEmSig(sn)
  106. int sn;
  107. {
  108. /* The EM machine got the signal */
  109. signal(sn, HndlIntSig); /* Revert to old situation */
  110. signalled = sn;
  111. }