aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/go-signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/go-signal.c')
-rw-r--r--libgo/runtime/go-signal.c113
1 files changed, 80 insertions, 33 deletions
diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index c16b058b79e..468235ddf4e 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -6,13 +6,12 @@
#include <signal.h>
#include <stdlib.h>
+#include <unistd.h>
#include <sys/time.h>
+#include "runtime.h"
#include "go-assert.h"
#include "go-panic.h"
-#include "go-signal.h"
-
-#include "runtime.h"
#ifndef SA_RESTART
#define SA_RESTART 0
@@ -24,6 +23,10 @@ struct sigtab
{
/* Signal number. */
int sig;
+ /* Nonzero if the signal should be caught. */
+ _Bool catch;
+ /* Nonzero if the signal should be queued. */
+ _Bool queue;
/* Nonzero if the signal should be ignored. */
_Bool ignore;
/* Nonzero if we should restart system calls. */
@@ -34,62 +37,81 @@ struct sigtab
static struct sigtab signals[] =
{
- { SIGHUP, 0, 1 },
- { SIGINT, 0, 1 },
- { SIGALRM, 1, 1 },
- { SIGTERM, 0, 1 },
+ { SIGHUP, 0, 1, 0, 1 },
+ { SIGINT, 0, 1, 0, 1 },
+ { SIGQUIT, 0, 1, 0, 1 },
+ { SIGALRM, 0, 1, 1, 1 },
+ { SIGTERM, 0, 1, 0, 1 },
+#ifdef SIGILL
+ { SIGILL, 1, 0, 0, 0 },
+#endif
+#ifdef SIGTRAP
+ { SIGTRAP, 1, 0, 0, 0 },
+#endif
+#ifdef SIGABRT
+ { SIGABRT, 1, 0, 0, 0 },
+#endif
#ifdef SIGBUS
- { SIGBUS, 0, 0 },
+ { SIGBUS, 1, 0, 0, 0 },
#endif
#ifdef SIGFPE
- { SIGFPE, 0, 0 },
+ { SIGFPE, 1, 0, 0, 0 },
#endif
#ifdef SIGUSR1
- { SIGUSR1, 1, 1 },
+ { SIGUSR1, 0, 1, 1, 1 },
#endif
#ifdef SIGSEGV
- { SIGSEGV, 0, 0 },
+ { SIGSEGV, 1, 0, 0, 0 },
#endif
#ifdef SIGUSR2
- { SIGUSR2, 1, 1 },
+ { SIGUSR2, 0, 1, 1, 1 },
#endif
#ifdef SIGPIPE
- { SIGPIPE, 1, 0 },
+ { SIGPIPE, 0, 0, 1, 0 },
+#endif
+#ifdef SIGSTKFLT
+ { SIGSTKFLT, 1, 0, 0, 0 },
#endif
#ifdef SIGCHLD
- { SIGCHLD, 1, 1 },
+ { SIGCHLD, 0, 1, 1, 1 },
#endif
#ifdef SIGTSTP
- { SIGTSTP, 1, 1 },
+ { SIGTSTP, 0, 1, 1, 1 },
#endif
#ifdef SIGTTIN
- { SIGTTIN, 1, 1 },
+ { SIGTTIN, 0, 1, 1, 1 },
#endif
#ifdef SIGTTOU
- { SIGTTOU, 1, 1 },
+ { SIGTTOU, 0, 1, 1, 1 },
#endif
#ifdef SIGURG
- { SIGURG, 1, 1 },
+ { SIGURG, 0, 1, 1, 1 },
#endif
#ifdef SIGXCPU
- { SIGXCPU, 1, 1 },
+ { SIGXCPU, 0, 1, 1, 1 },
#endif
#ifdef SIGXFSZ
- { SIGXFSZ, 1, 1 },
+ { SIGXFSZ, 0, 1, 1, 1 },
#endif
#ifdef SIGVTARLM
- { SIGVTALRM, 1, 1 },
+ { SIGVTALRM, 0, 1, 1, 1 },
+#endif
+#ifdef SIGPROF
+ { SIGPROF, 0, 1, 1, 1 },
#endif
#ifdef SIGWINCH
- { SIGWINCH, 1, 1 },
+ { SIGWINCH, 0, 1, 1, 1 },
#endif
#ifdef SIGIO
- { SIGIO, 1, 1 },
+ { SIGIO, 0, 1, 1, 1 },
#endif
#ifdef SIGPWR
- { SIGPWR, 1, 1 },
+ { SIGPWR, 0, 1, 1, 1 },
+#endif
+#ifdef SIGSYS
+ { SIGSYS, 1, 0, 0, 0 },
#endif
- { -1, 0, 0 }
+ { -1, 0, 0, 0, 0 }
};
/* The Go signal handler. */
@@ -103,7 +125,7 @@ sighandler (int sig)
if (sig == SIGPROF)
{
/* FIXME. */
- runtime_sigprof (0, 0, nil);
+ runtime_sigprof (0, 0, nil, nil);
return;
}
@@ -112,6 +134,12 @@ sighandler (int sig)
msg = NULL;
switch (sig)
{
+#ifdef SIGILL
+ case SIGILL:
+ msg = "illegal instruction";
+ break;
+#endif
+
#ifdef SIGBUS
case SIGBUS:
msg = "invalid memory address or nil pointer dereference";
@@ -138,7 +166,7 @@ sighandler (int sig)
{
sigset_t clear;
- if (__sync_bool_compare_and_swap (&m->mallocing, 1, 1))
+ if (runtime_m()->mallocing)
{
fprintf (stderr, "caught signal while mallocing: %s\n", msg);
__go_assert (0);
@@ -153,16 +181,22 @@ sighandler (int sig)
__go_panic_msg (msg);
}
- if (__go_sigsend (sig))
- return;
for (i = 0; signals[i].sig != -1; ++i)
{
if (signals[i].sig == sig)
{
struct sigaction sa;
- if (signals[i].ignore)
- return;
+ if (signals[i].queue)
+ {
+ if (__go_sigsend (sig) || signals[i].ignore)
+ return;
+ runtime_exit (2); // SIGINT, SIGTERM, etc
+ }
+
+ if (runtime_panicking)
+ runtime_exit (2);
+ runtime_panicking = 1;
memset (&sa, 0, sizeof sa);
@@ -181,11 +215,18 @@ sighandler (int sig)
abort ();
}
+/* Ignore a signal. */
+
+static void
+sigignore (int sig __attribute__ ((unused)))
+{
+}
+
/* Initialize signal handling for Go. This is called when the program
starts. */
void
-__initsig ()
+runtime_initsig (int32 queue)
{
struct sigaction sa;
int i;
@@ -201,6 +242,12 @@ __initsig ()
for (i = 0; signals[i].sig != -1; ++i)
{
+ if (signals[i].queue != (queue ? 1 : 0))
+ continue;
+ if (signals[i].catch || signals[i].queue)
+ sa.sa_handler = sighandler;
+ else
+ sa.sa_handler = sigignore;
sa.sa_flags = signals[i].restart ? SA_RESTART : 0;
if (sigaction (signals[i].sig, &sa, NULL) != 0)
__go_assert (0);
@@ -243,7 +290,7 @@ runtime_resetcpuprofiler(int32 hz)
__go_assert (i == 0);
}
- m->profilehz = hz;
+ runtime_m()->profilehz = hz;
}
/* Used by the os package to raise SIGPIPE. */