ack/util/int/m_sigtrp.c
1993-11-16 12:03:22 +00:00

132 lines
2.9 KiB
C

/*
Dedicated treatment of the sigtrp system call, MON 48.
*/
/* $Header$ */
#include <signal.h>
#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;
}