/* Dedicated treatment of the sigtrp system call, MON 48. */ /* $Id$ */ #include #include "global.h" #include "log.h" #include "warn.h" #include "trap.h" /*************************** SIGTRP ************************************* * The monitor call "sigtrp()" is handled by "do_sigtrp()". The first * * argument is a EM-trap number (0<=tn<=252), the second a UNIX signal * * number. The user wants trap "tn" to be generated, in case signal * * "sn" occurs. The report about this interpreter has a section, * * giving all details about signal handling. Do_sigtrp() returns the * * previous trap-number "sn" was mapped onto. A return value of -1 * * indicates an error. * ************************************************************************/ #define UNIX_trap(sn) (SIGILL <= sn && sn <= SIGSYS) #ifndef NSIG #define NSIG _NSIG #endif PRIVATE int sig_map[NSIG+1]; /* maps signals onto trap numbers */ PRIVATE void HndlIntSig(); /* handle signal to interpreter */ PRIVATE void HndlEmSig(); /* handle signal to user program */ init_signals() { int sn; for (sn = 0; sn < NSIG+1; sn++) { sig_map[sn] = -2; /* Default EM trap number */ } for (sn = 0; sn < NSIG+1; sn++) { /* for all signals that would cause termination */ if (!UNIX_trap(sn)) { #ifdef SIGCHLD if (sn == SIGCHLD) continue; #endif #ifdef SIGIO if (sn == SIGIO) continue; #endif #ifdef SIGWINCH if (sn == SIGWINCH) continue; #endif if (signal(sn, SIG_IGN) != SIG_IGN) { /* we take our fate in our own hand */ signal(sn, HndlIntSig); } } } } int do_sigtrp(tn, sn) int tn; /* EM trap number */ int sn; /* UNIX signal number */ { register int old_tn; if (sn <= 0 || sn > NSIG) { einval(WILLSN); return (-1); } if (UNIX_trap(sn)) { einval(WUNIXTR); return (-1); } old_tn = sig_map[sn]; sig_map[sn] = tn; if (tn == -2) { /* reset default for signal sn */ signal(sn, SIG_DFL); } else if (tn == -3) { /* ignore signal sn */ signal(sn, SIG_IGN); } else if (tn >= 0 && tn <= 252) {/* legal tn */ if ((int)signal(sn, HndlEmSig) == -1) { sig_map[sn] = old_tn; return (-1); } } else { /* illegal trap number */ einval(WILLTN); sig_map[sn] = old_tn; /* restore sig_map */ return (-1); } return (old_tn); } trap_signal() { /* execute the trap belonging to the signal that came in during the last instruction */ register int old_sig = signalled; signalled = 0; trap(sig_map[old_sig]); } /* The handling functions for the UNIX signals */ PRIVATE void HndlIntSig(sn) int sn; { /* The interpreter got the signal */ signal(sn, SIG_IGN); /* peace and quiet for close_down() */ LOG(("@t1 signal %d caught by interpreter", sn)); message("interpreter received signal %d, which was not caught by the interpreted program", sn); close_down(1); } PRIVATE void HndlEmSig(sn) int sn; { /* The EM machine got the signal */ signal(sn, HndlIntSig); /* Revert to old situation */ signalled = sn; }